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