1/* 2 * 3 * BRIEF MODULE DESCRIPTION 4 * Qtronix 990P infrared keyboard driver. 5 * 6 * 7 * Copyright 2001 MontaVista Software Inc. 8 * Author: MontaVista Software, Inc. 9 * ppopov@mvista.com or source@mvista.com 10 * 11 * 12 * The bottom portion of this driver was take from 13 * pc_keyb.c Please see that file for copyrights. 14 * 15 * This program is free software; you can redistribute it and/or modify it 16 * under the terms of the GNU General Public License as published by the 17 * Free Software Foundation; either version 2 of the License, or (at your 18 * option) any later version. 19 * 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * You should have received a copy of the GNU General Public License along 32 * with this program; if not, write to the Free Software Foundation, Inc., 33 * 675 Mass Ave, Cambridge, MA 02139, USA. 34 */ 35 36#include <linux/config.h> 37 38/* 39 * NOTE: 40 * 41 * This driver has only been tested with the Consumer IR 42 * port of the ITE 8172 system controller. 43 * 44 * You do not need this driver if you are using the ps/2 or 45 * USB adapter that the keyboard ships with. You only need 46 * this driver if your board has a IR port and the keyboard 47 * data is being sent directly to the IR. In that case, 48 * you also need some low-level IR support. See it8172_cir.c. 49 * 50 */ 51 52#ifdef CONFIG_QTRONIX_KEYBOARD 53 54#include <linux/module.h> 55#include <linux/types.h> 56#include <linux/pci.h> 57#include <linux/kernel.h> 58 59#include <asm/it8172/it8172.h> 60#include <asm/it8172/it8172_int.h> 61#include <asm/it8172/it8172_cir.h> 62 63#include <linux/spinlock.h> 64#include <linux/sched.h> 65#include <linux/interrupt.h> 66#include <linux/tty.h> 67#include <linux/mm.h> 68#include <linux/signal.h> 69#include <linux/init.h> 70#include <linux/kbd_ll.h> 71#include <linux/delay.h> 72#include <linux/random.h> 73#include <linux/poll.h> 74#include <linux/miscdevice.h> 75#include <linux/slab.h> 76#include <linux/kbd_kern.h> 77#include <linux/smp_lock.h> 78#include <asm/io.h> 79#include <linux/pc_keyb.h> 80 81#include <asm/keyboard.h> 82#include <asm/bitops.h> 83#include <asm/uaccess.h> 84#include <asm/irq.h> 85#include <asm/system.h> 86 87#define leading1 0 88#define leading2 0xF 89 90#define KBD_CIR_PORT 0 91#define AUX_RECONNECT 170 /* scancode when ps2 device is plugged (back) in */ 92 93static int data_index; 94struct cir_port *cir; 95static unsigned char kbdbytes[5]; 96static unsigned char cir_data[32]; /* we only need 16 chars */ 97 98static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs); 99static int handle_data(unsigned char *p_data); 100static inline void handle_mouse_event(unsigned char scancode); 101static inline void handle_keyboard_event(unsigned char scancode, int down); 102static int __init psaux_init(void); 103 104static struct aux_queue *queue; /* Mouse data buffer. */ 105static int aux_count = 0; 106 107/* 108 * Keys accessed through the 'Fn' key 109 * The Fn key does not produce a key-up sequence. So, the first 110 * time the user presses it, it will be key-down event. The key 111 * stays down until the user presses it again. 112 */ 113#define NUM_FN_KEYS 56 114static unsigned char fn_keys[NUM_FN_KEYS] = { 115 0,0,0,0,0,0,0,0, /* 0 7 */ 116 8,9,10,93,0,0,0,0, /* 8 15 */ 117 0,0,0,0,0,0,0,5, /* 16 23 */ 118 6,7,91,0,0,0,0,0, /* 24 31 */ 119 0,0,0,0,0,2,3,4, /* 32 39 */ 120 92,0,0,0,0,0,0,0, /* 40 47 */ 121 0,0,0,0,11,0,94,95 /* 48 55 */ 122 123}; 124 125void __init init_qtronix_990P_kbd(void) 126{ 127 int retval; 128 129 cir = (struct cir_port *)kmalloc(sizeof(struct cir_port), GFP_KERNEL); 130 if (!cir) { 131 printk("Unable to initialize Qtronix keyboard\n"); 132 return; 133 } 134 135 /* 136 * revisit 137 * this should be programmable, somehow by the, by the user. 138 */ 139 cir->port = KBD_CIR_PORT; 140 cir->baud_rate = 0x1d; 141 cir->rdwos = 0; 142 cir->rxdcr = 0x3; 143 cir->hcfs = 0; 144 cir->fifo_tl = 0; 145 cir->cfq = 0x1d; 146 cir_port_init(cir); 147 148 retval = request_irq(IT8172_CIR0_IRQ, kbd_int_handler, 149 (unsigned long )(SA_INTERRUPT|SA_SHIRQ), 150 (const char *)"Qtronix IR Keyboard", (void *)cir); 151 152 if (retval) { 153 printk("unable to allocate cir %d irq %d\n", 154 cir->port, IT8172_CIR0_IRQ); 155 } 156#ifdef CONFIG_PSMOUSE 157 psaux_init(); 158#endif 159} 160 161static inline unsigned char BitReverse(unsigned short key) 162{ 163 unsigned char rkey = 0; 164 rkey |= (key & 0x1) << 7; 165 rkey |= (key & 0x2) << 5; 166 rkey |= (key & 0x4) << 3; 167 rkey |= (key & 0x8) << 1; 168 rkey |= (key & 0x10) >> 1; 169 rkey |= (key & 0x20) >> 3; 170 rkey |= (key & 0x40) >> 5; 171 rkey |= (key & 0x80) >> 7; 172 return rkey; 173 174} 175 176 177static inline u_int8_t UpperByte(u_int8_t data) 178{ 179 return (data >> 4); 180} 181 182 183static inline u_int8_t LowerByte(u_int8_t data) 184{ 185 return (data & 0xF); 186} 187 188 189int CheckSumOk(u_int8_t byte1, u_int8_t byte2, 190 u_int8_t byte3, u_int8_t byte4, u_int8_t byte5) 191{ 192 u_int8_t CheckSum; 193 194 CheckSum = (byte1 & 0x0F) + byte2 + byte3 + byte4 + byte5; 195 if ( LowerByte(UpperByte(CheckSum) + LowerByte(CheckSum)) != UpperByte(byte1) ) 196 return 0; 197 else 198 return 1; 199} 200 201 202static void kbd_int_handler(int irq, void *dev_id, struct pt_regs *regs) 203{ 204 struct cir_port *cir; 205 int j; 206 unsigned char int_status; 207 208 cir = (struct cir_port *)dev_id; 209 int_status = get_int_status(cir);; 210 if (int_status & 0x4) { 211 clear_fifo(cir); 212 return; 213 } 214 215 while (cir_get_rx_count(cir)) { 216 217 cir_data[data_index] = cir_read_data(cir); 218 219 if (data_index == 0) {/* expecting first byte */ 220 if (cir_data[data_index] != leading1) { 221 //printk("!leading byte %x\n", cir_data[data_index]); 222 set_rx_active(cir); 223 clear_fifo(cir); 224 continue; 225 } 226 } 227 if (data_index == 1) { 228 if ((cir_data[data_index] & 0xf) != leading2) { 229 set_rx_active(cir); 230 data_index = 0; /* start over */ 231 clear_fifo(cir); 232 continue; 233 } 234 } 235 236 if ( (cir_data[data_index] == 0xff)) { /* last byte */ 237 //printk("data_index %d\n", data_index); 238 set_rx_active(cir); 239 data_index = 0; 240 handle_data(cir_data); 241 return; 242 } 243 else if (data_index>16) { 244 set_rx_active(cir); 245 data_index = 0; 246 clear_fifo(cir); 247 return; 248 } 249 data_index++; 250 } 251} 252 253 254#define NUM_KBD_BYTES 5 255static int handle_data(unsigned char *p_data) 256{ 257 u_int32_t bit_bucket; 258 u_int32_t i, j; 259 u_int32_t got_bits, next_byte; 260 int down = 0; 261 262 /* Reorganize the bit stream */ 263 for (i=0; i<16; i++) 264 p_data[i] = BitReverse(~p_data[i]); 265 266 /* 267 * We've already previously checked that p_data[0] 268 * is equal to leading1 and that (p_data[1] & 0xf) 269 * is equal to leading2. These twelve bits are the 270 * leader code. We can now throw them away (the 12 271 * bits) and continue parsing the stream. 272 */ 273 bit_bucket = p_data[1] << 12; 274 got_bits = 4; 275 next_byte = 2; 276 277 /* 278 * Process four bits at a time 279 */ 280 for (i=0; i<NUM_KBD_BYTES; i++) { 281 282 kbdbytes[i]=0; 283 284 for (j=0; j<8; j++) /* 8 bits per byte */ 285 { 286 if (got_bits < 4) { 287 bit_bucket |= (p_data[next_byte++] << (8 - got_bits)); 288 got_bits += 8; 289 } 290 291 if ((bit_bucket & 0xF000) == 0x8000) { 292 /* Convert 1000b to 1 */ 293 kbdbytes[i] = 0x80 | (kbdbytes[i] >> 1); 294 got_bits -= 4; 295 bit_bucket = bit_bucket << 4; 296 } 297 else if ((bit_bucket & 0xC000) == 0x8000) { 298 /* Convert 10b to 0 */ 299 kbdbytes[i] = kbdbytes[i] >> 1; 300 got_bits -= 2; 301 bit_bucket = bit_bucket << 2; 302 } 303 else { 304 /* bad serial stream */ 305 return 1; 306 } 307 308 if (next_byte > 16) { 309 //printk("error: too many bytes\n"); 310 return 1; 311 } 312 } 313 } 314 315 316 if (!CheckSumOk(kbdbytes[0], kbdbytes[1], 317 kbdbytes[2], kbdbytes[3], kbdbytes[4])) { 318 //printk("checksum failed\n"); 319 return 1; 320 } 321 322 if (kbdbytes[1] & 0x08) { 323 //printk("m: %x %x %x\n", kbdbytes[1], kbdbytes[2], kbdbytes[3]); 324 handle_mouse_event(kbdbytes[1]); 325 handle_mouse_event(kbdbytes[2]); 326 handle_mouse_event(kbdbytes[3]); 327 } 328 else { 329 if (kbdbytes[2] == 0) down = 1; 330 handle_keyboard_event(kbdbytes[3], down); 331 } 332 return 0; 333} 334 335 336spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED; 337static unsigned char handle_kbd_event(void); 338 339 340int kbd_setkeycode(unsigned int scancode, unsigned int keycode) 341{ 342 printk("kbd_setkeycode scancode %x keycode %x\n", scancode, keycode); 343 return 0; 344} 345 346int kbd_getkeycode(unsigned int scancode) 347{ 348 return scancode; 349} 350 351 352int kbd_translate(unsigned char scancode, unsigned char *keycode, 353 char raw_mode) 354{ 355 static int prev_scancode = 0; 356 357 if (scancode == 0x00 || scancode == 0xff) { 358 prev_scancode = 0; 359 return 0; 360 } 361 362 /* todo */ 363 if (!prev_scancode && scancode == 160) { /* Fn key down */ 364 //printk("Fn key down\n"); 365 prev_scancode = 160; 366 return 0; 367 } 368 else if (prev_scancode && scancode == 160) { /* Fn key up */ 369 //printk("Fn key up\n"); 370 prev_scancode = 0; 371 return 0; 372 } 373 374 /* todo */ 375 if (prev_scancode == 160) { 376 if (scancode <= NUM_FN_KEYS) { 377 *keycode = fn_keys[scancode]; 378 //printk("fn keycode %d\n", *keycode); 379 } 380 else 381 return 0; 382 } 383 else if (scancode <= 127) { 384 *keycode = scancode; 385 } 386 else 387 return 0; 388 389 390 return 1; 391} 392 393char kbd_unexpected_up(unsigned char keycode) 394{ 395 //printk("kbd_unexpected_up\n"); 396 return 0; 397} 398 399static unsigned char kbd_exists = 1; 400 401static inline void handle_keyboard_event(unsigned char scancode, int down) 402{ 403 kbd_exists = 1; 404 handle_scancode(scancode, down); 405 tasklet_schedule(&keyboard_tasklet); 406} 407 408 409void kbd_leds(unsigned char leds) 410{ 411} 412 413/* dummy */ 414void kbd_init_hw(void) 415{ 416} 417 418 419 420static inline void handle_mouse_event(unsigned char scancode) 421{ 422 if(scancode == AUX_RECONNECT){ 423 queue->head = queue->tail = 0; /* Flush input queue */ 424 // __aux_write_ack(AUX_ENABLE_DEV); /* ping the mouse :) */ 425 return; 426 } 427 428 add_mouse_randomness(scancode); 429 if (aux_count) { 430 int head = queue->head; 431 432 queue->buf[head] = scancode; 433 head = (head + 1) & (AUX_BUF_SIZE-1); 434 if (head != queue->tail) { 435 queue->head = head; 436 kill_fasync(&queue->fasync, SIGIO, POLL_IN); 437 wake_up_interruptible(&queue->proc_list); 438 } 439 } 440} 441 442static unsigned char get_from_queue(void) 443{ 444 unsigned char result; 445 unsigned long flags; 446 447 spin_lock_irqsave(&kbd_controller_lock, flags); 448 result = queue->buf[queue->tail]; 449 queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1); 450 spin_unlock_irqrestore(&kbd_controller_lock, flags); 451 return result; 452} 453 454 455static inline int queue_empty(void) 456{ 457 return queue->head == queue->tail; 458} 459 460static int fasync_aux(int fd, struct file *filp, int on) 461{ 462 int retval; 463 464 //printk("fasync_aux\n"); 465 retval = fasync_helper(fd, filp, on, &queue->fasync); 466 if (retval < 0) 467 return retval; 468 return 0; 469} 470 471 472/* 473 * Random magic cookie for the aux device 474 */ 475#define AUX_DEV ((void *)queue) 476 477static int release_aux(struct inode * inode, struct file * file) 478{ 479 lock_kernel(); 480 fasync_aux(-1, file, 0); 481 aux_count--; 482 unlock_kernel(); 483 return 0; 484} 485 486static int open_aux(struct inode * inode, struct file * file) 487{ 488 if (aux_count++) { 489 return 0; 490 } 491 queue->head = queue->tail = 0; /* Flush input queue */ 492 return 0; 493} 494 495/* 496 * Put bytes from input queue to buffer. 497 */ 498 499static ssize_t read_aux(struct file * file, char * buffer, 500 size_t count, loff_t *ppos) 501{ 502 DECLARE_WAITQUEUE(wait, current); 503 ssize_t i = count; 504 unsigned char c; 505 506 if (queue_empty()) { 507 if (file->f_flags & O_NONBLOCK) 508 return -EAGAIN; 509 add_wait_queue(&queue->proc_list, &wait); 510repeat: 511 set_current_state(TASK_INTERRUPTIBLE); 512 if (queue_empty() && !signal_pending(current)) { 513 schedule(); 514 goto repeat; 515 } 516 current->state = TASK_RUNNING; 517 remove_wait_queue(&queue->proc_list, &wait); 518 } 519 while (i > 0 && !queue_empty()) { 520 c = get_from_queue(); 521 put_user(c, buffer++); 522 i--; 523 } 524 if (count-i) { 525 file->f_dentry->d_inode->i_atime = CURRENT_TIME; 526 return count-i; 527 } 528 if (signal_pending(current)) 529 return -ERESTARTSYS; 530 return 0; 531} 532 533/* 534 * Write to the aux device. 535 */ 536 537static ssize_t write_aux(struct file * file, const char * buffer, 538 size_t count, loff_t *ppos) 539{ 540 /* 541 * The ITE boards this was tested on did not have the 542 * transmit wires connected. 543 */ 544 return count; 545} 546 547static unsigned int aux_poll(struct file *file, poll_table * wait) 548{ 549 poll_wait(file, &queue->proc_list, wait); 550 if (!queue_empty()) 551 return POLLIN | POLLRDNORM; 552 return 0; 553} 554 555struct file_operations psaux_fops = { 556 read: read_aux, 557 write: write_aux, 558 poll: aux_poll, 559 open: open_aux, 560 release: release_aux, 561 fasync: fasync_aux, 562}; 563 564/* 565 * Initialize driver. 566 */ 567static struct miscdevice psaux_mouse = { 568 PSMOUSE_MINOR, "psaux", &psaux_fops 569}; 570 571static int __init psaux_init(void) 572{ 573 misc_register(&psaux_mouse); 574 queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); 575 memset(queue, 0, sizeof(*queue)); 576 queue->head = queue->tail = 0; 577 init_waitqueue_head(&queue->proc_list); 578 579 return 0; 580} 581module_init(init_qtronix_990P_kbd); 582#endif 583