File: /usr/src/linux/drivers/sbus/char/sunmouse.c

1     /* sunmouse.c: Sun mouse driver for the Sparc
2      *
3      * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
4      * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
5      *
6      * Parts based on the psaux.c driver written by:
7      * Johan Myreen.
8      *
9      * Dec/19/95 Added SunOS mouse ioctls - miguel.
10      * Jan/5/96  Added VUID support, sigio support - miguel.
11      * Mar/5/96  Added proper mouse stream support - miguel.
12      * Sep/96    Allow more than one reader -miguel.
13      * Aug/97    Added PCI 8042 controller support -DaveM
14      */
15     
16     /* The mouse is run off of one of the Zilog serial ports.  On
17      * that port is the mouse and the keyboard, each gets a zs channel.
18      * The mouse itself is mouse-systems in nature.  So the protocol is:
19      *
20      * Byte 1) Button state which is bit-encoded as
21      *            0x4 == left-button down, else up
22      *            0x2 == middle-button down, else up
23      *            0x1 == right-button down, else up
24      *
25      * Byte 2) Delta-x
26      * Byte 3) Delta-y
27      * Byte 4) Delta-x again
28      * Byte 5) Delta-y again
29      *
30      * One day this driver will have to support more than one mouse in the system.
31      *
32      * This driver has two modes of operation: the default VUID_NATIVE is
33      * set when the device is opened and allows the application to see the
34      * mouse character stream as we get it from the serial (for gpm for
35      * example).  The second method, VUID_FIRM_EVENT will provide cooked
36      * events in Firm_event records as expected by SunOS/Solaris applications.
37      *
38      * FIXME: We need to support more than one mouse.
39      * */
40     
41     #include <linux/config.h>
42     #include <linux/kernel.h>
43     #include <linux/sched.h>
44     #include <linux/fcntl.h>
45     #include <linux/signal.h>
46     #include <linux/timer.h>
47     #include <linux/errno.h>
48     #include <linux/miscdevice.h>
49     #include <linux/mm.h>
50     #include <linux/poll.h>
51     #include <linux/spinlock.h>
52     #include <linux/smp_lock.h>
53     #include <linux/init.h>
54     #include <asm/uaccess.h>
55     #include <asm/system.h>
56     #include <asm/vuid_event.h>
57     #include <linux/random.h>
58     /* The following keeps track of software state for the Sun
59      * mouse.
60      */
61     #define STREAM_SIZE   2048
62     #define EV_SIZE       (STREAM_SIZE/sizeof (Firm_event))
63     #define BUTTON_LEFT   4
64     #define BUTTON_MIDDLE 2
65     #define BUTTON_RIGHT  1
66     
67     struct sun_mouse {
68     	unsigned char transaction[5];  /* Each protocol transaction */
69     	unsigned char byte;            /* Counter, starts at 0 */
70     	unsigned char button_state;    /* Current button state */
71     	unsigned char prev_state;      /* Previous button state */
72     	int delta_x;                   /* Current delta-x */
73     	int delta_y;                   /* Current delta-y */
74     	int active;		       /* set if device is open */
75             int vuid_mode;	               /* VUID_NATIVE or VUID_FIRM_EVENT */
76     	wait_queue_head_t proc_list;
77     	struct fasync_struct *fasync;
78     	
79     	/* The event/stream queue */
80     	spinlock_t lock;
81     	unsigned int head;
82     	unsigned int tail;
83     	union {
84     		char stream [STREAM_SIZE];
85     		Firm_event ev [EV_SIZE];
86     	} queue;
87     };
88     
89     static struct sun_mouse sunmouse;
90     #define gen_events (sunmouse.vuid_mode != VUID_NATIVE)
91     #define bstate sunmouse.button_state
92     #define pstate sunmouse.prev_state
93     
94     extern void mouse_put_char(char ch);
95     
96     #undef SMOUSE_DEBUG
97     
98     static int
99     push_event (Firm_event *ev)
100     {
101     	unsigned long flags;
102     	int next, ret;
103     	
104     	spin_lock_irqsave(&sunmouse.lock, flags);
105     
106     	next = (sunmouse.head + 1) % EV_SIZE;
107     	ret = 0;
108     	if (next != sunmouse.tail) {
109     		sunmouse.queue.ev [sunmouse.head] = *ev;
110     		sunmouse.head = next;
111     		ret = 1;
112     	}
113     
114     	spin_unlock_irqrestore(&sunmouse.lock, flags);
115     
116     	return ret;
117     }
118     
119     static int
120     queue_empty (void)
121     {
122     	return sunmouse.head == sunmouse.tail;
123     }
124     
125     /* Must be invoked under the sunmouse.lock */
126     static void get_from_queue (Firm_event *p)
127     {
128     	*p = sunmouse.queue.ev [sunmouse.tail];
129     	sunmouse.tail = (sunmouse.tail + 1) % EV_SIZE;
130     }
131     
132     static void
133     push_char (char c)
134     {
135     	unsigned long flags;
136     	int next;
137     
138     	spin_lock_irqsave(&sunmouse.lock, flags);
139     
140     	next = (sunmouse.head + 1) % STREAM_SIZE;
141     	if (next != sunmouse.tail) {
142     #ifdef SMOUSE_DEBUG
143     		printk("P<%02x>\n", (unsigned char)c);
144     #endif
145     		sunmouse.queue.stream [sunmouse.head] = c;
146     		sunmouse.head = next;
147     	}
148     
149     	spin_unlock_irqrestore(&sunmouse.lock, flags);
150     
151     	kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
152     	wake_up_interruptible (&sunmouse.proc_list);
153     }
154     
155     /* Auto baud rate "detection".  ;-) */
156     static int mouse_baud = 4800;		/* Initial rate set by zilog driver. */
157     
158     /* Change the baud rate after receiving too many "bogon bytes". */
159     void sun_mouse_change_baud(void)
160     {
161     	extern void rs_change_mouse_baud(int newbaud);
162     
163     	if(mouse_baud == 1200)
164     		mouse_baud = 2400;
165     	else if(mouse_baud == 2400)
166     		mouse_baud = 4800;
167     	else if(mouse_baud == 4800)
168     		mouse_baud = 9600;
169     	else
170     		mouse_baud = 1200;
171     
172     	rs_change_mouse_baud(mouse_baud);
173     }
174     
175     /* This tries to monitor the mouse state so that it
176      * can automatically adjust to the correct baud rate.
177      * The mouse spits out BRKs when the baud rate is
178      * incorrect.
179      *
180      * It returns non-zero if we should ignore this byte.
181      */
182     int mouse_baud_detection(unsigned char c, int is_break)
183     {
184     	static int mouse_got_break = 0;
185     	static int ctr = 0;
186     
187     	if (is_break) {
188     		/* Let a few normal bytes go by before
189     		 * we jump the gun and say we need to
190     		 * try another baud rate.
191     		 */
192     		if (mouse_got_break && ctr < 8)
193     			return 1;
194     
195     		/* OK, we need to try another baud rate. */
196     		sun_mouse_change_baud();
197     		ctr = 0;
198     		mouse_got_break = 1;
199     		return 1;
200     	}
201     	if (mouse_got_break) {
202     		ctr++;
203     		if (c == 0x87) {
204     			printk(KERN_INFO "sunmouse: Successfully "
205     			       "adjusted to %d baud.\n", mouse_baud);
206     			mouse_got_break = 0;
207     		}
208     		return 1;
209     	}
210     
211     	return 0;
212     }
213     
214     /* You ask me, why does this cap the lower bound at -127 and not
215      * -128?  Because the xf86 mouse code is crap and treats -128
216      * as an illegal value and resets it's protocol state machine
217      * when it sees this value.
218      */
219     #define CLIP(__X)	(((__X) > 127) ? 127 : (((__X) < -127) ? -127 : (__X)))
220     
221     /* The following is called from the serial driver when bytes/breaks
222      * are received on the Mouse line.
223      */
224     void
225     sun_mouse_inbyte(unsigned char byte, int is_break)
226     {
227     	signed char mvalue;
228     	int d, pushed = 0;
229     	Firm_event ev;
230     
231     	add_mouse_randomness (byte);
232     #if 0
233     	{
234     		static int xxx = 0;
235     		printk("mouse(%02x:%d) ",
236     		       byte, is_break);
237     		if (byte == 0x87) {
238     			xxx = 0;
239     			printk("\n");
240     		}
241     	}
242     #endif
243     	if (mouse_baud_detection(byte, is_break))
244     		return;
245     
246     	if(!sunmouse.active)
247     		return;
248     
249     	/* Ignore this if it is garbage. */
250     	if (sunmouse.byte == 69) {
251     		if (byte != 0x87)
252     			return;
253     
254     		/* Ok, we've begun the state machine. */
255     		sunmouse.byte = 0;
256     	}
257     #if 0
258     	/* If the mouse sends us a byte from 0x80 to 0x87
259     	 * we are starting at byte zero in the transaction
260     	 * protocol.
261     	 */
262     	if((byte & ~0x0f) == 0x80) 
263     		sunmouse.byte = 0;
264     #endif
265     
266     	mvalue = (signed char) byte;
267     	switch(sunmouse.byte) {
268     	case 0:
269     		/* If we get a bogus button byte, just skip it.
270     		 * When we get here the baud detection code has
271     		 * passed, so the only other things which can
272     		 * cause this are dropped serial characters and
273     		 * confused mouse.  We check this because otherwise
274     		 * begin posting erroneous mouse events.
275     		 */
276     		if ((byte & 0xf0) != 0x80)
277     			return;
278     
279     		/* Button state */
280     		sunmouse.button_state = (~byte) & 0x7;
281     #ifdef SMOUSE_DEBUG
282     		printk("B<Left %s, Middle %s, Right %s>",
283     		       ((sunmouse.button_state & 0x4) ? "DOWN" : "UP"),
284     		       ((sunmouse.button_state & 0x2) ? "DOWN" : "UP"),
285     		       ((sunmouse.button_state & 0x1) ? "DOWN" : "UP"));
286     #endif
287     		/* To deal with the Sparcbook 3 */
288     		if (byte & 0x8) {
289     			sunmouse.byte += 2;
290     			sunmouse.delta_y = 0;
291     			sunmouse.delta_x = 0;
292     		}
293     		sunmouse.byte++;
294     		return;
295     	case 1:
296     		/* Delta-x 1 */
297     #ifdef SMOUSE_DEBUG
298     		printk("DX1<%d>", mvalue);
299     #endif
300     		sunmouse.delta_x = mvalue;
301     		sunmouse.byte++;
302     		return;
303     	case 2:
304     		/* Delta-y 1 */
305     #ifdef SMOUSE_DEBUG
306     		printk("DY1<%d>", mvalue);
307     #endif
308     		sunmouse.delta_y = mvalue;
309     		sunmouse.byte++;
310     		return;
311     	case 3:
312     		/* Delta-x 2 */
313     #ifdef SMOUSE_DEBUG
314     		printk("DX2<%d>", mvalue);
315     #endif
316     		sunmouse.delta_x += mvalue;
317     		sunmouse.delta_x = CLIP(sunmouse.delta_x);
318     		sunmouse.byte++;
319     		return;
320     	case 4:
321     		/* Last byte, Delta-y 2 */
322     #ifdef SMOUSE_DEBUG
323     		printk("DY2<%d>", mvalue);
324     #endif
325     		sunmouse.delta_y += mvalue;
326     		sunmouse.delta_y = CLIP(sunmouse.delta_y);
327     		sunmouse.byte = 0;  /* Back to button state */
328     		break;
329     	case 69:
330     		/* Until we get the (0x80 -> 0x87) value we aren't
331     		 * in the middle of a real transaction, so just
332     		 * return.
333     		 */
334     		return;
335     	default:
336     		printk("sunmouse: bogon transaction state\n");
337     		sunmouse.byte = 69;  /* What could cause this? */
338     		return;
339     	};
340     
341     	if (!gen_events) {
342     		push_char (~sunmouse.button_state & 0x87);
343     		push_char (sunmouse.delta_x);
344     		push_char (sunmouse.delta_y);
345     		return;
346     	}
347     
348     	d = bstate ^ pstate;
349     	pstate = bstate;
350     	if (d) {
351     		if (d & BUTTON_LEFT) {
352     			ev.id = MS_LEFT;
353     			ev.value = bstate & BUTTON_LEFT;
354     		}
355     		if (d & BUTTON_RIGHT) {
356     			ev.id = MS_RIGHT;
357     			ev.value = bstate & BUTTON_RIGHT;
358     		}
359     		if (d & BUTTON_MIDDLE) {
360     			ev.id = MS_MIDDLE;
361     			ev.value = bstate & BUTTON_MIDDLE;
362     		}
363     		ev.time = xtime;
364     		ev.value = ev.value ? VKEY_DOWN : VKEY_UP;
365     		pushed += push_event (&ev);
366     	}
367     	if (sunmouse.delta_x) {
368     		ev.id = LOC_X_DELTA;
369     		ev.time = xtime;
370     		ev.value = sunmouse.delta_x;
371     		pushed += push_event (&ev);
372     		sunmouse.delta_x = 0;
373     	}
374     	if (sunmouse.delta_y) {
375     		ev.id = LOC_Y_DELTA;
376     		ev.time = xtime;
377     		ev.value = sunmouse.delta_y;
378     		pushed += push_event (&ev);
379     	}
380     	
381     	if (pushed != 0) {
382     		/* We just completed a transaction, wake up whoever is awaiting
383     		 * this event.
384     		 */
385     		kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
386     		wake_up_interruptible(&sunmouse.proc_list);
387     	}
388     	return;
389     }
390     
391     static int
392     sun_mouse_open(struct inode * inode, struct file * file)
393     {
394     	spin_lock_irq(&sunmouse.lock);
395     	if (sunmouse.active++)
396     		goto out;
397     	sunmouse.delta_x = sunmouse.delta_y = 0;
398     	sunmouse.button_state = 0x80;
399     	sunmouse.vuid_mode = VUID_NATIVE;
400     out:
401     	spin_unlock_irq(&sunmouse.lock);
402     	return 0;
403     }
404     
405     static int sun_mouse_fasync (int fd, struct file *filp, int on)
406     {
407     	int retval;
408     
409     	retval = fasync_helper (fd, filp, on, &sunmouse.fasync);
410     	if (retval < 0)
411     		return retval;
412     	return 0;
413     }
414     
415     static int
416     sun_mouse_close(struct inode *inode, struct file *file)
417     {
418     	sun_mouse_fasync (-1, file, 0);
419     
420     	spin_lock_irq(&sunmouse.lock);
421     	sunmouse.active--;
422     	spin_unlock_irq(&sunmouse.lock);
423     
424     	return 0;
425     }
426     
427     static ssize_t
428     sun_mouse_write(struct file *file, const char *buffer,
429     		size_t count, loff_t *ppos)
430     {
431     	return -EINVAL;  /* foo on you */
432     }
433     
434     static ssize_t
435     sun_mouse_read(struct file *file, char *buffer,
436     	       size_t count, loff_t *ppos)
437     {
438     	DECLARE_WAITQUEUE(wait, current);
439     	unsigned long flags;
440     
441     	if (queue_empty ()) {
442     		if (file->f_flags & O_NONBLOCK)
443     			return -EWOULDBLOCK;
444     		add_wait_queue (&sunmouse.proc_list, &wait);
445     repeat:
446     		set_current_state(TASK_INTERRUPTIBLE);
447     		if (queue_empty() && !signal_pending(current)) {
448     			schedule();
449     			goto repeat;
450     		}
451     		current->state = TASK_RUNNING;
452     		remove_wait_queue (&sunmouse.proc_list, &wait);
453     	}
454     	if (gen_events) {
455     		char *p = buffer, *end = buffer+count;
456     		
457     		spin_lock_irqsave(&sunmouse.lock, flags);
458     		while (p < end && !queue_empty ()){
459     			Firm_event this_event;
460     
461     			get_from_queue(&this_event);
462     			spin_unlock_irqrestore(&sunmouse.lock, flags);
463     
464     #ifdef CONFIG_SPARC32_COMPAT
465     			if (current->thread.flags & SPARC_FLAG_32BIT) {
466     				if ((end - p) <
467     				    ((sizeof(Firm_event) - sizeof(struct timeval) +
468     				      (sizeof(u32) * 2))))
469     					break;
470     				if (copy_to_user((Firm_event *)p, &this_event,
471     						 sizeof(Firm_event)-sizeof(struct timeval)))
472     					return -EFAULT;
473     				p += sizeof(Firm_event)-sizeof(struct timeval);
474     				if (__put_user(this_event.time.tv_sec, (u32 *)p))
475     					return -EFAULT;
476     				p += sizeof(u32);
477     				if (__put_user(this_event.time.tv_usec, (u32 *)p))
478     					return -EFAULT;
479     				p += sizeof(u32);
480     			} else
481     #endif	
482     			{	
483     				if ((end - p) < sizeof(Firm_event))
484     					break;
485     				if (copy_to_user((Firm_event *)p, &this_event,
486     				     		 sizeof(Firm_event)))
487     					return -EFAULT;
488     				p += sizeof (Firm_event);
489     			}
490     			spin_lock_irqsave(&sunmouse.lock, flags);
491     		}
492     		spin_unlock_irqrestore(&sunmouse.lock, flags);
493     		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
494     		return p-buffer;
495     	} else {
496     		int c, limit = 3;
497     
498     		if (count < limit)
499     			limit = count;
500     		for (c = 0; c < limit; c++) {
501     			unsigned char val;
502     			int empty = 0;
503     
504     			spin_lock_irqsave(&sunmouse.lock, flags);
505     			if (queue_empty()) {
506     				empty = 1;
507     				val = 0;
508     			} else {
509     				val = sunmouse.queue.stream[sunmouse.tail];
510     				sunmouse.tail = (sunmouse.tail + 1) % STREAM_SIZE;
511     			}
512     			spin_unlock_irqrestore(&sunmouse.lock, flags);
513     
514     			if (empty)
515     				break;
516     
517     			put_user(val, buffer);
518     			buffer++;
519     		}
520     		while (c < count) {
521     			if (c >= 5)
522     				break;
523     			put_user(0, buffer);
524     			buffer++;
525     			c++;
526     		}
527     		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
528     		return c;
529     	}
530     	/* Only called if nothing was sent */
531     	if (signal_pending(current))
532     		return -ERESTARTSYS;
533     	return 0;
534     }
535     
536     static unsigned int sun_mouse_poll(struct file *file, poll_table *wait)
537     {
538     	poll_wait(file, &sunmouse.proc_list, wait);
539     	if(!queue_empty())
540     		return POLLIN | POLLRDNORM;
541     	return 0;
542     }
543     int
544     sun_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
545     {
546     	int i;
547     	
548     	switch (cmd){
549     		/* VUIDGFORMAT - Get input device byte stream format */
550     	case _IOR('v', 2, int):
551     		if (put_user(sunmouse.vuid_mode, (int *) arg))
552     			return -EFAULT;
553     		break;
554     
555     		/* VUIDSFORMAT - Set input device byte stream format*/
556     	case _IOW('v', 1, int):
557     		if (get_user(i, (int *) arg))
558     			return -EFAULT;
559     		if (i == VUID_NATIVE || i == VUID_FIRM_EVENT){
560     			int value;
561     
562     			if (get_user(value, (int *)arg))
563     				return -EFAULT;
564     
565     			spin_lock_irq(&sunmouse.lock);
566     			sunmouse.vuid_mode = value;
567     			sunmouse.head = sunmouse.tail = 0;
568     			spin_unlock_irq(&sunmouse.lock);
569     		} else
570     			return -EINVAL;
571     		break;
572     
573     	case 0x8024540b:
574     	case 0x40245408:
575     		/* This is a buggy application doing termios on the mouse driver */
576     		/* we ignore it.  I keep this check here so that we will notice   */
577     		/* future mouse vuid ioctls */
578     		return -ENOTTY;
579     		
580     	default:
581     #ifdef DEBUG
582     		printk ("[MOUSE-ioctl: %8.8x]\n", cmd);
583     #endif
584     		return -EINVAL;
585     	}
586     	return 0;
587     }
588     
589     struct file_operations sun_mouse_fops = {
590     	read:		sun_mouse_read,
591     	write:		sun_mouse_write,
592     	poll:		sun_mouse_poll,
593     	ioctl:		sun_mouse_ioctl,
594     	open:		sun_mouse_open,
595     	release:	sun_mouse_close,
596     	fasync:		sun_mouse_fasync,
597     };
598     
599     static struct miscdevice sun_mouse_mouse = {
600     	SUN_MOUSE_MINOR, "sunmouse", &sun_mouse_fops
601     };
602     
603     void sun_mouse_zsinit(void)
604     {
605     	printk("Sun Mouse-Systems mouse driver version 1.00\n");
606     
607     	sunmouse.active = 0;
608     	misc_register (&sun_mouse_mouse);
609     	sunmouse.delta_x = sunmouse.delta_y = 0;
610     	sunmouse.button_state = 0x80;
611     	init_waitqueue_head(&sunmouse.proc_list);
612     	spin_lock_init(&sunmouse.lock);
613     	sunmouse.byte = 69;
614     }
615