Commit 831577c2 authored by Vojtech Pavlik's avatar Vojtech Pavlik

Modify i8042.c to be able to support non-isa based archs which

use i8042-alike keyboard controllers, namely PPC. Patch by
Franz Sirl.
parent 722c0aaf
#ifndef _I8042_IO_H
#define _I8042_IO_H
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
/*
* Names.
*/
#define I8042_KBD_PHYS_DESC "isa0060/serio0"
#define I8042_AUX_PHYS_DESC "isa0060/serio1"
/*
* IRQs.
*/
#define I8042_KBD_IRQ CONFIG_I8042_KBD_IRQ
#define I8042_AUX_IRQ CONFIG_I8042_AUX_IRQ
/*
* Register numbers.
*/
#define I8042_COMMAND_REG CONFIG_I8042_REG_BASE + 4
#define I8042_STATUS_REG CONFIG_I8042_REG_BASE + 4
#define I8042_DATA_REG CONFIG_I8042_REG_BASE
static inline int i8042_read_data(void)
{
return inb(I8042_DATA_REG);
}
static inline int i8042_read_status(void)
{
return inb(I8042_STATUS_REG);
}
static inline void i8042_write_data(int val)
{
outb(val, I8042_DATA_REG);
return;
}
static inline void i8042_write_command(int val)
{
outb(val, I8042_COMMAND_REG);
return;
}
static inline int i8042_platform_init(void)
{
/*
* On ix86 platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on ix86 boxes.
*/
#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
return 0;
#endif
return 1;
}
static inline void i8042_platform_exit(void)
{
#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__)
release_region(I8042_DATA_REG, 16);
#endif
}
#endif /* _I8042_IO_H */
#ifndef _I8042_PPCIO_H
#define _I8042_PPCIO_H
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#if defined(CONFIG_WALNUT)
#define I8042_KBD_IRQ 25
#define I8042_AUX_IRQ 26
#define I8042_KBD_PHYS_DESC "walnutps2/serio0"
#define I8042_AUX_PHYS_DESC "walnutps2/serio1"
extern void *kb_cs;
extern void *kb_data;
static inline int i8042_read_data(void)
{
return readb(kb_data);
}
static inline int i8042_read_status(void)
{
return readb(kb_cs);
}
static inline void i8042_write_data(int val)
{
writeb(val, kb_data);
return;
}
static inline void i8042_write_command(int val)
{
writeb(val, kb_cs);
return;
}
static inline int i8042_platform_init(void)
{
return 1;
}
static inline void i8042_platform_exit(void)
{
}
#elif defined(CONFIG_SPRUCE)
#define I8042_KBD_IRQ 22
#define I8042_AUX_IRQ 21
#define I8042_KBD_PHYS_DESC "spruceps2/serio0"
#define I8042_AUX_PHYS_DESC "spruceps2/serio1"
static inline int i8042_read_data(void)
{
unsigned long kbd_data;
__raw_writel(0x00000088, 0xff500008);
eieio();
__raw_writel(0x03000000, 0xff50000c);
eieio();
asm volatile("lis 7,0xff88 \n\
lswi 6,7,0x8 \n\
mr %0,6"
: "=r" (kbd_data) :: "6", "7");
__raw_writel(0x00000000, 0xff50000c);
eieio();
return (unsigned char)(kbd_data >> 24);
}
static inline int i8042_read_status(void)
{
unsigned long kbd_status;
__raw_writel(0x00000088, 0xff500008);
eieio();
__raw_writel(0x03000000, 0xff50000c);
eieio();
asm volatile("lis 7,0xff88 \n\
ori 7,7,0x8 \n\
lswi 6,7,0x8 \n\
mr %0,6"
: "=r" (kbd_status) :: "6", "7");
__raw_writel(0x00000000, 0xff50000c);
eieio();
return (unsigned char)(kbd_status >> 24);
}
static inline void i8042_write_data(int val)
{
*((unsigned char *)0xff810000) = (char)val;
return;
}
static inline void i8042_write_command(int val)
{
*((unsigned char *)0xff810001) = (char)val;
return;
}
static inline int i8042_platform_init(void)
{
return 1;
}
static inline void i8042_platform_exit(void)
{
}
#else
#include "i8042-io.h"
#endif
#endif /* _I8042_PPCIO_H */
/*
* $Id: i8042.c,v 1.21 2002/03/01 22:09:27 jsimmons Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/
/*
* i8042 keyboard and mouse controller driver for Linux
*
* Copyright (c) 1999-2002 Vojtech Pavlik
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
#include <asm/io.h>
......@@ -98,7 +80,7 @@ static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static int i8042_wait_read(void)
{
int i = 0;
while ((~inb(I8042_STATUS_REG) & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
while ((~i8042_read_status() & I8042_STR_OBF) && (i < I8042_CTL_TIMEOUT)) {
udelay(50);
i++;
}
......@@ -108,7 +90,7 @@ static int i8042_wait_read(void)
static int i8042_wait_write(void)
{
int i = 0;
while ((inb(I8042_STATUS_REG) & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
while ((i8042_read_status() & I8042_STR_IBF) && (i < I8042_CTL_TIMEOUT)) {
udelay(50);
i++;
}
......@@ -127,12 +109,12 @@ static int i8042_flush(void)
spin_lock_irqsave(&i8042_lock, flags);
while ((inb(I8042_STATUS_REG) & I8042_STR_OBF) && (i++ < I8042_BUFFER_SIZE))
while ((i8042_read_status() & I8042_STR_OBF) && (i++ < I8042_BUFFER_SIZE))
#ifdef I8042_DEBUG_IO
printk(KERN_DEBUG "i8042.c: %02x <- i8042 (flush) [%d]\n",
inb(I8042_DATA_REG), (int) (jiffies - i8042_start));
i8042_read_data(), (int) (jiffies - i8042_start));
#else
inb(I8042_DATA_REG);
i8042_read_data();
#endif
spin_unlock_irqrestore(&i8042_lock, flags);
......@@ -161,7 +143,7 @@ static int i8042_command(unsigned char *param, int command)
printk(KERN_DEBUG "i8042.c: %02x -> i8042 (command) [%d]\n",
command & 0xff, (int) (jiffies - i8042_start));
#endif
outb(command & 0xff, I8042_COMMAND_REG);
i8042_write_command(command & 0xff);
}
if (!retval)
......@@ -171,16 +153,16 @@ static int i8042_command(unsigned char *param, int command)
printk(KERN_DEBUG "i8042.c: %02x -> i8042 (parameter) [%d]\n",
param[i], (int) (jiffies - i8042_start));
#endif
outb(param[i], I8042_DATA_REG);
i8042_write_data(param[i]);
}
if (!retval)
for (i = 0; i < ((command >> 8) & 0xf); i++) {
if ((retval = i8042_wait_read())) break;
if (inb(I8042_STATUS_REG) & I8042_STR_AUXDATA)
param[i] = ~inb(I8042_DATA_REG);
if (i8042_read_status() & I8042_STR_AUXDATA)
param[i] = ~i8042_read_data();
else
param[i] = inb(I8042_DATA_REG);
param[i] = i8042_read_data();
#ifdef I8042_DEBUG_IO
printk(KERN_DEBUG "i8042.c: %02x <- i8042 (return) [%d]\n",
param[i], (int) (jiffies - i8042_start));
......@@ -217,7 +199,7 @@ static int i8042_kbd_write(struct serio *port, unsigned char c)
printk(KERN_DEBUG "i8042.c: %02x -> i8042 (kbd-data) [%d]\n",
c, (int) (jiffies - i8042_start));
#endif
outb(c, I8042_DATA_REG);
i8042_write_data(c);
}
spin_unlock_irqrestore(&i8042_lock, flags);
......@@ -337,7 +319,7 @@ static struct serio i8042_kbd_port =
close: i8042_close,
driver: &i8042_kbd_values,
name: "i8042 Kbd Port",
phys: "isa0060/serio0",
phys: I8042_KBD_PHYS_DESC,
};
static struct i8042_values i8042_aux_values = {
......@@ -356,7 +338,7 @@ static struct serio i8042_aux_port =
close: i8042_close,
driver: &i8042_aux_values,
name: "i8042 Aux Port",
phys: "isa0060/serio1",
phys: I8042_AUX_PHYS_DESC,
};
/*
......@@ -373,9 +355,9 @@ static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
spin_lock_irqsave(&i8042_lock, flags);
while ((str = inb(I8042_STATUS_REG)) & I8042_STR_OBF) {
while ((str = i8042_read_status()) & I8042_STR_OBF) {
data = inb(I8042_DATA_REG);
data = i8042_read_data();
dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
......@@ -474,7 +456,7 @@ static int __init i8042_controller_init(void)
* Handle keylock.
*/
if (~inb(I8042_STATUS_REG) & I8042_STR_KEYLOCK) {
if (~i8042_read_status() & I8042_STR_KEYLOCK) {
if (i8042_unlock) {
i8042_ctr |= I8042_CTR_IGNKEYLOCK;
......@@ -716,14 +698,8 @@ int __init i8042_init(void)
i8042_start = jiffies;
#endif
/*
* On ix86 platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on ix86 boxes.
*/
#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
if (!i8042_platform_init())
return -EBUSY;
#endif
if (i8042_controller_init())
return -ENODEV;
......@@ -754,9 +730,7 @@ void __exit i8042_exit(void)
i8042_controller_cleanup();
#if !defined(__i386__) && !defined(__sh__) && !defined(__alpha__)
release_region(I8042_DATA_REG, 16);
#endif
i8042_platform_exit();
}
module_init(i8042_init);
......
......@@ -2,31 +2,23 @@
#define _I8042_H
/*
* $Id: i8042.h,v 1.6 2001/10/05 22:48:09 vojtech Exp $
* Copyright (c) 1999-2002 Vojtech Pavlik
*
* Copyright (c) 1999-2001 Vojtech Pavlik
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
* Arch-dependent inline functions and defines.
*/
#if defined(CONFIG_PPC)
#include "i8042-ppcio.h"
#else
#include "i8042-io.h"
#endif
/*
* If you want to trace all the i/o the i8042 module does for
* debugging purposes, define this.
......@@ -34,20 +26,6 @@
#undef I8042_DEBUG_IO
/*
* On most PC based systems the keyboard IRQ is 1.
*/
#define I8042_KBD_IRQ CONFIG_I8042_KBD_IRQ
/*
* On most PC based systems the aux port IRQ is 12. There are exceptions,
* though. Unfortunately IRQ probing is not possible without touching
* the device attached to the port.
*/
#define I8042_AUX_IRQ CONFIG_I8042_AUX_IRQ
/*
* This is in 50us units, the time we wait for the i8042 to react. This
* has to be long enough for the i8042 itself to timeout on sending a byte
......@@ -65,14 +43,6 @@
#define I8042_POLL_PERIOD HZ/20
/*
* Register numbers.
*/
#define I8042_COMMAND_REG CONFIG_I8042_REG_BASE + 4
#define I8042_STATUS_REG CONFIG_I8042_REG_BASE + 4
#define I8042_DATA_REG CONFIG_I8042_REG_BASE
/*
* Status register bits.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment