--- /dev/null
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/arch/i386/Kconfig linux-2.6.1-gentoo-test/arch/i386/Kconfig
+--- linux-2.6.1-gentoo/arch/i386/Kconfig 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/arch/i386/Kconfig 2004-01-09 22:33:09.000000000 +0000
+@@ -586,6 +586,9 @@
+ Say Y if you intend to run this kernel on a Dell Inspiron 8000.
+ Say N otherwise.
+
++config OMNIBOOK
++ tristate "HP Omnibook Support"
++
+ config MICROCODE
+ tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
+ ---help---
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/arch/i386/kernel/cpu/cpufreq/powernow-k7.c linux-2.6.1-gentoo-test/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+--- linux-2.6.1-gentoo/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/arch/i386/kernel/cpu/cpufreq/powernow-k7.c 2004-01-09 22:32:23.000000000 +0000
+@@ -279,6 +279,8 @@
+ etuple &= 0xf00;
+ etuple |= (c->x86_model<<4)|(c->x86_mask);
+
++ if (etuple == 0x7a0) { etuple = 0x781; }
++
+ for (i=0xC0000; i < 0xffff0 ; i+=16) {
+
+ p = phys_to_virt(i);
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/Makefile linux-2.6.1-gentoo-test/drivers/char/Makefile
+--- linux-2.6.1-gentoo/drivers/char/Makefile 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/drivers/char/Makefile 2004-01-09 22:33:09.000000000 +0000
+@@ -61,6 +61,7 @@
+ endif
+ obj-$(CONFIG_TOSHIBA) += toshiba.o
+ obj-$(CONFIG_I8K) += i8k.o
++obj-$(CONFIG_OMNIBOOK) += omnibook/
+ obj-$(CONFIG_DS1620) += ds1620.o
+ obj-$(CONFIG_HW_RANDOM) += hw_random.o
+ obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/drm/radeon_cp.c linux-2.6.1-gentoo-test/drivers/char/drm/radeon_cp.c
+--- linux-2.6.1-gentoo/drivers/char/drm/radeon_cp.c 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/drivers/char/drm/radeon_cp.c 2004-01-09 23:33:45.000000000 +0000
+@@ -855,7 +855,8 @@
+
+ /* Initialize the memory controller */
+ RADEON_WRITE( RADEON_MC_FB_LOCATION,
+- (dev_priv->gart_vm_start - 1) & 0xffff0000 );
++ ((dev_priv->gart_vm_start - 1) & 0xffff0000 ) |
++ (dev_priv->fb_base >> 16));
+
+ #if __REALLY_HAVE_AGP
+ if ( !dev_priv->is_pci ) {
+@@ -1071,13 +1072,6 @@
+ dev_priv->depth_offset = init->depth_offset;
+ dev_priv->depth_pitch = init->depth_pitch;
+
+- dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
+- (dev_priv->front_offset >> 10));
+- dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
+- (dev_priv->back_offset >> 10));
+- dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
+- (dev_priv->depth_offset >> 10));
+-
+ /* Hardware state for depth clears. Remove this if/when we no
+ * longer clear the depth buffer with a 3D rectangle. Hard-code
+ * all values to prevent unwanted 3D state from slipping through
+@@ -1204,9 +1198,17 @@
+ dev_priv->buffers->handle );
+ }
+
++ dev_priv->fb_base = (RADEON_READ( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
++ dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) |
++ ((dev_priv->front_offset+dev_priv->fb_base) >> 10));
++ dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) |
++ ((dev_priv->back_offset+dev_priv->fb_base) >> 10));
++ dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) |
++ ((dev_priv->depth_offset+dev_priv->fb_base) >> 10));
+
+ dev_priv->gart_size = init->gart_size;
+- dev_priv->gart_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE );
++ dev_priv->gart_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ) + dev_priv->fb_base;
++
+ #if __REALLY_HAVE_AGP
+ if ( !dev_priv->is_pci )
+ dev_priv->gart_buffers_offset = (dev_priv->buffers->offset
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/drm/radeon_drv.h linux-2.6.1-gentoo-test/drivers/char/drm/radeon_drv.h
+--- linux-2.6.1-gentoo/drivers/char/drm/radeon_drv.h 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/drivers/char/drm/radeon_drv.h 2004-01-09 22:32:40.000000000 +0000
+@@ -125,6 +125,7 @@
+
+ drm_radeon_depth_clear_t depth_clear;
+
++ unsigned long fb_base;
+ unsigned long fb_offset;
+ unsigned long mmio_offset;
+ unsigned long ring_offset;
+@@ -146,7 +147,6 @@
+ /* SW interrupt */
+ wait_queue_head_t swi_queue;
+ atomic_t swi_emitted;
+-
+ } drm_radeon_private_t;
+
+ typedef struct drm_radeon_buf_priv {
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/drm/radeon_state.c linux-2.6.1-gentoo-test/drivers/char/drm/radeon_state.c
+--- linux-2.6.1-gentoo/drivers/char/drm/radeon_state.c 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/drivers/char/drm/radeon_state.c 2004-01-09 22:32:40.000000000 +0000
+@@ -153,7 +153,7 @@
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) );
+ OUT_RING( tex[0].pp_txfilter );
+ OUT_RING( tex[0].pp_txformat );
+- OUT_RING( tex[0].pp_txoffset );
++ OUT_RING( tex[0].pp_txoffset + dev_priv->fb_base);
+ OUT_RING( tex[0].pp_txcblend );
+ OUT_RING( tex[0].pp_txablend );
+ OUT_RING( tex[0].pp_tfactor );
+@@ -167,7 +167,7 @@
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) );
+ OUT_RING( tex[1].pp_txfilter );
+ OUT_RING( tex[1].pp_txformat );
+- OUT_RING( tex[1].pp_txoffset );
++ OUT_RING( tex[1].pp_txoffset + dev_priv->fb_base);
+ OUT_RING( tex[1].pp_txcblend );
+ OUT_RING( tex[1].pp_txablend );
+ OUT_RING( tex[1].pp_tfactor );
+@@ -181,7 +181,7 @@
+ OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) );
+ OUT_RING( tex[2].pp_txfilter );
+ OUT_RING( tex[2].pp_txformat );
+- OUT_RING( tex[2].pp_txoffset );
++ OUT_RING( tex[2].pp_txoffset + dev_priv->fb_base);
+ OUT_RING( tex[2].pp_txcblend );
+ OUT_RING( tex[2].pp_txablend );
+ OUT_RING( tex[2].pp_tfactor );
+@@ -1178,7 +1178,7 @@
+ RADEON_GMC_CLR_CMP_CNTL_DIS |
+ RADEON_GMC_WR_MSK_DIS);
+
+- buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
++ buffer[2] = (tex->pitch << 22) | ((tex->offset + dev_priv->fb_base) >> 10);
+ buffer[3] = 0xffffffff;
+ buffer[4] = 0xffffffff;
+ buffer[5] = (image->y << 16) | image->x;
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/Makefile linux-2.6.1-gentoo-test/drivers/char/omnibook/Makefile
+--- linux-2.6.1-gentoo/drivers/char/omnibook/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/Makefile 2004-01-09 22:33:10.000000000 +0000
+@@ -0,0 +1,37 @@
++#
++# Makefile -- makefile for the HP OmniBook support module
++#
++# 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, 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.
++#
++# Written by Soós Péter <sp@osb.hu>, 2002,2003
++#
++# Note! Dependencies are done automagically by 'make dep', which also
++# removes any old dependencies. DON'T put your own dependencies here
++# unless it's something special (ie not a .c file).
++#
++# Note 2! The CFLAGS definitions are now in the main makefile...
++
++#export-objs := ac.o battery.o blank.o display.o dmi.o dock.o fan.o \
++ fan_policy.o init.o lcd.o onetouch.o polling.o temperature.o \
++ touchpad.o
++
++#O_TARGET := omnibook.o
++
++#obj-y := ac.o apmemu.o battery.o blank.o dmi.o display.o dock.o ec.o \
++ fan.o fan_policy.o init.o lcd.o onetouch.o polling.o \
++ temperature.o touchpad.o util.o
++#obj-m := $(O_TARGET)
++
++#include $(TOPDIR)/Rules.make
++
++obj-$(CONFIG_OMNIBOOK) += omnibook.o
++
++omnibook-objs := ac.o apmemu.o battery.o blank.o dmi.o display.o dock.o ec.o fan.o fan_policy.o init.o lcd.o onetouch.o temperature.o touchpad.o util.o
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/ac.c linux-2.6.1-gentoo-test/drivers/char/omnibook/ac.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/ac.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/ac.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,134 @@
++/*
++ * ac.c -- AC adapter related functions
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_ac;
++
++int omnibook_get_ac(void)
++{
++ u8 ac;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_ADP, &ac)))
++ return retval;
++ retval = (ac & XE3GF_ADP_MASK) ? 1 : 0;
++ break;
++ case XE3GC:
++ if ((retval = omnibook_ec_read(XE3GC_STA1, &ac)))
++ return retval;
++ retval = (ac & XE3GC_ADP_MASK) ? 1 : 0;
++ break;
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ if ((retval = omnibook_ec_read(OB500_STA2, &ac)))
++ return retval;
++ retval = (ac & OB500_ADP_MASK) ? 1 : 0;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_ADP, &ac)))
++ return retval;
++ retval = (ac & OB4150_ADP_MASK) ? 1 : 0;
++ break;
++ case XE2:
++ if ((retval = omnibook_ec_read(XE2_STA1, &ac)))
++ return retval;
++ retval = (ac & XE2_ADP_MASK) ? 1 : 0;
++ break;
++ default:
++ printk(KERN_INFO "%s: AC adapter status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++ return retval;
++}
++
++static int omnibook_proc_ac(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++ int ac;
++
++ ac = omnibook_get_ac();
++ if (ac < 0)
++ return ac;
++
++ b += sprintf(b, "AC %s\n", (ac) ? "on-line" : "off-line");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++int __init omnibook_ac_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ case OB4150:
++ case XE2:
++ pmode = S_IFREG | S_IRUGO;
++ proc_ac = create_proc_read_entry("ac", pmode, omnibook_proc_root, omnibook_proc_ac, NULL);
++ break;
++ default:
++ printk(KERN_INFO "%s: AC adapter status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_ac) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/ac.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: AC adapter status monitoring is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_ac_cleanup(void)
++{
++ if (proc_ac)
++ remove_proc_entry("ac", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_get_ac);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/apmemu.c linux-2.6.1-gentoo-test/drivers/char/omnibook/apmemu.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/apmemu.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/apmemu.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,187 @@
++/*
++ * apmemu.c -- /proc/apm emulation
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#ifdef CONFIG_APM
++#include <linux/apm_bios.h>
++#endif
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "apmemu.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_apmemu;
++
++/* Arguments, with symbols from linux/apm_bios.h. Information is
++ from the Get Power Status (0x0a) call unless otherwise noted.
++ 0) Linux driver version (this will change if format changes)
++ 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
++ 2) APM flags from APM Installation Check (0x00):
++ bit 0: APM_16_BIT_SUPPORT
++ bit 1: APM_32_BIT_SUPPORT
++ bit 2: APM_IDLE_SLOWS_CLOCK
++ bit 3: APM_BIOS_DISABLED
++ bit 4: APM_BIOS_DISENGAGED
++ 3) AC line status
++ 0x00: Off-line
++ 0x01: On-line
++ 0x02: On backup power (BIOS >= 1.1 only)
++ 0xff: Unknown
++ 4) Battery status
++ 0x00: High
++ 0x01: Low
++ 0x02: Critical
++ 0x03: Charging
++ 0x04: Selected battery not present (BIOS >= 1.2 only)
++ 0xff: Unknown
++ 5) Battery flag
++ bit 0: High
++ bit 1: Low
++ bit 2: Critical
++ bit 3: Charging
++ bit 7: No system battery
++ 0xff: Unknown
++ 6) Remaining battery life (percentage of charge):
++ 0-100: valid
++ -1: Unknown
++ 7) Remaining battery life (time units):
++ Number of remaining minutes or seconds
++ -1: Unknown
++ 8) min = minutes; sec = seconds */
++
++static int omnibook_proc_apmemu(char *buffer, char **start, off_t off, int count)
++{
++ int retval;
++ char *b = buffer;
++
++ int ac;
++ struct omnibook_battery_status battstat;
++
++ struct apm_features {
++ char *drvver;
++ char *apmver;
++ u8 apmflags;
++ u8 ac;
++ u8 battstat;
++ u8 battflags;
++ u8 gauge;
++ int time;
++ char *units;
++ };
++
++ struct apm_features apm = {
++ APMEMU_DRIVER_VERSION,
++ APMEMU_APM_VERSION,
++ APMEMU_32_BIT_SUPPORT | APMEMU_BIOS_DISABLED,
++ APMEMU_AC_UNKNOWN,
++ APMEMU_BATTSTAT_UNKN,
++ 0x00,
++ APMEMU_BATTLIFE_UNKN,
++ APMEMU_BATTLIFE_UNKN,
++ "?"
++ };
++
++ ac = omnibook_get_ac();
++ apm.ac = (ac) ? APMEMU_AC_ONLINE : APMEMU_AC_OFFLINE;
++ /* Asking for Battery 0 as APM does */
++ retval = omnibook_get_battery_status(0, &battstat);
++ if (retval == 0)
++ apm.gauge = battstat.gauge;
++ if (apm.gauge >= APMEMU_BATTERY_LOW) {
++ apm.battflags = apm.battflags | APMEMU_BATTFLAG_HIGH;
++ apm.battstat = APMEMU_BATTSTAT_HIGH;
++ } else {
++ apm.battflags = apm.battflags | APMEMU_BATTFLAG_LOW;
++ apm.battstat = APMEMU_BATTSTAT_LOW;
++ }
++ if (battstat.status == OMNIBOOK_BATTSTAT_CHARGING) {
++ apm.battflags = apm.battflags | APMEMU_BATTFLAG_CHR;
++ apm.battstat = APMEMU_BATTSTAT_CHR;
++ }
++ if (battstat.status == OMNIBOOK_BATTSTAT_CRITICAL) {
++ apm.battflags = apm.battflags | APMEMU_BATTFLAG_CRIT;
++ apm.battstat = APMEMU_BATTSTAT_CRIT;
++ }
++
++ b += sprintf(b, "%s %s 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
++ apm.drvver,
++ apm.apmver,
++ apm.apmflags,
++ apm.ac,
++ apm.battstat,
++ apm.battflags,
++ apm.gauge,
++ apm.time,
++ apm.units
++ );
++
++ return b - buffer;
++}
++
++int __init omnibook_apmemu_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++#ifdef CONFIG_APM
++ if (! apm_info.disabled) {
++ printk(KERN_NOTICE "%s: Real APM support is present, emulation is not necessary.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++#endif
++ pmode = S_IFREG | S_IRUGO;
++ proc_apmemu = create_proc_info_entry("apm", pmode, NULL, omnibook_proc_apmemu);
++ break;
++ default:
++ printk(KERN_INFO "%s: /proc/apm emulation is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_apmemu) {
++ printk(KERN_ERR "%s: Unable to create /proc/apm.\n", OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: /proc/apm emulation enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_apmemu_cleanup(void)
++{
++ if (proc_apmemu) {
++ remove_proc_entry("apm", NULL);
++ printk(KERN_INFO "%s: /proc/apm emulation disabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++}
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/apmemu.h linux-2.6.1-gentoo-test/drivers/char/omnibook/apmemu.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/apmemu.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/apmemu.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,48 @@
++/*
++ * apmemu.c -- code to emulate /proc/apm
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#define APMEMU_DRIVER_VERSION "1.16"
++#define APMEMU_APM_VERSION "1.2"
++
++#define APMEMU_BATTERY_LOW 30 /* Battery low threshold */
++
++#define APMEMU_16_BIT_SUPPORT 0x01 /* 16 bit APM BIOS */
++#define APMEMU_32_BIT_SUPPORT 0x02 /* 32 bit APM BIOS */
++#define APMEMU_IDLE_SLOWS_CLOCK 0x04
++#define APMEMU_BIOS_DISABLED 0x08 /* APM BIOS disabled */
++#define APMEMU_BIOS_DISENGAGED 0x10 /* APM BIOS disengaged */
++
++#define APMEMU_AC_OFFLINE 0x00 /* AC offline */
++#define APMEMU_AC_ONLINE 0x01 /* AC online */
++#define APMEMU_AC_BACKUP 0x02 /* On backup power */
++#define APMEMU_AC_UNKNOWN 0xFF /* Unkonwn status */
++
++#define APMEMU_BATTSTAT_HIGH 0x00 /* Remaining battery capacity is high */
++#define APMEMU_BATTSTAT_LOW 0x01 /* Remaining battery capacity is low */
++#define APMEMU_BATTSTAT_CRIT 0x02 /* Battery status is critical */
++#define APMEMU_BATTSTAT_CHR 0x03 /* Battery is charging */
++#define APMEMU_BATTSTAT_MISS 0x04 /* Battery is not present */
++
++#define APMEMU_BATTFLAG_HIGH 0x01 /* Remaining battery capacity is high bit */
++#define APMEMU_BATTFLAG_LOW 0x02 /* Remaining battery capacity is low bit */
++#define APMEMU_BATTFLAG_CRIT 0x04 /* Battery status is critical bit */
++#define APMEMU_BATTFLAG_CHR 0x08 /* Battery is charging bit */
++#define APMEMU_BATTFLAG_MISS 0x80 /* Battery is not present bit */
++
++#define APMEMU_BATTSTAT_UNKN 0xff /* Status is unknown */
++
++#define APMEMU_BATTLIFE_UNKN -1 /* Remaining battery capacity is unknown */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/battery.c linux-2.6.1-gentoo-test/drivers/char/omnibook/battery.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/battery.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/battery.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,426 @@
++/*
++ * battery.c -- battery related functions
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_battery;
++
++int omnibook_battery_present(int num)
++{
++ int retval;
++ int i;
++ u8 bat;
++ u8 mask = 0;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if (num >= 2)
++ return -EINVAL;
++ if ((retval = omnibook_ec_read(XE3GF_BAL, &bat)))
++ return retval;
++ mask = XE3GF_BAL0_MASK;
++ for (i = 0; i < num; i++)
++ mask = mask << 1;
++ break;
++ case XE3GC:
++ if (num >= 2)
++ return -EINVAL;
++ if ((retval = omnibook_ec_read(XE3GC_BAT, &bat)))
++ return retval;
++ mask = XE3GC_BAT0_MASK;
++ for (i = 0; i < num; i++)
++ mask = mask << 1;
++ break;
++ }
++ return (bat & mask) ? 1 : 0;
++}
++
++/*
++ * Get static battery information
++ * All info have to be reread every time because battery sould be cahnged
++ * when laptop is on AC power
++ * return values:
++ * < 0 - ERROR
++ * 0 - OK
++ * 1 - Battery is not present
++ * 2 - Not supported
++ */
++int omnibook_get_battery_info(int num, struct omnibook_battery_info *battinfo)
++{
++ int retval;
++ u32 offset;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ offset = 0x10;
++ retval = omnibook_battery_present(num);
++ if (retval < 0)
++ return retval;
++ if (retval) {
++ if ((retval = omnibook_ec_read(XE3GF_BTY0 + (offset * num), &(*battinfo).type)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BSN0 + (offset * num), &(*battinfo).sn)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BDV0 + (offset * num), &(*battinfo).dv)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BDC0 + (offset * num), &(*battinfo).dc)))
++ return retval;
++
++ (*battinfo).type = ((*battinfo).type & XE3GF_BTY_MASK) ? 1 : 0;
++ } else
++ return 1;
++ break;
++ case XE3GC:
++ offset = 0x10;
++ retval = omnibook_battery_present(num);
++ if (retval < 0)
++ return retval;
++ if (retval) {
++ if ((retval = omnibook_ec_read16(XE3GC_BDV0 + (offset * num), &(*battinfo).dv)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GC_BDC0 + (offset * num), &(*battinfo).dc)))
++ return retval;
++ if ((retval = omnibook_ec_read(XE3GC_BTY0 + (offset * num), &(*battinfo).type)))
++ return retval;
++
++ (*battinfo).type = ((*battinfo).type & XE3GC_BTY_MASK) ? 1 : 0;
++ (*battinfo).sn = 0; /* Unknown */
++ } else
++ return 1;
++ break;
++ /* FIXME */
++ case OB500:
++ case OB510:
++ switch (num) {
++ case 0:
++ break;
++ case 1:
++ break;
++ case 2:
++ break;
++ default:
++ return -EINVAL;
++ }
++ break;
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ switch (num) {
++ case 0:
++ break;
++ case 1:
++ break;
++ default:
++ return -EINVAL;
++ }
++ break;
++ default:
++ return 2;
++ }
++ return 0;
++}
++
++/*
++ * Get battery status
++ * return values:
++ * < 0 - ERROR
++ * 0 - OK
++ * 1 - Battery is not present
++ * 2 - Not supported
++ */
++int omnibook_get_battery_status(int num, struct omnibook_battery_status *battstat)
++{
++ int retval;
++ u8 status;
++ u16 dc;
++ int gauge;
++ u8 offset;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ offset = 0x10;
++ retval = omnibook_battery_present(num);
++ if (retval < 0)
++ return retval;
++ if (retval) {
++ if ((retval = omnibook_ec_read(XE3GF_BST0 + (offset * num), &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BRC0 + (offset * num), &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BPV0 + (offset * num), &(*battstat).pv)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GF_BFC0 + (offset * num), &(*battstat).lc)))
++ return retval;
++ if ((retval = omnibook_ec_read(XE3GF_GAU0 + (offset * num), &(*battstat).gauge)))
++ return retval;
++
++ if (status & XE3GF_BST_MASK_CRT)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CRITICAL;
++ else if (status & XE3GF_BST_MASK_CHR)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGING;
++ else if (status & XE3GF_BST_MASK_DSC)
++ (*battstat).status = OMNIBOOK_BATTSTAT_DISCHARGING;
++ else if (status & (XE3GF_BST_MASK_CHR | XE3GF_BST_MASK_DSC))
++ (*battstat).status = OMNIBOOK_BATTSTAT_UNKNOWN;
++ else {
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGED;
++ }
++ } else
++ return 1;
++ break;
++ case XE3GC:
++ offset = 0x10;
++ retval = omnibook_battery_present(num);
++ if (retval < 0)
++ return retval;
++ if (retval) {
++ if ((retval = omnibook_ec_read(XE3GC_BST0 + (offset * num), &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GC_BRC0 + (offset * num), &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GC_BPV0 + (offset * num), &(*battstat).pv)))
++ return retval;
++ if ((retval = omnibook_ec_read16(XE3GC_BDC0 + (offset * num), &dc)))
++ return retval;
++
++ if (status & XE3GC_BST_MASK_CRT)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CRITICAL;
++ else if (status & XE3GC_BST_MASK_CHR)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGING;
++ else if (status & XE3GC_BST_MASK_DSC)
++ (*battstat).status = OMNIBOOK_BATTSTAT_DISCHARGING;
++ else if (status & (XE3GC_BST_MASK_CHR | XE3GC_BST_MASK_DSC))
++ (*battstat).status = OMNIBOOK_BATTSTAT_UNKNOWN;
++ else {
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGED;
++ }
++ gauge = ((*battstat).rc * 100) / dc;
++ (*battstat).gauge = gauge;
++ (*battstat).lc = 0; /* Unknown */
++ } else
++ return 1;
++ case OB500:
++ case OB510:
++ switch (num) {
++ case 0:
++ if ((retval = omnibook_ec_read(OB500_BT1S, &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT1C, &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT1V, &(*battstat).pv)))
++ return retval;
++ break;
++ case 1:
++ if ((retval = omnibook_ec_read(OB500_BT2S, &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT2C, &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT2V, &(*battstat).pv)))
++ return retval;
++ break;
++ case 2:
++ if ((retval = omnibook_ec_read(OB500_BT3S, &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT3C, &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT3V, &(*battstat).pv)))
++ return retval;
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (status & OB500_BST_MASK_CRT)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CRITICAL;
++ else if (status & OB500_BST_MASK_CHR)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGING;
++ else if (status & OB500_BST_MASK_DSC)
++ (*battstat).status = OMNIBOOK_BATTSTAT_DISCHARGING;
++ else if (status & (OB500_BST_MASK_CHR | OB500_BST_MASK_DSC))
++ (*battstat).status = OMNIBOOK_BATTSTAT_UNKNOWN;
++ else {
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGED;
++ }
++ break;
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ switch (num) {
++ case 0:
++ if ((retval = omnibook_ec_read(OB500_BT1S, &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT1C, &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT1V, &(*battstat).pv)))
++ return retval;
++ break;
++ case 1:
++ if ((retval = omnibook_ec_read(OB500_BT3S, &status)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT3C, &(*battstat).rc)))
++ return retval;
++ if ((retval = omnibook_ec_read16(OB500_BT3V, &(*battstat).pv)))
++ return retval;
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (status & OB500_BST_MASK_CRT)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CRITICAL;
++ else if (status & OB500_BST_MASK_CHR)
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGING;
++ else if (status & OB500_BST_MASK_DSC)
++ (*battstat).status = OMNIBOOK_BATTSTAT_DISCHARGING;
++ else if (status & (OB500_BST_MASK_CHR | OB500_BST_MASK_DSC))
++ (*battstat).status = OMNIBOOK_BATTSTAT_UNKNOWN;
++ else {
++ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGED;
++ }
++ break;
++ default:
++ return 2;
++ }
++ return 0;
++}
++
++static int omnibook_proc_battery(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *statustr;
++ char *typestr;
++ int max = 0;
++ int num = 0;
++ int retval;
++ char *b = buffer;
++ int i;
++ struct omnibook_battery_info battinfo;
++ struct omnibook_battery_status battstat;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ max = 2;
++ break;
++ case OB500:
++ case OB510:
++ max = 3;
++ break;
++ }
++
++ for (i = 0; i < max; i++) {
++ retval = omnibook_get_battery_info(i, &battinfo);
++ if (retval == 0) {
++ num++;
++ omnibook_get_battery_status(i, &battstat);
++ typestr = (battinfo.type) ? "Li-Ion" : "NiMH";
++ switch (battstat.status) {
++ case OMNIBOOK_BATTSTAT_CHARGED:
++ statustr = "charged";
++ break;
++ case OMNIBOOK_BATTSTAT_DISCHARGING:
++ statustr = "discharging";
++ break;
++ case OMNIBOOK_BATTSTAT_CHARGING:
++ statustr = "charging";
++ break;
++ case OMNIBOOK_BATTSTAT_CRITICAL:
++ statustr = "critical";
++ break;
++ default:
++ statustr = "unknown";
++ }
++
++ b += sprintf(b, "Battery: %11d\n", i);
++ b += sprintf(b, "Type: %11s\n", typestr);
++ if (battinfo.sn)
++ b += sprintf(b, "Serial Number: %11d\n", battinfo.sn);
++ b += sprintf(b, "Present Voltage: %11d mV\n", battstat.pv);
++ b += sprintf(b, "Design Voltage: %11d mV\n", battinfo.dv);
++ b += sprintf(b, "Remaining Capacity: %11d mAh\n", battstat.rc);
++ if (battstat.lc)
++ b += sprintf(b, "Last Full Capacity: %11d mAh\n", battstat.lc);
++ b += sprintf(b, "Design Capacity: %11d mAh\n", battinfo.dc);
++ b += sprintf(b, "Gauge: %11d %%\n", battstat.gauge);
++ b += sprintf(b, "Status: %11s\n", statustr);
++ b += sprintf(b, "\n");
++ }
++ }
++ if (num == 0)
++ b += sprintf(b, "No battery present\n");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++int __init omnibook_battery_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ /* FIXME */
++// case OB500:
++// case OB510:
++// case OB6000:
++// case OB6100:
++// case XE4500:
++ pmode = S_IFREG | S_IRUGO;
++ proc_battery = create_proc_read_entry("battery", pmode, omnibook_proc_root, omnibook_proc_battery, NULL);
++ break;
++ default:
++ printk(KERN_INFO "%s: Battery status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_battery) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/battery.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: Battery status monitoring is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_battery_cleanup(void)
++{
++ if (proc_battery)
++ remove_proc_entry("battery", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_battery_present);
++EXPORT_SYMBOL(omnibook_get_battery_info);
++EXPORT_SYMBOL(omnibook_get_battery_status);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/blank.c linux-2.6.1-gentoo-test/drivers/char/omnibook/blank.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/blank.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/blank.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,208 @@
++/*
++ * blank.c -- blanking lcd console
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_blank;
++int omnibook_console_blank_enabled = 0;
++
++extern int (*console_blank_hook)(int);
++
++/*
++ * Turn LCD display off at console blanking if APM does not do it
++ * (e.g. using ACPI).
++ */
++
++int omnibook_lcd_blank(int blank)
++{
++ int retval = 0;
++#ifdef CONFIG_VT
++ u8 cmd;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ cmd = blank ? OMNIBOOK_KBC_CMD_LCD_OFF : OMNIBOOK_KBC_CMD_LCD_ON;
++ if ((retval = omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, cmd)))
++ return retval;
++ break;
++ case OB500:
++ case OB6000:
++ case XE2:
++ if ((retval = omnibook_io_read(OB500_GPO1, &cmd)))
++ return retval;
++ cmd = blank ? cmd & ~OB500_BKLT_MASK : cmd | OB500_BKLT_MASK;
++ if ((retval = omnibook_io_write(OB500_GPO1, cmd)))
++ return retval;
++ break;
++ case OB510:
++ case OB6100:
++ if ((retval = omnibook_io_read(OB510_GPO2, &cmd)))
++ return retval;
++ cmd = blank ? cmd & ~OB510_BKLT_MASK : cmd | OB510_BKLT_MASK;
++ if ((retval = omnibook_io_write(OB510_GPO2, cmd)))
++ return retval;
++ break;
++ default:
++ printk(KERN_INFO "%s: LCD console blanking is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++#endif
++ return retval;
++}
++
++int omnibook_console_blank_enable(void)
++{
++#ifdef CONFIG_VT
++ if (omnibook_console_blank_enabled == 0) {
++ if (console_blank_hook == NULL) {
++ console_blank_hook = omnibook_lcd_blank;
++ printk(KERN_INFO "%s: LCD display turn off at console blanking enabled.\n", OMNIBOOK_MODULE_NAME);
++ omnibook_console_blank_enabled = 1;
++ } else {
++ printk(KERN_INFO "%s: There is a console blanking solution already registered.\n", OMNIBOOK_MODULE_NAME);
++ }
++ }
++#endif
++ return 0;
++}
++
++int omnibook_console_blank_disable(void)
++{
++#ifdef CONFIG_VT
++ if (console_blank_hook == omnibook_lcd_blank) {
++ console_blank_hook = NULL;
++ printk(KERN_INFO "%s: LCD display turn off at console blanking disabled.\n", OMNIBOOK_MODULE_NAME);
++ omnibook_console_blank_enabled = 0;
++ } else if (console_blank_hook) {
++ printk(KERN_WARNING "%s: You can not disable another console blanking solution.\n", OMNIBOOK_MODULE_NAME);
++ return -EBUSY;
++ } else {
++ printk(KERN_INFO "%s: Console blanking already disabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++#endif
++ return 0;
++}
++
++static int omnibook_console_blank_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "LCD console blanking is %s\n", (omnibook_console_blank_enabled) ? "enabled" : "disabled");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_console_blank_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char status[1] = {'\0'};
++ int retval;
++
++ if ((retval = copy_from_user(status, buffer, 1)))
++ return retval;
++ switch (*status) {
++ case '0':
++ if ((retval = omnibook_console_blank_disable()))
++ return retval;
++ break;
++ case '1':
++ if ((retval = omnibook_console_blank_enable()))
++ return retval;
++ break;
++ default:
++ count = -EINVAL;
++ }
++ return count;
++}
++
++int __init omnibook_console_blank_init(void)
++{
++#ifdef CONFIG_VT
++ mode_t pmode;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE2:
++ if ((retval = omnibook_console_blank_enable()))
++ return retval;
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_blank = create_proc_entry("blank", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: LCD console blanking is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++
++ if (proc_blank) {
++ proc_blank->read_proc = omnibook_console_blank_status;
++ proc_blank->write_proc = omnibook_console_blank_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/blank.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ return 0;
++#else
++ printk(KERN_ERR "%s: Virtual terminal support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++ return -ENODEV;
++#endif
++}
++
++void __exit omnibook_console_blank_cleanup(void)
++{
++#ifdef CONFIG_VT
++ if (proc_blank) {
++ remove_proc_entry("blank", omnibook_proc_root);
++ omnibook_console_blank_disable();
++ }
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_console_blank_enabled);
++EXPORT_SYMBOL(omnibook_lcd_blank);
++EXPORT_SYMBOL(omnibook_console_blank_enable);
++EXPORT_SYMBOL(omnibook_console_blank_disable);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/display.c linux-2.6.1-gentoo-test/drivers/char/omnibook/display.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/display.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/display.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,137 @@
++/*
++ * display.c -- external display related functions
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_display;
++
++int omnibook_get_display(void)
++{
++ int retval = 0;
++#ifdef CONFIG_VT
++ u8 sta;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_STA1, &sta)))
++ return retval;
++ retval = (sta & XE3GF_SHDD_MASK) ? 1 : 0;
++ break;
++ case XE3GC:
++ if ((retval = omnibook_ec_read(XE3GC_STA1, &sta)))
++ return retval;
++ retval = (sta & XE3GC_CRTI_MASK) ? 1 : 0;
++ break;
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ if ((retval = omnibook_ec_read(OB500_STA1, &sta)))
++ return retval;
++ retval = (sta & OB500_CRTS_MASK) ? 1 : 0;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_STA2, &sta)))
++ return retval;
++ retval = (sta & OB4150_CRST_MASK) ? 1 : 0;
++ break;
++ default:
++ printk(KERN_INFO "%s: External display status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++#endif
++ return retval;
++}
++
++static int omnibook_proc_display(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++ int display;
++
++ display = omnibook_get_display();
++ if (display < 0)
++ return display;
++
++ b += sprintf(b, "External display is %s\n", (display) ? "present" : "not present");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++int __init omnibook_display_init(void)
++{
++#ifdef CONFIG_VT
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ case OB4150:
++ pmode = S_IFREG | S_IRUGO;
++ proc_display = create_proc_read_entry("display", pmode, omnibook_proc_root, omnibook_proc_display, NULL);
++ break;
++ default:
++ printk(KERN_INFO "%s: External display status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_display) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/display.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: External display status monitoring is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++#else
++ printk(KERN_ERR "%s: Virtual terminal support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++ return -ENODEV;
++#endif
++}
++
++void __exit omnibook_display_cleanup(void)
++{
++#ifdef CONFIG_VT
++ if (proc_display)
++ remove_proc_entry("display", omnibook_proc_root);
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_get_display);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/dmi.c linux-2.6.1-gentoo-test/drivers/char/omnibook/dmi.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/dmi.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/dmi.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,205 @@
++/*
++ * dmi.c -- to get DMI information
++ *
++ * This code originally came from file arch/i386/kernel/dmi_scan.c from
++ * Linux kernel version 2.4.18
++ *
++ * 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, 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.
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/init.h>
++#include <linux/apm_bios.h>
++#include <linux/slab.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "dmi.h"
++
++struct dmi_header
++{
++ u8 type;
++ u8 length;
++ u16 handle;
++};
++
++static char * __init dmi_string(struct dmi_header *dm, u8 s)
++{
++ u8 *bp=(u8 *)dm;
++ bp+=dm->length;
++ if(!s)
++ return "";
++ s--;
++ while(s>0 && *bp)
++ {
++ bp+=strlen(bp);
++ bp++;
++ s--;
++ }
++ return bp;
++}
++
++/*
++ * We have to be cautious here. We have seen BIOSes with DMI pointers
++ * pointing to completely the wrong place for example
++ */
++
++static int __init dmi_table(u32 base, int len, int num, void (*decode)(struct dmi_header *))
++{
++ u8 *buf;
++ struct dmi_header *dm;
++ u8 *data;
++ int i=0;
++
++ buf = ioremap(base, len);
++ if(buf==NULL)
++ return -1;
++
++ data = buf;
++
++ /*
++ * Stop when we see all the items the table claimed to have
++ * OR we run off the end of the table (also happens)
++ */
++
++ while(i<num && data-buf+sizeof(struct dmi_header)<=len)
++ {
++ dm=(struct dmi_header *)data;
++ /*
++ * We want to know the total length (formated area and strings)
++ * before decoding to make sure we won't run off the table in
++ * dmi_decode or dmi_string
++ */
++ data+=dm->length;
++ while(data-buf<len-1 && (data[0] || data[1]))
++ data++;
++ if(data-buf<len-1)
++ decode(dm);
++ data+=2;
++ i++;
++ }
++ iounmap(buf);
++ return 0;
++}
++
++inline static int __init dmi_checksum(u8 *buf)
++{
++ u8 sum=0;
++ int a;
++
++ for(a=0; a<15; a++)
++ sum+=buf[a];
++ return (sum==0);
++}
++
++static int __init dmi_iterate(void (*decode)(struct dmi_header *))
++{
++ u8 buf[15];
++ u32 fp=0xF0000;
++
++#ifdef CONFIG_SIMNOW
++ /*
++ * Skip on x86/64 with simnow. Will eventually go away
++ * If you see this ifdef in 2.6pre mail me !
++ */
++ return -1;
++#endif
++
++ while( fp < 0xFFFFF)
++ {
++ isa_memcpy_fromio(buf, fp, 15);
++ if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
++ {
++ u16 num=buf[13]<<8|buf[12];
++ u16 len=buf[7]<<8|buf[6];
++ u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
++
++ if(dmi_table(base,len,num,decode)==0)
++ return 0;
++ }
++ fp+=16;
++ }
++ return -1;
++}
++
++char *omnibook_dmi_ident[OMNIBOOK_STRING_MAX];
++
++/*
++ * Save a DMI string
++ */
++
++static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
++{
++ char *d = (char*)dm;
++ char *p = dmi_string(dm, d[string]);
++ if(p==NULL || *p == 0)
++ return;
++ if (omnibook_dmi_ident[slot])
++ return;
++ omnibook_dmi_ident[slot] = kmalloc(strlen(p)+1, GFP_KERNEL);
++ if(omnibook_dmi_ident[slot])
++ strcpy(omnibook_dmi_ident[slot], p);
++ else
++ printk(KERN_ERR "%s: dmi_save_ident: out of memory.\n", OMNIBOOK_MODULE_NAME);
++}
++
++/*
++ * Process a DMI table entry. Right now all we care about are the BIOS
++ * and machine entries. For 2.5 we should pull the smbus controller info
++ * out of here.
++ */
++
++static void __init dmi_decode(struct dmi_header *dm)
++{
++ switch(dm->type)
++ {
++ case 0:
++ dmi_save_ident(dm, OMNIBOOK_BIOS_VENDOR, 4);
++ dmi_save_ident(dm, OMNIBOOK_BIOS_VERSION, 5);
++ dmi_save_ident(dm, OMNIBOOK_BIOS_DATE, 8);
++ break;
++
++ case 1:
++ dmi_save_ident(dm, OMNIBOOK_SYS_VENDOR, 4);
++ dmi_save_ident(dm, OMNIBOOK_PRODUCT_NAME, 5);
++ dmi_save_ident(dm, OMNIBOOK_PRODUCT_VERSION, 6);
++ dmi_save_ident(dm, OMNIBOOK_SERIAL_NUMBER, 7);
++ break;
++ case 2:
++ dmi_save_ident(dm, OMNIBOOK_BOARD_VENDOR, 4);
++ dmi_save_ident(dm, OMNIBOOK_BOARD_NAME, 5);
++ dmi_save_ident(dm, OMNIBOOK_BOARD_VERSION, 6);
++ break;
++ }
++}
++
++int __init omnibook_dmi_scan_machine(void)
++{
++ int err = dmi_iterate(dmi_decode);
++ return err;
++}
++
++EXPORT_SYMBOL(omnibook_dmi_ident);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/dmi.h linux-2.6.1-gentoo-test/drivers/char/omnibook/dmi.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/dmi.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/dmi.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,37 @@
++/*
++ * dmi.h -- code to get DMI information
++ *
++ * This code originally came from file arch/i386/kernel/dmi_scan.c from
++ * Linux kernel version 2.4.18
++ *
++ * 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, 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.
++ */
++
++enum
++{
++ OMNIBOOK_BIOS_VENDOR,
++ OMNIBOOK_BIOS_VERSION,
++ OMNIBOOK_BIOS_DATE,
++ OMNIBOOK_SYS_VENDOR,
++ OMNIBOOK_PRODUCT_NAME,
++ OMNIBOOK_PRODUCT_VERSION,
++ OMNIBOOK_SERIAL_NUMBER,
++ OMNIBOOK_BOARD_VENDOR,
++ OMNIBOOK_BOARD_NAME,
++ OMNIBOOK_BOARD_VERSION,
++ OMNIBOOK_STRING_MAX
++};
++
++extern char *omnibook_dmi_ident[OMNIBOOK_STRING_MAX];
++
++extern int __init omnibook_dmi_scan_machine(void);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/dock.c linux-2.6.1-gentoo-test/drivers/char/omnibook/dock.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/dock.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/dock.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,123 @@
++/*
++ * dock.c -- docking station/port replicator support
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_dock;
++
++int omnibook_get_dock(void)
++{
++ u8 dock;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_CSPR, &dock)))
++ return retval;
++ retval = (dock & XE3GF_CSPR_MASK) ? 1 : 0;
++ break;
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ if ((retval = omnibook_ec_read(OB500_STA1, &dock)))
++ return retval;
++ retval = (dock & OB500_DCKS_MASK) ? 1 : 0;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_DCID, &dock)))
++ return retval;
++ retval = (dock) ? 1 : 0;
++ break;
++ default:
++ printk(KERN_INFO "%s: Docking station handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++static int omnibook_dock_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++ int dock;
++
++ dock = omnibook_get_dock();
++ if (dock < 0)
++ return dock;
++
++ b += sprintf(b, "Laptop is %s\n", (dock) ? "docked" : "undocked");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++int __init omnibook_dock_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case OB4150:
++ pmode = S_IFREG | S_IRUGO;
++ proc_dock = create_proc_read_entry("dock", pmode, omnibook_proc_root, omnibook_dock_status, NULL);
++ break;
++ default:
++ printk(KERN_INFO "%s: Docking station status monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++
++ if (! proc_dock) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/dock.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: Docking station status monitoring is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_dock_cleanup(void)
++{
++ if (proc_dock)
++ remove_proc_entry("dock", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_get_dock);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/ec.c linux-2.6.1-gentoo-test/drivers/char/omnibook/ec.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/ec.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/ec.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,341 @@
++/*
++ * ec.c -- low level functions to access Embedded Conrtroller,
++ * Keyboard Controller and system I/O ports or memory
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/delay.h>
++#include <linux/sched.h>
++
++#ifdef CONFIG_ACPI_EC
++#include <linux/acpi.h>
++#ifdef ACPI_CA_VERSION
++#if ACPI_CA_VERSION > 0x20021121
++#define USE_ACPI_EC
++#endif
++#endif
++#endif
++
++#include <asm/io.h>
++
++#include "ec.h"
++
++/*
++ * Interrupt control
++ */
++
++#ifdef CONFIG_SMP /* Are you ready for SMP laptops? Coming soon... ;) */
++static spinlock_t omnibook_ec_lock = SPIN_LOCK_UNLOCKED;
++#include <linux/spinlock.h>
++#define omnibook_save_flags(x) spin_lock_irqsave(&omnibook_ec_lock, x)
++#define omnibook_restore_flags(x) spin_unlock_irqrestore(&omnibook_ec_lock, x)
++#else
++#include <linux/version.h>
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28))
++#define omnibook_save_flags(x) do { save_flags(x); cli(); } while (0)
++#define omnibook_restore_flags(x) restore_flags(x)
++#else
++#define omnibook_save_flags(x) local_irq_save(x)
++#define omnibook_restore_flags(x) local_irq_restore(x)
++#endif
++#endif /* CONFIG_SMP */
++
++/*
++ * Timeout in ms for sending to controller
++ */
++
++#define OMNIBOOK_TIMEOUT 250
++
++/*
++ * Registers of the embedded controller
++ */
++
++#define OMNIBOOK_EC_DATA 0x62
++#define OMNIBOOK_EC_SC 0x66
++
++/*
++ * Embedded controller status register bits
++ */
++
++#define OMNIBOOK_EC_STAT_OBF 0x01 /* Output buffer full */
++#define OMNIBOOK_EC_STAT_IBF 0x02 /* Input buffer full */
++#define OMNIBOOK_EC_STAT_CMD 0x08 /* Last write was a command write (0=data) */
++
++/*
++ * Embedded controller commands
++ */
++
++#define OMNIBOOK_EC_CMD_READ 0x80
++#define OMNIBOOK_EC_CMD_WRITE 0x81
++#define OMNIBOOK_EC_CMD_QUERY 0x84
++
++/*
++ * Wait for embedded controller buffer
++ */
++
++static int omnibook_ec_wait(u8 event)
++{
++ int timeout = OMNIBOOK_TIMEOUT;
++
++ switch (event) {
++ case OMNIBOOK_EC_STAT_OBF:
++ while (!(inb(OMNIBOOK_EC_SC) & event) && timeout--)
++ mdelay(1);
++ break;
++ case OMNIBOOK_EC_STAT_IBF:
++ while ((inb(OMNIBOOK_EC_SC) & event) && timeout--)
++ mdelay(1);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (timeout>0)
++ return 0;
++ return -ETIME;
++}
++
++/*
++ * Read from the embedded controller
++ */
++
++int omnibook_ec_read(u8 addr, u8 *data)
++{
++ unsigned long flags;
++ int retval;
++
++#ifdef USE_ACPI_EC
++ retval = ec_read(addr, data);
++ if (!retval)
++ return retval;
++#endif
++ omnibook_save_flags(flags);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(OMNIBOOK_EC_CMD_READ, OMNIBOOK_EC_SC);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(addr, OMNIBOOK_EC_DATA);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_OBF);
++ if (retval)
++ goto end;
++ *data = inb(OMNIBOOK_EC_DATA);
++end:
++ omnibook_restore_flags(flags);
++ return retval;
++}
++
++/*
++ * Write to the embedded controller
++ */
++
++int omnibook_ec_write(u8 addr, u8 data)
++{
++
++ unsigned long flags;
++ int retval;
++
++#ifdef USE_ACPI_EC
++ retval = ec_write(addr, data);
++ if (!retval)
++ return retval;
++#endif
++ omnibook_save_flags(flags);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(OMNIBOOK_EC_CMD_WRITE, OMNIBOOK_EC_SC);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(addr, OMNIBOOK_EC_DATA);
++ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(data, OMNIBOOK_EC_DATA);
++end:
++ omnibook_restore_flags(flags);
++ return retval;
++}
++
++int omnibook_ec_read16(u8 addr, u16 *data)
++{
++ int retval;
++ u8 high;
++ u8 low;
++ u16 result;
++
++ retval = omnibook_ec_read(addr, &low);
++ if (retval)
++ return retval;
++ retval = omnibook_ec_read(addr + 0x01, &high);
++ result = ((high << 8) + low);
++ *data = result;
++ return retval;
++}
++
++/*
++ * Registers of the keyboard controller
++ */
++
++#define OMNIBOOK_KBC_DATA 0x60
++#define OMNIBOOK_KBC_SC 0x64
++
++/*
++ * Keyboard controller status register bits
++ */
++
++#define OMNIBOOK_KBC_STAT_OBF 0x01 /* Output buffer full */
++#define OMNIBOOK_KBC_STAT_IBF 0x02 /* Input buffer full */
++#define OMNIBOOK_KBC_STAT_CMD 0x08 /* Last write was a command write (0=data) */
++
++/*
++ * Wait for keyboard buffer
++ */
++
++static int omnibook_kbc_wait(u8 event)
++{
++ int timeout = OMNIBOOK_TIMEOUT;
++
++ switch (event) {
++ case OMNIBOOK_KBC_STAT_OBF:
++ while (!(inb(OMNIBOOK_KBC_SC) & event) && timeout--)
++ mdelay(1);
++ break;
++ case OMNIBOOK_KBC_STAT_IBF:
++ while ((inb(OMNIBOOK_KBC_SC) & event) && timeout--)
++ mdelay(1);
++ break;
++ default:
++ return -EINVAL;
++ }
++ if (timeout>0)
++ return 0;
++ return -ETIME;
++}
++
++/*
++ * Write to the keyboard command register
++ */
++
++static int omnibook_kbc_write_command(u8 cmd)
++{
++ unsigned long flags;
++ int retval;
++
++ omnibook_save_flags(flags);
++ retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
++ if (retval)
++ goto end;
++ outb(cmd, OMNIBOOK_KBC_SC);
++ retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
++end:
++ omnibook_restore_flags(flags);
++ return retval;
++}
++
++/*
++ * Write to the keyboard data register
++ */
++
++static int omnibook_kbc_write_data(u8 data)
++{
++ unsigned long flags;
++ int retval;
++
++ omnibook_save_flags(flags);
++ retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
++ if (retval)
++ goto end;;
++ outb(data, OMNIBOOK_KBC_DATA);
++ retval = omnibook_kbc_wait(OMNIBOOK_KBC_STAT_IBF);
++end:
++ omnibook_restore_flags(flags);
++ return retval;
++}
++
++/*
++ * Send a command to keyboard controller
++ */
++
++int omnibook_kbc_command(u8 cmd, u8 data)
++{
++ int retval;
++
++ retval = omnibook_kbc_write_command(cmd);
++ if (retval)
++ return retval;
++ retval = omnibook_kbc_write_data(data);
++ return retval;
++}
++
++/*
++ * Read a value from a system I/O address
++ */
++
++int omnibook_io_read(u32 addr, u8 *data)
++{
++ unsigned long flags;
++
++ omnibook_save_flags(flags);
++ *data = inb(addr);
++ omnibook_restore_flags(flags);
++ return 0;
++}
++
++/*
++ * Write a value to a system I/O address
++ */
++
++int omnibook_io_write(u32 addr, u8 data)
++{
++ unsigned long flags;
++
++ omnibook_save_flags(flags);
++ outb(data, addr);
++ omnibook_restore_flags(flags);
++ return 0;
++}
++
++/*
++ * Read a value from a system memory address
++ */
++
++int omnibook_mem_read(u32 addr, u8 *data)
++{
++ char *base = ioremap(addr, 1);
++
++ *data = readb(base);
++ iounmap(base);
++ return 0;
++}
++
++/*
++ * Write a value to a system memory address
++ */
++
++int omnibook_mem_write(u32 addr, u8 data)
++{
++ char *base = ioremap(addr, 1);
++
++ writeb(data, base);
++ iounmap(base);
++ return 0;
++}
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/ec.h linux-2.6.1-gentoo-test/drivers/char/omnibook/ec.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/ec.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/ec.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,269 @@
++/*
++ * ec.h -- low level definitions to access Embedded Conrtroller
++ * and Keyboard Controller and system I/O ports or memory
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++extern int omnibook_ec_read(u8 addr, u8 *data);
++extern int omnibook_ec_read16(u8 addr, u16 *data);
++extern int omnibook_ec_write(u8 addr, u8 data);
++extern int omnibook_kbc_command(u8 cmd, u8 data);
++extern int omnibook_io_read(u32 addr, u8 *data);
++extern int omnibook_io_write(u32 addr, u8 data);
++extern int omnibook_mem_read(u32 addr, u8 *data);
++extern int omnibook_mem_write(u32 addr, u8 data);
++
++/*
++ * Embedded controller adresses
++ */
++
++#define XE3GF_CHGM 0x90 /* , 16 bit */
++#define XE3GF_CHGS 0x92 /* , 16 bit */
++#define XE3GF_CHGC 0x94 /* Current charge of board, 16 bit */
++#define XE3GF_CHGV 0x96 /* Current voltage, 16 bit */
++#define XE3GF_CHGA 0x98 /* Current intensity, 16 bit */
++#define XE3GF_BAL 0x9A /* Battery present status */
++#define XE3GF_STA1 0x9C /* Various status bits*/
++#define XE3GF_CSPR 0xA1 /* Port replicator status, 1 bit */
++#define XE3GF_ADP 0xA3 /* AC acapter status, 1 bit */
++#define XE3GF_FOT 0xA5 /* Fan off temperature, 8 bit */
++#define XE3GF_FSD1 0xA6 /* Fan on temperature, 8 bit */
++#define XE3GF_FSD2 0xA7 /* Fan level 2 temperature, 8 bit */
++#define XE3GF_FSD3 0xA8 /* Fan level 3 temperature, 8 bit */
++#define XE3GF_FSD4 0xA9 /* Fan level 4 temperature, 8 bit */
++#define XE3GF_FSD5 0xAA /* Fan level 5 temperature, 8 bit */
++#define XE3GF_FSD6 0xAB /* Fan level 6 temperature, 8 bit */
++#define XE3GF_FSD7 0xAC /* Fan level 7 temperature, 8 bit */
++#define XE3GF_FSRD 0xAD /* Fan status, 8 bit */
++#define XE3GF_CTMP 0xB0 /* CPU tempetature, 8 bit */
++#define XE3GF_BRTS 0xB9 /* LCD brightness, 4 bit */
++#define XE3GF_BTY0 0xC0 /* Battery 0 type, 1 bit */
++#define XE3GF_BST0 0xC1 /* Battery 0 status, 3 bit */
++#define XE3GF_BRC0 0xC2 /* Battery 0 remaining capacity, 16 bit */
++#define XE3GF_BSN0 0xC4 /* Battery 0 serial number 16 bit */
++#define XE3GF_BPV0 0xC6 /* Battery 0 present voltage, 16 bit */
++#define XE3GF_BDV0 0xC8 /* Battery 0 design voltage 16 bit */
++#define XE3GF_BDC0 0xCA /* Battery 0 design capacity 16 bit */
++#define XE3GF_BFC0 0xCC /* Battery 0 last full capacity 16 bit */
++#define XE3GF_GAU0 0xCE /* Battery 0 gauge, 8 bit */
++#define XE3GF_BTY1 0xD0 /* Battery 1 type, 1 bit */
++#define XE3GF_BST1 0xD1 /* Battery 1 status, 3 bit */
++#define XE3GF_BRC1 0xD2 /* Battery 1 remaining capacity, 16 bit */
++#define XE3GF_BSN1 0xD4 /* Battery 1 serial number, 16 bit */
++#define XE3GF_BPV1 0xD6 /* Battery 1 present voltage, 16 bit */
++#define XE3GF_BDV1 0xD8 /* Battery 1 design voltage 16 bit */
++#define XE3GF_BDC1 0xDA /* Battery 1 design capacity 16 bit */
++#define XE3GF_BFC1 0xDC /* Battery 1 last full capacity 16 bit */
++#define XE3GF_GAU1 0xDE /* Battery 1 gauge, 8 bit */
++
++/*
++ * Bitmasks for sub byte values
++ */
++
++#define XE3GF_SHDD_MASK 0x40 /* External display status */
++#define XE3GF_CSPR_MASK 0x01 /* Port replicator status */
++#define XE3GF_ADP_MASK 0x20 /* AC acapter status */
++#define XE3GF_BAL0_MASK 0x01 /* Battery 0 present */
++#define XE3GF_BAL1_MASK 0x02 /* Battery 1 present */
++#define XE3GF_BMF_MASK 0x70 /* Model code */
++#define XE3GF_BTY_MASK 0x80 /* Type: Ni-MH or Li-Ion */
++#define XE3GF_BST_MASK_DSC 0x01 /* Discarging */
++#define XE3GF_BST_MASK_CHR 0x02 /* Charging */
++#define XE3GF_BST_MASK_CRT 0x04 /* Critical */
++#define XE3GF_FSRD_MASK_S1 0x01 /* Fan level 1 */
++#define XE3GF_FSRD_MASK_S2 0x02 /* Fan level 2 */
++#define XE3GF_FSRD_MASK_S3 0x04 /* Fan level 3 */
++#define XE3GF_FSRD_MASK_S4 0x08 /* Fan level 4 */
++#define XE3GF_FSRD_MASK_S5 0x10 /* Fan level 5 */
++#define XE3GF_FSRD_MASK_S6 0x20 /* Fan level 6 */
++#define XE3GF_FSRD_MASK_S7 0x40 /* Fan level 7 */
++#define XE3GF_BRTS_MASK 0x0F /* LCD brightness */
++
++#define XE3GF_FAN_ON_MASK 0x02 /* Fan on */
++
++/*
++ * OmniBook XE3 GC values
++ */
++
++#define XE3GC_CTMP 0x28 /* CPU tempetature, 8 bit */
++#define XE3GC_STA1 0x30 /* Various status bits */
++#define XE3GC_Q0A 0x31 /* Various status bits */
++#define XE3GC_CCUR 0x38 /* Current charge of board, 16 bit ? */
++#define XE3GC_CVOL 0x3A /* Current voltage, 16 bit ? */
++#define XE3GC_CARM 0x3C /* Current intensity, 16 bit ? */
++#define XE3GC_BAT 0x3E /* Battery present status */
++#define XE3GC_BST0 0x40 /* Battery 0 status, 3 bit */
++#define XE3GC_BPR0 0x41 /* Battery 0 present rate, 16 bit ? */
++#define XE3GC_BRC0 0x43 /* Battery 0 remaining capacity, 16 bit */
++#define XE3GC_BPV0 0x45 /* Battery 0 present voltage, 16 bit */
++#define XE3GC_BDV0 0x47 /* Battery 0 design voltage 16 bit */
++#define XE3GC_BDC0 0x49 /* Battery 0 design capacity 16 bit */
++#define XE3GC_BTY0 0x4A /* Battery 0 type, 1 bit ?*/
++#define XE3GC_BTP0 0x4B /* Battery 0 ?, 1 bit */
++#define XE3GC_BSN0 0x4C /* Battery 0 serial number, 8 bit ?*/
++#define XE3GC_BMF0 0x4D /* Battery 0 ?,8 bit */
++#define XE3GC_BST1 0x50 /* Battery 0 status, 3 bit */
++#define XE3GC_BPR1 0x51 /* Battery 0 present rate, 16 bit ? */
++#define XE3GC_BRC1 0x53 /* Battery 0 remaining capacity, 16 bit */
++#define XE3GC_BPV1 0x55 /* Battery 0 present voltage, 16 bit */
++#define XE3GC_BDV1 0x57 /* Battery 0 design voltage 16 bit */
++#define XE3GC_BDC1 0x59 /* Battery 0 design capacity 16 bit */
++#define XE3GC_BTY1 0x5A /* Battery 0 type, 1 bit ?*/
++#define XE3GC_BTP1 0x5B /* Battery 0 ?, 1 bit */
++#define XE3GC_BSN1 0x5C /* Battery 0 serial number, 8 bit ?*/
++#define XE3GC_BMF1 0x5D /* Battery 0 ?,8 bit */
++#define XE3GC_STA2 0x61 /* Various status bits */
++#define XE3GC_BTVL 0x6A /* LCD brightness, 4 bit */
++
++/*
++ * Bitmasks for sub byte values
++ */
++
++#define XE3GC_ADP_MASK 0x40 /* AC acapter status */
++#define XE3GC_BAT0_MASK 0x01 /* Battery 0 present */
++#define XE3GC_BAT1_MASK 0x02 /* Battery 1 present */
++#define XE3GC_BTY_MASK 0x01 /* Type: Ni-MH or Li-Ion */
++#define XE3GC_BST_MASK_DSC 0x01 /* Discarging */
++#define XE3GC_BST_MASK_CHR 0x02 /* Charging */
++#define XE3GC_BST_MASK_CRT 0x04 /* Critical */
++#define XE3GC_CRTI_MASK 0x04 /* External display status */
++#define XE3GC_SLPB_MASK 0x01 /* Sleep button pressed */
++#define XE3GC_F5_MASK 0x02 /* Fn-F5 - LCD/CRT switch pressed */
++#define XE3GC_VOLD_MASK 0x04 /* Fn-down arrow or Volume down pressed */
++#define XE3GC_VOLU_MASK 0x08 /* Fn-up arrow or Volume up pressed */
++#define XE3GC_MUTE_MASK 0x10 /* Fn+F7 - Volume mute pressed */
++#define XE3GC_CNTR_MASK 0x20 /* Fn+F3/Fn+F4 - Contrast up or down pressed */
++#define XE3GC_BRGT_MASK 0x40 /* Fn+F1/Fn+F2 - Brightness up or down pressed */
++#define XE3GC_BTVL_MASK 0x0F /* LCD brightness */
++
++/*
++ * Emulated scancodes
++ */
++
++#define XE3GC_VOLD_SCAN 0x2E /* Volume down button scancode */
++#define XE3GC_VOLU_SCAN 0x30 /* Volume up button scancode */
++#define XE3GC_MUTE_SCAN 0x20 /* Volume up button scancode */
++
++/*
++ * OmniBook 500, 510, 6000, 6100, XE2 values
++ */
++
++#define OB500_STA1 0x44 /* Various status bits */
++#define OB500_STA2 0x50 /* Various status bits */
++#define OB500_CTMP 0x55 /* CPU tempetature, 8 bit */
++#define OB500_BT1I 0x58 /* Battery 1 ? 16 bit */
++#define OB500_BT1C 0x5A /* Battery 1 remaining capacity 16 bit ? */
++#define OB500_BT1V 0x5C /* Battery 1 present voltage 16 bit ? */
++#define OB500_BT1S 0x5E /* Battery 1 status 3 bit ? */
++#define OB500_BT2I 0x6A /* Battery 2 ? 16 bit */
++#define OB500_BT2C 0x6C /* Battery 2 remaining capacity 16 bit ? */
++#define OB500_BT2V 0x6E /* Battery 2 present voltage 16 bit ? */
++#define OB500_BT2S 0x70 /* Battery 2 status 3 bit ? */
++#define OB500_BT3I 0x5F /* Battery 3 ? 16 bit */
++#define OB500_BT3C 0x61 /* Battery 3 remaining capacity 16 bit ? */
++#define OB500_BT3V 0x63 /* Battery 3 present voltage 16 bit ? */
++#define OB500_BT3S 0x65 /* Battery 3 status 3 bit ? */
++
++#define OB6000_STA1 0x77 /* Various status bits */
++
++#define XE2_STA1 0x50 /* Various status bits */
++
++/*
++ * Bitmasks for sub byte values
++ */
++
++#define OB500_LIDS_MASK 0x01 /* LID status */
++#define OB500_CRTS_MASK 0x20 /* External display status */
++#define OB500_SLPS_MASK 0x40 /* Sleep button status */
++#define OB500_DCKS_MASK 0x80 /* Docking status */
++#define OB500_ADP_MASK 0x02 /* AC acapter status */
++#define OB500_BST_MASK_DSC 0x01 /* Discarging */
++#define OB500_BST_MASK_CHR 0x02 /* Charging */
++#define OB500_BST_MASK_CRT 0x04 /* Critical */
++
++#define OB6000_FAN_MASK 0x10 /* Fan status */
++
++#define XE2_ADP_MASK 0x02 /* AC acapter status */
++
++/*
++ * OmniBook 4150
++ */
++
++#define OB4150_TMP 0x28 /* CPU tempetature, 8 bit */
++#define OB4150_STA1 0x2E /* Various status bits */
++#define OB4150_STA2 0x2F /* Various status bits */
++#define OB4150_ADP 0x30 /* AC acapter status, 1 bit */
++#define OB4150_DCID 0x2C /* Port replicator */
++
++/*
++ * Bitmasks for sub byte values
++ */
++
++#define OB4150_FAN_MASK 0x01 /* Fan status */
++#define OB4150_ADP_MASK 0x40 /* AC acapter status */
++#define OB4150_CRST_MASK 0x20 /* External display status */
++
++/*
++ * Keyboard controller command for some laptop functions
++ */
++
++#define OMNIBOOK_KBC_CONTROL_CMD 0x59
++
++/*
++ * Keyboard controller command parameters for functions available via kbc
++ */
++
++#define OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE 0x90 /* Enables OneTouch buttons */
++#define OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE 0x91 /* Disables OneTouch buttons */
++#define OMNIBOOK_KBC_CMD_TOUCHPAD_ENABLE 0xAA /* Enables toucpad */
++#define OMNIBOOK_KBC_CMD_TOUCHPAD_DISABLE 0xA9 /* Disables toucpad */
++#define OMNIBOOK_KBC_CMD_LCD_ON 0xE1 /* Turns LCD display on */
++#define OMNIBOOK_KBC_CMD_LCD_OFF 0xE2 /* Turns LCD display off */
++#define OMNIBOOK_KBC_CMD_AC_POWER_ENABLE 0xC2 /* Enable AC power */
++#define OMNIBOOK_KBC_CMD_AC_POWER_DISABLE 0xC1 /* Disable AC power */
++
++/*
++ * Other I/O ports
++ */
++
++#define ACL00_AC_STAT 0x11B9 /* AC adapter status on ACL00 */
++#define ACL00_AC_MASK 0x04 /* Bitmask for AC adapter status on ACL00 */
++#define TOSH3K_AC_STAT 0x102D /* AC adapter status on Toshiba 3000 */
++#define TOSH3K_AC_MASK 0x08 /* Bitmask for AC adapter status on Toshiba 3000 */
++#define XE3GF_AC_STAT 0x11B9 /* AC adapter status on XE3 GF */
++#define XE3GF_AC_MASK 0x04 /* Bitmask for AC adapter status on XE3 GF */
++#define XE3GF_LID_STAT 0x11AD /* LID switch status on XE3 GF */
++#define XE3GF_LID_MASK 0x20 /* Bitmask for LID switch status on XE3 GF */
++#define XE3GC_SMIC 0xFE00
++
++#define OB500_GPO1 0x8034 /* Fan control */
++#define OB510_GPO2 0x11B9 /* LCD backlight */
++#define OB510_GPIO 0x118F /* Fan control */
++
++#define OB500_FAN_ON_MASK 0x0A /* Turn fan on with zero bits */
++#define OB500_FAN_OFF_MASK 0x08 /* Fan status/off */
++#define OB500_BKLT_MASK 0x40 /* LCD backlight */
++#define OB510_FAN_ON_MASK 0x18 /* Turn fan on with zero bits */
++#define OB510_FAN_OFF_MASK 0x10 /* Turn fan on */
++#define OB510_BKLT_MASK 0x01 /* LCD backlight */
++
++#define XE2_FAN_MASK 0x02 /* Turn fan on with zero bit */
++
++/*
++ * Memory adresses
++ */
++
++#define XE3GC_BCMD 0xFFFFEBC
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/fan.c linux-2.6.1-gentoo-test/drivers/char/omnibook/fan.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/fan.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/fan.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,290 @@
++/*
++ * fan.c -- fan status/control
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_fan;
++
++int omnibook_get_fan(void)
++{
++ u8 fan;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_FSRD, &fan)))
++ return retval;
++ retval = fan;
++ break;
++ case OB500:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ retval = (fan & OB500_FAN_OFF_MASK) ? 0 : 1;
++ break;
++ case OB510:
++ if ((retval = omnibook_io_read(OB510_GPIO, &fan)))
++ return retval;
++ retval = (fan & OB510_FAN_OFF_MASK) ? 0 : 1;
++ break;
++ case OB6000:
++ case OB6100:
++ if ((retval = omnibook_ec_read(OB6000_STA1, &fan)))
++ return retval;
++ retval = (fan & OB6000_FAN_MASK) ? 1 : 0;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_STA1, &fan)))
++ return retval;
++ retval = (fan & OB4150_FAN_MASK) ? 1 : 0;
++ break;
++ case XE2:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ retval = (fan & XE2_FAN_MASK) ? 0 : 1;
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan status monitoring is unsupported on this machie.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++int omnibook_fan_on(void)
++{
++ u8 fan;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_FSRD, &fan)))
++ return retval;
++ if ((retval = omnibook_ec_write(XE3GF_FSRD, fan | XE3GF_FAN_ON_MASK)))
++ return retval;
++ break;
++ case OB500:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB500_GPO1, fan & ~OB500_FAN_ON_MASK)))
++ return retval;
++ break;
++ case OB510:
++ if ((retval = omnibook_io_read(OB510_GPIO, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB510_GPIO, fan & ~OB510_FAN_ON_MASK)))
++ return retval;
++ break;
++ case OB6000:
++ case OB6100:
++ if ((retval = omnibook_ec_read(OB6000_STA1, &fan)))
++ return retval;
++ if ((retval = omnibook_ec_write(OB6000_STA1, fan | OB6000_FAN_MASK)))
++ return retval;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_STA1, &fan)))
++ return retval;
++ if ((retval = omnibook_ec_write(OB4150_STA1, fan | OB4150_FAN_MASK)))
++ return retval;
++ break;
++ case XE2:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB500_GPO1, fan & ~XE2_FAN_MASK)))
++ return retval;
++ break;
++ default:
++ printk(KERN_INFO "%s: Direct fan control is unsupported on this machie.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++int omnibook_fan_off(void)
++{
++ u8 fan;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ {
++ u8 fot, temp;
++ if ((retval = omnibook_ec_read(XE3GF_FSRD, &fan)))
++ return retval;
++
++ /* fan is already off */
++ if (!fan)
++ return 0;
++
++ /* now we set FOT to current temp, then reset to initial value */
++ if ((retval = omnibook_ec_read(XE3GF_FOT, &fot)))
++ return retval;
++ if ((retval = omnibook_ec_read(XE3GF_CTMP, &temp)))
++ return retval;
++
++ do {
++ omnibook_ec_write(XE3GF_FOT, temp);
++ mdelay(1);
++ } while (omnibook_get_fan() != 0);
++
++ omnibook_ec_write(XE3GF_FOT, fot);
++ }
++ break;
++ case OB500:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB500_GPO1, fan | OB500_FAN_OFF_MASK)))
++ return retval;
++ break;
++ case OB510:
++ if ((retval = omnibook_io_read(OB510_GPIO, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB510_GPIO, fan | OB510_FAN_OFF_MASK)))
++ return retval;
++ break;
++ case OB6000:
++ case OB6100:
++ if ((retval = omnibook_ec_read(OB6000_STA1, &fan)))
++ return retval;
++ if ((retval = omnibook_ec_write(OB6000_STA1, fan & ~OB6000_FAN_MASK)))
++ return retval;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_STA1, &fan)))
++ return retval;
++ if ((retval = omnibook_ec_write(OB4150_STA1, fan & ~OB4150_FAN_MASK)))
++ return retval;
++ break;
++ case XE2:
++ if ((retval = omnibook_io_read(OB500_GPO1, &fan)))
++ return retval;
++ if ((retval = omnibook_io_write(OB500_GPO1, fan | XE2_FAN_MASK)))
++ return retval;
++ break;
++ default:
++ printk(KERN_INFO "%s: Direct fan control is unsupported on this machie.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++static int omnibook_fan_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ int fan;
++ char *b = buffer;
++ char *str;
++
++ fan = omnibook_get_fan();
++ if (fan < 0)
++ return fan;
++ str = (fan) ? "on" : "off";
++
++ if (fan > 1)
++ b += sprintf(b, "Fan is %s (level %d)\n", str, fan);
++ else
++ b += sprintf(b, "Fan is %s\n", str);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);;
++}
++
++static int omnibook_fan_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char status[1] = {'\0'};
++
++ if (copy_from_user(status, buffer, 1))
++ return -EFAULT;
++ switch (*status) {
++ case '0':
++ omnibook_fan_off();
++ break;
++ case '1':
++ omnibook_fan_on();
++ break;
++ default:
++ count = -EINVAL;
++ }
++
++ return count;
++}
++
++int __init omnibook_fan_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case OB4150:
++ case XE2:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_fan = create_proc_entry("fan", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan status monitor and control is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++
++ if (proc_fan) {
++ proc_fan->read_proc = omnibook_fan_status;
++ proc_fan->write_proc = omnibook_fan_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/fan.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: Fan status monitor and control is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_fan_cleanup(void)
++{
++ if (proc_fan)
++ remove_proc_entry("fan", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_get_fan);
++EXPORT_SYMBOL(omnibook_fan_on);
++EXPORT_SYMBOL(omnibook_fan_off);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/fan_policy.c linux-2.6.1-gentoo-test/drivers/char/omnibook/fan_policy.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/fan_policy.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/fan_policy.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,227 @@
++/*
++ * fan_policy.c -- fan policy support
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_fan_policy;
++
++u8 omnibook_fan_policy[OMNIBOOK_FAN_LEVELS];
++
++int omnibook_get_fan_policy(void)
++{
++ int retval = 0;
++ int i;
++ u8 tmp;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
++ if ((retval = omnibook_ec_read(XE3GF_FOT + i, &tmp)))
++ return retval;
++ omnibook_fan_policy[i] = tmp;
++ }
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan policy is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++int omnibook_set_fan_policy(void)
++{
++ int retval;
++ int i;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if (omnibook_fan_policy[0] > OMNIBOOK_FOT_MAX)
++ return -EINVAL;
++ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
++ if ((omnibook_fan_policy[i] > omnibook_fan_policy[i + 1]) || (omnibook_fan_policy[i] < OMNIBOOK_FAN_MIN) || (omnibook_fan_policy[i] > OMNIBOOK_FAN_MAX))
++ return -EINVAL;
++ if (omnibook_fan_policy[i + 1] > OMNIBOOK_FAN_MAX)
++ return -EINVAL;
++ }
++ for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
++ if ((retval = omnibook_ec_write(XE3GF_FOT + i, omnibook_fan_policy[i])))
++ return retval;
++ }
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan policy is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++int omnibook_set_fan_policy_defaults(void)
++{
++ int retval;
++ int i;
++ u8 fan_defaults[] = {
++ OMNIBOOK_FOT_DEFAULT,
++ OMNIBOOK_FAN1_DEFAULT,
++ OMNIBOOK_FAN2_DEFAULT,
++ OMNIBOOK_FAN3_DEFAULT,
++ OMNIBOOK_FAN4_DEFAULT,
++ OMNIBOOK_FAN5_DEFAULT,
++ OMNIBOOK_FAN6_DEFAULT,
++ OMNIBOOK_FAN7_DEFAULT,
++ };
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ for (i = 0; i <= OMNIBOOK_FAN_LEVELS; i++) {
++ if ((retval = omnibook_ec_write(XE3GF_FOT + i, fan_defaults[i])))
++ return retval;
++ }
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan policy is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++ return retval;
++}
++
++static int omnibook_proc_fan_policy_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ int retval;
++ char *b = buffer;
++ u8 i;
++
++ if ((retval = omnibook_get_fan_policy()))
++ return retval;
++
++ b += sprintf(b, "Fan off temperature: %2d C\n", omnibook_fan_policy[0]);
++ b += sprintf(b, "Fan on temperature: %2d C\n", omnibook_fan_policy[1]);
++ for (i = 2; i <= OMNIBOOK_FAN_LEVELS; i++) {
++ b += sprintf(b, "Fan level %1d temperature: %2d C\n", i, omnibook_fan_policy[i]);
++ }
++ b += sprintf(b, "Minimal temperature to set: %2d C\n", OMNIBOOK_FAN_MIN);
++ b += sprintf(b, "Maximal temperature to set: %2d C\n", OMNIBOOK_FAN_MAX);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_proc_fan_policy_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ unsigned int len = (count < OMNIBOOK_FAN_POLICY_STRING) ? count : OMNIBOOK_FAN_POLICY_STRING;
++ char status[OMNIBOOK_FAN_POLICY_STRING] = {'\0'};
++ char *b;
++ char *prev;
++ u8 n;
++ u8 c;
++ int retval;
++
++ if ((retval = omnibook_get_fan_policy()))
++ return retval;
++
++ if (copy_from_user(status, buffer, len))
++ return -EFAULT;
++ status[len] = 0;
++ b = status;
++ n = 0;
++ c = 0;
++ prev = NULL;
++ do {
++ printk(KERN_INFO "%s: c=%d\n", OMNIBOOK_MODULE_NAME, c);
++ if (n > OMNIBOOK_FAN_LEVELS)
++ return -EINVAL;
++ if (*b >= '0' && *b <= '9')
++ c = c * 10 + (*b - '0');
++ else if (((*b == ' ') || (*b == '\0') || (*b == '\n')) && (*prev >= '0') && (*prev <= '9')) {
++ omnibook_fan_policy[n] = c;
++ n++;
++ c = 0;
++ } else {
++ return -EINVAL;
++ }
++ prev = b;
++ b++;
++ } while ((*prev != '\n') && (*prev != '\0'));
++
++ /* A zero value set the defaults */
++ if ((omnibook_fan_policy[0] == 0) && (n == 1)) {
++ if ((retval = omnibook_set_fan_policy_defaults()))
++ return retval;
++ } else
++ omnibook_set_fan_policy();
++
++ return count;
++}
++
++int __init omnibook_fan_policy_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_fan_policy = create_proc_entry("fan_policy", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: Fan policy is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (proc_fan_policy) {
++ proc_fan_policy->read_proc = omnibook_proc_fan_policy_status;
++ proc_fan_policy->write_proc = omnibook_proc_fan_policy_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/fan_policy.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: Fan policy setting is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_fan_policy_cleanup(void)
++{
++ if (proc_fan_policy)
++ remove_proc_entry("fan_policy", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_fan_policy);
++EXPORT_SYMBOL(omnibook_get_fan_policy);
++EXPORT_SYMBOL(omnibook_set_fan_policy);
++EXPORT_SYMBOL(omnibook_set_fan_policy_defaults);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/init.c linux-2.6.1-gentoo-test/drivers/char/omnibook/init.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/init.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/init.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,492 @@
++/*
++ * init.c -- module initialization code
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "dmi.h"
++#include "init.h"
++#include "util.h"
++
++int omnibook_ectype;
++int omnibook_userset;
++
++struct proc_dir_entry *omnibook_proc_root __initdata = NULL;
++static struct proc_dir_entry *proc_version;
++static struct proc_dir_entry *proc_dmi;
++
++/*
++ * Module parameters
++ * 0 disables the feature
++ * >1 enables the feature
++ * All feature enabled by default
++ */
++
++static int ectype __initdata = NONE;
++static int ac __initdata = 1;
++static int battery __initdata = 1;
++static int blank __initdata = 1;
++static int display __initdata = 1;
++static int dmi __initdata = 1;
++static int fan __initdata = 1;
++static int fan_policy __initdata = 1;
++static int onetouch __initdata = 1;
++static int lcd __initdata = 1;
++static int temperature __initdata = 1;
++static int touchpad __initdata = 1;
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++static int key_polling __initdata = 1;
++#endif
++
++static int apmemu __initdata = 0;
++static int dock __initdata = 0;
++static int user __initdata = 0;
++
++static int omnibook_proc_version(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "%s\n", OMNIBOOK_MODULE_VERSION);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_proc_dmi(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "BIOS Vendor: %s\n", omnibook_dmi_ident[OMNIBOOK_BIOS_VENDOR]);
++ b += sprintf(b, "BIOS Version: %s\n", omnibook_dmi_ident[OMNIBOOK_BIOS_VERSION]);
++ b += sprintf(b, "BIOS Release: %s\n", omnibook_dmi_ident[OMNIBOOK_BIOS_DATE]);
++ b += sprintf(b, "System Vendor: %s\n", omnibook_dmi_ident[OMNIBOOK_SYS_VENDOR]);
++ b += sprintf(b, "Product Name: %s\n", omnibook_dmi_ident[OMNIBOOK_PRODUCT_NAME]);
++ b += sprintf(b, "Version: %s\n", omnibook_dmi_ident[OMNIBOOK_PRODUCT_VERSION]);
++ b += sprintf(b, "Serial Number: %s\n", omnibook_dmi_ident[OMNIBOOK_SERIAL_NUMBER]);
++ b += sprintf(b, "Board Vendor: %s\n", omnibook_dmi_ident[OMNIBOOK_BOARD_VENDOR]);
++ b += sprintf(b, "Board Name: %s\n", omnibook_dmi_ident[OMNIBOOK_BOARD_NAME]);
++ b += sprintf(b, "Board Version: %s\n", omnibook_dmi_ident[OMNIBOOK_BOARD_VERSION]);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++#define HP_SIGNATURE "Hewlett-Packard"
++
++struct omnibook_models_t {
++ /* DMI field matchers (table inputs) */
++ char *sys_vendor;
++ char *product_name;
++ char *product_version;
++ char *board_name;
++
++ /* Table outputs */
++ char *syslog_name; /* Name which will appear in the syslog */
++ int ectype; /* Type of the embedded controller firmware, see omnibook.h and README */
++};
++
++static struct omnibook_models_t omnibook_models[] __initdata = {
++ /* sys_vendor product_name product_version board_name syslog_name ectype */
++ { NULL, "HP OmniBook PC*", "HP OmniBook XE3 GF*", NULL, NULL, XE3GF },
++ { NULL, "HP OmniBook PC*", "HP OmniBook XT1000*", NULL, NULL, XE3GF },
++ { NULL, "HP OmniBook PC*", "HP OmniBook XE2 DC*", NULL, NULL, XE2 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook XE3 GC*", NULL, NULL, XE3GC },
++ /* HP Pavilion N5430 */
++ { NULL, "HP OmniBook PC*", "HP OmniBook XE3 GD*", NULL, NULL, XE3GC },
++ /* HP Pavilion N5415 */
++ { NULL, "HP OmniBook PC*", "HP OmniBook XE3 GE*", NULL, NULL, XE3GC },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 500 FA*", NULL, NULL, OB500 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 510 FB*", NULL, NULL, OB510 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 4150*", NULL, NULL, OB4150 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 900 B*", NULL, NULL, OB4150 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 6000 EA*", NULL, NULL, OB6000 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook 6100 EB*", NULL, NULL, OB6100 },
++ /* HP OmniBook xe4100 */
++ { NULL, "HP OmniBook PC*", "HP OmniBook xe4000*", NULL, NULL, XE4500 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook xe4400*", NULL, NULL, XE4500 },
++ { NULL, "HP OmniBook PC*", "HP OmniBook xe4500*", NULL, NULL, XE4500 },
++ /* HP OmniBook vt6200 and xt6200 */
++ { NULL, "HP OmniBook PC*", "HP OmniBook 6200 EG*", NULL, NULL, XE4500 },
++ /* HP Pavilion ze4125 */
++ { NULL, "HP NoteBook PC*", "HP NoteBook ze4000*", NULL, NULL, XE4500 },
++ /* There are no model specific strings of some HP Pavilion xt155 and some HP Pavilion ze4100 */
++ { NULL, "HP NoteBook PC*", "HP NoteBook PC*", NULL, NULL, XE4500 },
++ /* HP Pavilion ZU1155 and ZU1175 */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion ZU1000 FA*", NULL, NULL, OB500 },
++ /* HP Pavilion N5290 */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion Notebook XE3 GC*", NULL, NULL, XE3GC },
++ /* HP Pavilion N5441 */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion Notebook Model GD*", NULL, NULL, XE3GC },
++ /* HP Pavilion XH545 */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion Notebook Model GE*", NULL, NULL, XE3GC },
++ /* HP Pavilion ZT1141 */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion Notebook ZT1000*", NULL, NULL, XE3GF },
++ /* There are no model specific strings of some HP Pavilion ZT1175 and ZT1195 notebooks */
++ { NULL, "HP Pavilion Notebook PC*", "HP Pavilion Notebook*", NULL, NULL, XE3GF },
++ { NULL, "Pavilion ze4200*", NULL, NULL, "HP Pavilion ze4200 series", XE4500 },
++ /* Compaq nx9000 */
++ { NULL, "HP nx9000*", NULL, NULL, "HP/Compaq nx9000", XE4500 },
++ /* Compaq nx9005 */
++ { NULL, "HP nx9005*", NULL, NULL, "HP/Compaq nx9005", XE4500 },
++ /* Compaq nx9010 */
++ { NULL, "HP nx9010*", NULL, NULL, "HP/Compaq nx9010", XE4500 },
++ { "TOSHIBA", "S1000*", NULL, NULL, "Toshiba Satellite 1000", XE3GF },
++ { "TOSHIBA", "S1005*", NULL, NULL, "Toshiba Satellite 1005", XE3GF },
++ { "TOSHIBA", "S1110*", NULL, NULL, "Toshiba Satellite 1110", XE3GF },
++ { "TOSHIBA", "S1115*", NULL, NULL, "Toshiba Satellite 1115", XE3GF },
++ { "TOSHIBA", "S1900*", NULL, NULL, "Toshiba Satellite 1900", XE3GF },
++ { "TOSHIBA", "S1905*", NULL, NULL, "Toshiba Satellite 1905", XE3GF },
++ { "TOSHIBA", "S1950*", NULL, NULL, "Toshiba Satellite 1950", XE3GF },
++ { "TOSHIBA", "S2430*", NULL, NULL, "Toshiba Satellite 2430", XE3GF },
++ { "TOSHIBA", "S3000*", NULL, NULL, "Toshiba Satellite 3000", XE3GF },
++ { "TOSHIBA", "S3005*", NULL, NULL, "Toshiba Satellite 3005", XE3GF },
++ { "TOSHIBA", "Satellite 1000*", NULL, NULL, "Toshiba Satellite 1000", XE3GF },
++ { "TOSHIBA", "Satellite 1005*", NULL, NULL, "Toshiba Satellite 1005", XE3GF },
++ { "TOSHIBA", "Satellite 1110*", NULL, NULL, "Toshiba Satellite 1110", XE3GF },
++ { "TOSHIBA", "Satellite 1115*", NULL, NULL, "Toshiba Satellite 1115", XE3GF },
++ { "TOSHIBA", "Satellite 1900*", NULL, NULL, "Toshiba Satellite 1900", XE3GF },
++ { "TOSHIBA", "Satellite 1905*", NULL, NULL, "Toshiba Satellite 1905", XE3GF },
++ { "TOSHIBA", "Satellite 1950*", NULL, NULL, "Toshiba Satellite 1950", XE3GF },
++ { "TOSHIBA", "Satellite 2430*", NULL, NULL, "Toshiba Satellite 2430", XE3GF },
++ { "TOSHIBA", "Satellite 3000*", NULL, NULL, "Toshiba Satellite 3000", XE3GF },
++ { "TOSHIBA", "Satellite 3005*", NULL, NULL, "Toshiba Satellite 3005", XE3GF },
++ { "COMPAL", NULL, NULL, "ACL00", "Compal ACL00", XE3GF },
++ { "Acer", "Aspire 1400 series*", NULL, NULL, "Acer Aspire 1400 series", XE3GF },
++ /* This sentinel at the end catches all unsupported models */
++ { NULL, NULL, NULL, NULL, NONE }
++};
++
++struct omnibook_tc_t {
++ char *tc;
++ int ectype;
++};
++
++/* HP technology codes */
++static struct omnibook_tc_t omnibook_tc[] __initdata = {
++ /* technology code ectype */
++ { "CI.", OB4150 },
++ { "CL.", OB4150 },
++ { "DC.", XE2 },
++ { "EA.", OB6000 },
++ { "EB.", OB6100 },
++ { "EG.", XE4500 },
++ { "FA.", OB500 },
++ { "FB.", OB510 },
++ { "GC.", XE3GC },
++ { "GD.", XE3GC },
++ { "GE.", XE3GC },
++ { "GF.", XE3GF },
++ { "IB.", XE3GF },
++ { "IC.", XE3GF },
++ { "ID.", XE3GF },
++ { "KA.", XE4500 },
++ { "KB.", XE4500 },
++ { "KC.", XE4500 },
++ { "KD.", XE4500 },
++ { "KE.", XE4500 },
++ { NULL, NONE }
++};
++
++/*
++ * Compare the saved DMI info at "index" with a string.
++ * A '*' at the end of the string will match anything.
++ * Returns 0 for a match.
++ *
++ * This preserves the semantics of the old omnibook_features[]
++ * table. I don't know if its generally useful or not.
++ */
++static int __init cmp_with_glob(int index, char *str)
++{
++ int retval = 0;
++ char *glob;
++ unsigned int len;
++
++ if (str) {
++ glob = strchr(str, '*');
++ len = glob ? glob - str : strlen(str);
++ retval = strncmp(omnibook_dmi_ident[index], str, len);
++ }
++
++ return retval;
++}
++
++static int __init omnibook_ident(void)
++{
++ struct omnibook_models_t *mp;
++
++ for (mp = omnibook_models; mp->ectype != NONE; ++mp) {
++ /* Check all fields for a match */
++ if (cmp_with_glob(OMNIBOOK_SYS_VENDOR, mp->sys_vendor))
++ continue;
++ if (cmp_with_glob(OMNIBOOK_PRODUCT_NAME, mp->product_name))
++ continue;
++ if (cmp_with_glob(OMNIBOOK_PRODUCT_VERSION, mp->product_version))
++ continue;
++ if (cmp_with_glob(OMNIBOOK_BOARD_NAME, mp->board_name))
++ continue;
++
++ /* All required fields matched */
++ break;
++ }
++
++ return (mp - omnibook_models);
++}
++
++static int __init omnibook_get_tc(void)
++{
++ struct omnibook_tc_t *tc;
++
++ for (tc = omnibook_tc; tc->ectype != NONE; ++tc) {
++ /*
++ * Technology code appears in the first two chracters of BIOS version string
++ * ended by a dot, but it prefixed a space character on some models and BIOS
++ * versions.
++ * The new HP/Compaq models use different codes, this is not supported yet.
++ */
++ if (strstr(omnibook_dmi_ident[OMNIBOOK_BIOS_VERSION], tc->tc))
++ break;
++ }
++
++ return (tc - omnibook_tc);
++}
++
++static int __init omnibook_init(void)
++{
++ int retval;
++ int model = 0;
++ int tc = 0;
++ char *syslog_name;
++ char *glob;
++ mode_t pmode;
++
++ omnibook_userset = user;
++
++#ifdef MODULE
++ printk(KERN_INFO "%s: module version %s.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_VERSION);
++#else
++ printk(KERN_INFO "%s: driver version %s.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_VERSION);
++#endif
++
++ /* saving DMI information */
++ if (omnibook_dmi_scan_machine() != 0)
++ return -ENODEV;
++
++ if (ectype != NONE)
++ printk(KERN_WARNING "%s: Forced load with EC firmware type %d.\n", OMNIBOOK_MODULE_NAME, ectype);
++ else {
++ model = omnibook_ident();
++ if (omnibook_models[model].ectype != NONE) {
++ ectype = omnibook_models[model].ectype;
++ syslog_name = omnibook_models[model].syslog_name;
++ if (!syslog_name) {
++ syslog_name = omnibook_models[model].product_version;
++ glob = strchr(syslog_name, '*');
++ if (glob)
++ *glob = '\0';
++ }
++ printk(KERN_INFO "%s: %s detected.\n", OMNIBOOK_MODULE_NAME, syslog_name);
++ } else {
++ /* Without explicite informations try chechking for technology code of HP laptops */
++ tc = omnibook_get_tc();
++ if ((strncmp(omnibook_dmi_ident[OMNIBOOK_SYS_VENDOR], HP_SIGNATURE, strlen(HP_SIGNATURE)) == 0) &&
++ (omnibook_tc[tc].ectype != NONE)) {
++ ectype = omnibook_tc[tc].ectype;
++ printk(KERN_INFO "%s: HP tecnology code %s detected.\n", OMNIBOOK_MODULE_NAME, omnibook_tc[tc].tc);
++ } else {
++ printk(KERN_INFO "%s: Unknown model detected.\n", OMNIBOOK_MODULE_NAME);
++ ac = 0;
++ apmemu = 0;
++ battery = 0;
++ blank = 0;
++ display = 0;
++ dock = 0;
++ fan = 0;
++ fan_policy = 0;
++ lcd = 0;
++ onetouch = 0;
++ temperature = 0;
++ touchpad = 0;
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++ key_polling = 0;
++#endif
++ }
++ }
++ }
++ omnibook_ectype = ectype;
++
++ omnibook_proc_root = proc_mkdir(OMNIBOOK_MODULE_NAME, NULL);
++ if (! omnibook_proc_root) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++
++ pmode = S_IFREG | S_IRUGO;
++ proc_version = create_proc_read_entry("version", pmode, omnibook_proc_root, omnibook_proc_version, NULL);
++ if (! proc_version) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/version.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++
++ if (dmi) {
++ pmode = S_IFREG | S_IRUGO;
++ proc_dmi = create_proc_read_entry("dmi", pmode, omnibook_proc_root, omnibook_proc_dmi, NULL);
++ if (! proc_dmi) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/dmi.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ }
++
++ if ((retval = (ac ? omnibook_ac_init() : 0)))
++ return retval;
++ ac = retval;
++
++ if ((retval = (battery ? omnibook_battery_init() : 0)))
++ return retval;
++ battery = retval;
++
++ /* /proc/apm emulation needs to read battery and AC adapter status */
++ if ((ac == 0) && (battery == 0) && apmemu) {
++ if ((retval = omnibook_apmemu_init()))
++ return retval;
++ }
++
++ if ((retval = (blank ? omnibook_console_blank_init() : 0)))
++ return retval;
++
++ if ((retval = (display ? omnibook_display_init() : 0)))
++ return retval;
++
++ if ((retval = (dock ? omnibook_dock_init() : 0)))
++ return retval;
++
++ if ((retval = (fan ? omnibook_fan_init() : 0)))
++ return retval;
++
++ if ((retval = (fan_policy ? omnibook_fan_policy_init() : 0)))
++ return retval;
++
++ if ((retval = (lcd ? omnibook_brightness_init() : 0)))
++ return retval;
++
++ if ((retval = (onetouch ? omnibook_onetouch_init() : 0)))
++ return retval;
++
++ if ((retval = (temperature ? omnibook_temperature_init() : 0)))
++ return retval;
++
++ if ((retval = (touchpad ? omnibook_touchpad_init() : 0)))
++ return retval;
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++ if ((retval = (key_polling ? omnibook_key_polling_init() : 0)))
++ return retval;
++
++ printk(KERN_WARNING "%s: module unloading does not work yet on 2.6 kernel.\n", OMNIBOOK_MODULE_NAME);
++#endif
++
++ return 0;
++}
++
++static void __exit omnibook_cleanup(void)
++{
++ omnibook_ac_cleanup();
++ omnibook_apmemu_cleanup();
++ omnibook_battery_cleanup();
++ omnibook_brightness_cleanup();
++ omnibook_console_blank_cleanup();
++ omnibook_display_cleanup();
++ omnibook_dock_cleanup();
++ omnibook_fan_cleanup();
++ omnibook_fan_policy_cleanup();
++ omnibook_onetouch_cleanup();
++ omnibook_temperature_cleanup();
++ omnibook_touchpad_cleanup();
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++ omnibook_key_polling_cleanup();
++#endif
++ if (proc_version)
++ remove_proc_entry("version", omnibook_proc_root);
++ if (proc_dmi)
++ remove_proc_entry("dmi", omnibook_proc_root);
++ if (omnibook_proc_root)
++ remove_proc_entry("omnibook", NULL);
++ printk(KERN_INFO "%s: module is unloaded.\n", OMNIBOOK_MODULE_NAME);
++}
++
++module_init(omnibook_init);
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++module_exit(omnibook_cleanup);
++#endif
++
++EXPORT_SYMBOL(omnibook_ectype);
++EXPORT_SYMBOL(omnibook_proc_root);
++
++MODULE_AUTHOR("Soós Péter <sp@osb.hu>");
++MODULE_DESCRIPTION("Kernel interface for HP OmniBook, HP Pavilion, Toshiba Satellite, Acer Aspire and Compal ACL00 laptops");
++MODULE_LICENSE("GPL");
++MODULE_PARM(ectype, "i");
++MODULE_PARM(ac, "i");
++MODULE_PARM(apmemu, "i");
++MODULE_PARM(battery, "i");
++MODULE_PARM(blank, "i");
++MODULE_PARM(display, "i");
++MODULE_PARM(dock, "i");
++MODULE_PARM(dmi, "i");
++MODULE_PARM(fan, "i");
++MODULE_PARM(fan_policy, "i");
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++MODULE_PARM(key_polling, "i");
++#endif
++MODULE_PARM(lcd, "i");
++MODULE_PARM(onetouch, "i");
++MODULE_PARM(temperature, "i");
++MODULE_PARM(touchpad, "i");
++MODULE_PARM(user, "i");
++MODULE_PARM_DESC(ectype, "Type of embedded controller firmware");
++MODULE_PARM_DESC(ac, "Use 0 to disable, 1 to enable AC adapter status monitoring");
++MODULE_PARM_DESC(apmemu, "Use 0 to disable, 1 to enable /proc/apm emulation");
++MODULE_PARM_DESC(battery, "Use 0 to disable, 1 to enable battery status monitoring");
++MODULE_PARM_DESC(blank, "Use 0 to disable, 1 to enable lcd console blanking");
++MODULE_PARM_DESC(display, "Use 0 to disable, 1 to enable display status handling");
++MODULE_PARM_DESC(dock, "Use 0 to disable, 1 to enable docking station support");
++MODULE_PARM_DESC(dmi, "Use 0 to disable, 1 to enable /proc/omnibook/dmi");
++MODULE_PARM_DESC(fan, "Use 0 to disable, 1 to enable fan status monitor and control");
++MODULE_PARM_DESC(fan_policy, "Use 0 to disable, 1 to enable fan control policy support");
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++MODULE_PARM_DESC(key_polling, "Use 0 to disable, 1 to enable to scancode emulation for volume keys");
++#endif
++MODULE_PARM_DESC(lcd, "Use 0 to disable, 1 to enable to LCD brightness support");
++MODULE_PARM_DESC(onetouch, "Use 0 to disable, 1 to enable onetouch handling");
++MODULE_PARM_DESC(temperature, "Use 0 to disable, 1 to enable thermal status and policy support");
++MODULE_PARM_DESC(touchpad, "Use 0 to disable, 1 to enable touchpad handling");
++MODULE_PARM_DESC(user, "Use 0 to disable, 1 to enable users to set parameters");
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/init.h linux-2.6.1-gentoo-test/drivers/char/omnibook/init.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/init.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/init.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,44 @@
++/*
++ * init.h -- initialization and cleanup functions
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++extern int __init omnibook_ac_init(void);
++extern void __exit omnibook_ac_cleanup(void);
++extern int __init omnibook_apmemu_init(void);
++extern void __exit omnibook_apmemu_cleanup(void);
++extern int __init omnibook_battery_init(void);
++extern void __exit omnibook_battery_cleanup(void);
++extern int __init omnibook_console_blank_init(void);
++extern void __exit omnibook_console_blank_cleanup(void);
++extern int __init omnibook_display_init(void);
++extern void __exit omnibook_display_cleanup(void);
++extern int __init omnibook_dock_init(void);
++extern void __exit omnibook_dock_cleanup(void);
++extern int __init omnibook_fan_init(void);
++extern void __exit omnibook_fan_cleanup(void);
++extern int __init omnibook_fan_policy_init(void);
++extern void __exit omnibook_fan_policy_cleanup(void);
++extern int __init omnibook_onetouch_init(void);
++extern void __exit omnibook_onetouch_cleanup(void);
++extern int __init omnibook_key_polling_init(void);
++extern void __exit omnibook_key_polling_cleanup(void);
++extern int __init omnibook_touchpad_init(void);
++extern void __exit omnibook_touchpad_cleanup(void);
++extern int __init omnibook_temperature_init(void);
++extern void __exit omnibook_temperature_cleanup(void);
++extern int __init omnibook_brightness_init(void);
++extern void __exit omnibook_brightness_cleanup(void);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/lcd.c linux-2.6.1-gentoo-test/drivers/char/omnibook/lcd.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/lcd.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/lcd.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,183 @@
++/*
++ * lcd.c -- LCD brightness and on/off
++ *
++ * 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, 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.
++ *
++ * Written by Maciek Górniak <mago@acn.waw.pl>, 2002
++ * Modified by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_brightness;
++
++int omnibook_get_lcd_brightness(void)
++{
++ int retval = 0;
++ u8 brgt;
++#ifdef CONFIG_VT
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_BRTS, &brgt)))
++ return retval;
++ retval = brgt &= XE3GF_BRTS_MASK;
++ break;
++ case XE3GC:
++ if ((retval = omnibook_ec_read(XE3GC_BTVL, &brgt)))
++ return retval;
++ retval = brgt &= XE3GC_BTVL_MASK;
++ break;
++ default:
++ printk(KERN_INFO "%s: LCD brightness handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++
++#endif
++ return retval;
++}
++
++int omnibook_set_lcd_brightness(u8 brgt)
++{
++ int retval = 0;
++#ifdef CONFIG_VT
++
++ brgt = (brgt > 10) ? 10 : brgt;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_write(XE3GF_BRTS, brgt)))
++ return retval;
++ break;
++ case XE3GC:
++ if ((retval = omnibook_ec_write(XE3GC_BTVL, brgt)))
++ return retval;
++ break;
++ default:
++ printk(KERN_INFO "%s: LCD brightness handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV;
++ }
++#endif
++ return retval;
++}
++
++static int omnibook_proc_brightness_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++ int brgt;
++
++ brgt = omnibook_get_lcd_brightness();
++ if (brgt < 0)
++ return brgt;
++
++ b += sprintf(b, "LCD brightness: %2d\n", brgt);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);;
++}
++
++static int omnibook_proc_brightness_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char value[4+1];
++ int brgt = 0;
++ int i;
++ unsigned int len;
++
++ len = sizeof(value) - 1;
++ if (count < len)
++ len = count;
++ if (copy_from_user(value, buffer, len))
++ return -EFAULT;
++ value[len] = 0;
++
++ if (strcmp(value, "off\n") == 0)
++ omnibook_lcd_blank(1);
++ else if (strcmp(value, "on\n") == 0)
++ omnibook_lcd_blank(0);
++ else
++ {
++ for (i = 0; (value[i] != '\0') && (value[i] != '\n'); i++)
++ if ((value[i] >= '0') && (value[i] <= '9'))
++ brgt = brgt * 10 + value[i] - '0';
++ else
++ return -EINVAL;
++
++ if ((brgt >= 0) && (brgt <= 10))
++ omnibook_set_lcd_brightness(brgt);
++ else
++ return -EINVAL;
++ }
++
++ return count;
++}
++
++int __init omnibook_brightness_init(void)
++{
++#ifdef CONFIG_VT
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_brightness = create_proc_entry("lcd", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: LCD brightness handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_brightness) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/lcd.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ } else {
++ proc_brightness->read_proc = omnibook_proc_brightness_status;
++ proc_brightness->write_proc = omnibook_proc_brightness_set;
++ }
++ printk(KERN_INFO "%s: LCD brightness handling is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++#else
++ printk(KERN_ERR "%s: Virtual terminal support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++ return -ENODEV;
++#endif
++}
++
++void __exit omnibook_brightness_cleanup(void)
++{
++#ifdef CONFIG_VT
++ if (proc_brightness)
++ remove_proc_entry("lcd", omnibook_proc_root);
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_get_lcd_brightness);
++EXPORT_SYMBOL(omnibook_set_lcd_brightness);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/omnibook.h linux-2.6.1-gentoo-test/drivers/char/omnibook/omnibook.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/omnibook.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/omnibook.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,131 @@
++/*
++ * omnibook.h -- High level data structures and functions of omnibook
++ * support code
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++/*
++ * Module informations
++ */
++
++#define OMNIBOOK_MODULE_NAME "omnibook"
++#define OMNIBOOK_MODULE_VERSION "2003-12-08"
++
++/*
++ * EC types
++ */
++
++extern int omnibook_ectype;
++enum {
++ NONE,
++ XE3GF, /* HP OmniBook XE3 GF, most Toshiba Satellites and more*/
++ XE3GC, /* HP OmniBook XE3 GC, GD, GE and compatible */
++ OB500, /* HP OmniBook 500 and compatible */
++ OB510, /* HP OmniBook 510 */
++ OB6000, /* HP OmniBook 6000 */
++ OB6100, /* HP OmniBook 6100 */
++ XE4500, /* HP OmniBook xe4500 and compatible */
++ OB4150, /* HP OmniBook 4150 */
++ XE2 /* HP OmniBook XE2 */
++};
++
++extern struct __init proc_dir_entry *omnibook_proc_root;
++extern int omnibook_userset;
++
++extern int omnibook_get_ac(void);
++
++struct omnibook_battery_info {
++ u8 type; /* 1 - Li-Ion, 2 NiMH */
++ u16 sn; /* Serial number */
++ u16 dv; /* Design Voltage */
++ u16 dc; /* Design Capacity */
++};
++struct omnibook_battery_status {
++ u16 pv; /* Present Voltage */
++ u16 rc; /* Remaining Capacity */
++ u16 lc; /* Last Full Capacity */
++ u8 gauge; /* Gauge in % */
++ u8 status; /* 0 - unknown, 1 - charged, 2 - discharging, 3 - charging, 4 - critical) */
++};
++enum {
++ OMNIBOOK_BATTSTAT_UNKNOWN,
++ OMNIBOOK_BATTSTAT_CHARGED,
++ OMNIBOOK_BATTSTAT_DISCHARGING,
++ OMNIBOOK_BATTSTAT_CHARGING,
++ OMNIBOOK_BATTSTAT_CRITICAL
++};
++
++extern int omnibook_battery_present(int num);
++extern int omnibook_get_battery_info(int num, struct omnibook_battery_info *battinfo);
++extern int omnibook_get_battery_status(int num, struct omnibook_battery_status *battstat);
++
++extern int omnibook_console_blank_enabled;
++extern int omnibook_lcd_blank(int blank);
++extern int omnibook_console_blank_enable(void);
++extern int omnibook_console_blank_disable(void);
++
++extern int omnibook_get_display(void);
++
++extern int omnibook_get_dock(void);
++
++extern int omnibook_get_fan(void);
++extern int omnibook_fan_on(void);
++extern int omnibook_fan_off(void);
++
++/*
++ * Default temperature limits.
++ * Danger! You may overheat your CPU!
++ * Do not change these values unless you exactly know what you do.
++ */
++
++#define OMNIBOOK_FAN_LEVELS 7
++#define OMNIBOOK_FAN_MIN 25 /* Minimal value of fan off temperature */
++#define OMNIBOOK_FOT_MAX 75 /* Maximal value of fan off temperature */
++#define OMNIBOOK_FAN_MAX 95 /* Maximal value of fan on temperature */
++#define OMNIBOOK_FOT_DEFAULT 60 /* Default value of fan off temperature */
++#define OMNIBOOK_FAN1_DEFAULT 75 /* Default value of fan on temperature */
++#define OMNIBOOK_FAN2_DEFAULT 85 /* Default value of fan level 2 temperature */
++#define OMNIBOOK_FAN3_DEFAULT 90 /* Default value of fan level 3 temperature */
++#define OMNIBOOK_FAN4_DEFAULT 95 /* Default value of fan level 4 temperature */
++#define OMNIBOOK_FAN5_DEFAULT 95 /* Default value of fan level 5 temperature */
++#define OMNIBOOK_FAN6_DEFAULT 95 /* Default value of fan level 6 temperature */
++#define OMNIBOOK_FAN7_DEFAULT 95 /* Default value of fan level 7 temperature */
++#define OMNIBOOK_FAN_POLICY_STRING 32 /* Maximal length of temperature policy control string */
++
++extern u8 omnibook_fan_policy[OMNIBOOK_FAN_LEVELS];
++
++extern int omnibook_get_fan_policy(void);
++extern int omnibook_set_fan_policy(void);
++extern int omnibook_set_fan_policy_defaults(void);
++
++extern int omnibook_get_lcd_brightness(void);
++extern int omnibook_set_lcd_brightness(u8 brgt);
++
++extern int omnibook_onetouch_enabled;
++extern int omnibook_onetouch_enable(void);
++extern int omnibook_onetouch_disable(void);
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++extern int omnibook_key_polling_enabled;
++extern int omnibook_key_polling_enable(void);
++extern int omnibook_key_polling_disable(void);
++#endif
++
++extern int omnibook_get_cpu_temp(void);
++
++extern int omnibook_touchpad_enabled;
++extern int omnibook_touchpad_enable(void);
++extern int omnibook_touchpad_disable(void);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/onetouch.c linux-2.6.1-gentoo-test/drivers/char/omnibook/onetouch.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/onetouch.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/onetouch.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,239 @@
++/*
++ * onetouch.c -- code to handling OneTouch buttons
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct pm_dev *pm_onetouch;
++static pm_callback pm_onetouch_callback = NULL;
++
++static struct proc_dir_entry *proc_onetouch;
++
++/* There is no information about reading OneTouch status */
++int omnibook_onetouch_enabled = 0;
++
++static int omnibook_onetouch_on(void)
++{
++ if (omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE)) {
++ printk(KERN_ERR "%s: failed OneTouch enable command.\n", OMNIBOOK_MODULE_NAME);
++ return -EIO;
++ }
++ return 0;
++}
++
++static int omnibook_onetouch_off(void)
++{
++ if (omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)) {
++ printk(KERN_ERR "%s: failed OneTouch disable command.\n", OMNIBOOK_MODULE_NAME);
++ return -EIO;
++ }
++ return 0;
++}
++
++/*
++ * Power management handler: on resume it reenables the OneTouch buttons it they were enabled previously
++ */
++
++static int pm_onetouch_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
++{
++ switch (rqst) {
++ case PM_RESUME:
++ if (omnibook_onetouch_enabled)
++ return omnibook_onetouch_on();
++ break;
++ case PM_SUSPEND:
++ if (omnibook_onetouch_enabled)
++ return omnibook_onetouch_off();
++ break;
++ }
++ return 0;
++}
++
++static int omnibook_onetouch_register(void)
++{
++ pm_onetouch_callback = pm_onetouch_handler;
++ pm_onetouch = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_onetouch_callback);
++ return (pm_onetouch ? 0 : -EFAULT);
++}
++
++static void omnibook_onetouch_unregister(void)
++{
++ pm_onetouch_callback = NULL;
++ pm_unregister(pm_onetouch);
++}
++
++int omnibook_onetouch_enable(void)
++{
++#ifdef CONFIG_VT
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ if (! omnibook_onetouch_enabled) {
++ if (omnibook_onetouch_on())
++ return -EIO;
++ omnibook_onetouch_enabled = 1;
++ printk(KERN_INFO "%s: OneTouch buttons are enabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++ break;
++ default:
++ omnibook_onetouch_enabled = 0;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++int omnibook_onetouch_disable(void)
++{
++#ifdef CONFIG_VT
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ if (omnibook_onetouch_enabled) {
++ if (omnibook_onetouch_off()) {
++ return -EIO;
++ }
++ omnibook_onetouch_enabled = 0;
++ printk(KERN_INFO "%s: OneTouch buttons are disabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++ break;
++ default:
++ omnibook_onetouch_enabled = 0;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++static int omnibook_onetouch_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "OneTouch buttons are %s\n", (omnibook_onetouch_enabled) ? "enabled" : "disabled");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_onetouch_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char status[1] = {'\0'};
++
++ if (copy_from_user(status, buffer, 1))
++ return -EFAULT;
++ switch (*status) {
++ case '0':
++ omnibook_onetouch_disable();
++ break;
++ case '1':
++ omnibook_onetouch_enable();
++ break;
++ default:
++ count = -EINVAL;
++ }
++ return count;
++}
++
++int __init omnibook_onetouch_init(void)
++{
++#ifdef CONFIG_VT
++ int retval;
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_onetouch = create_proc_entry("onetouch", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: OneTouch button handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ omnibook_onetouch_enabled = 0;
++ return 0;
++ }
++ if (proc_onetouch) {
++ proc_onetouch->read_proc = omnibook_onetouch_status;
++ proc_onetouch->write_proc = omnibook_onetouch_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/onetouch.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ if ((retval = omnibook_onetouch_register()))
++ return retval;
++ if ((retval = omnibook_onetouch_enable()))
++ return retval;
++
++ return 0;
++#else
++ printk(KERN_ERR "%s: Virtual terminal support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++// return -ENODEV;
++ return 0;
++#endif
++}
++
++void __exit omnibook_onetouch_cleanup(void)
++{
++#ifdef CONFIG_VT
++ if (proc_onetouch)
++ remove_proc_entry("onetouch", omnibook_proc_root);
++ if (pm_onetouch)
++ omnibook_onetouch_unregister();
++
++ omnibook_onetouch_disable();
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_onetouch_enabled);
++EXPORT_SYMBOL(omnibook_onetouch_enable);
++EXPORT_SYMBOL(omnibook_onetouch_disable);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/polling.c linux-2.6.1-gentoo-test/drivers/char/omnibook/polling.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/polling.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/polling.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,268 @@
++/*
++ * polling.c -- scancode emulation for volume buttons on certain models
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++#include <linux/version.h>
++#include <linux/timer.h>
++#include <linux/kbd_ll.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++/*
++ * Pollong interval for keys (50 ms)
++ */
++
++#define OMNIBOOK_POLL 50 * HZ / 1000
++
++
++
++static struct pm_dev *pm_key_polling;
++static pm_callback pm_key_polling_callback = NULL;
++
++static struct proc_dir_entry *proc_key_polling;
++
++static struct timer_list omnibook_key_timer;
++
++int omnibook_key_polling_enabled = 0;
++static int pm_omnibook_key_polling_enabled;
++
++static void omnibook_key_poller(unsigned long data)
++{
++ u8 q0a;
++
++ switch (omnibook_ectype) {
++ case XE3GC:
++ omnibook_ec_read(XE3GC_Q0A, &q0a);
++ omnibook_ec_write(XE3GC_Q0A, 0);
++
++// if (q0a & XE3GC_SLPB_MASK)
++// printk(KERN_INFO "%s: Sleep button pressed.\n", OMNIBOOK_MODULE_NAME);
++// if (q0a & XE3GC_F5_MASK)
++// printk(KERN_INFO "%s: Fn-F5 - LCD/CRT switch pressed.\n", OMNIBOOK_MODULE_NAME);
++ /*
++ * Volume button scancode emulaton
++ * It emulates a key press and a release without repeat as other OneTouch buttons do.
++ */
++ if (q0a & XE3GC_VOLD_MASK) {
++ printk(KERN_INFO "%s: Fn-down arrow or Volume down pressed.\n", OMNIBOOK_MODULE_NAME);
++ handle_scancode(0xe0, 1);
++ handle_scancode(XE3GC_VOLD_SCAN, 1);
++ handle_scancode(0xe0, 0);
++ handle_scancode(XE3GC_VOLD_SCAN, 0);
++ }
++ if (q0a & XE3GC_VOLU_MASK) {
++ printk(KERN_INFO "%s: Fn-up arrow or Volume up pressed.\n", OMNIBOOK_MODULE_NAME);
++ handle_scancode(0xe0, 1);
++ handle_scancode(XE3GC_VOLU_SCAN, 1);
++ handle_scancode(0xe0, 0);
++ handle_scancode(XE3GC_VOLU_SCAN, 0);
++ }
++ if (q0a & XE3GC_MUTE_MASK) {
++ printk(KERN_INFO "%s: Fn+F7 - Volume mute pressed.\n", OMNIBOOK_MODULE_NAME);
++ handle_scancode(0xe0, 1);
++ handle_scancode(XE3GC_MUTE_SCAN, 1);
++ handle_scancode(0xe0, 0);
++ handle_scancode(XE3GC_MUTE_SCAN, 0);
++ }
++// if (q0a & XE3GC_CNTR_MASK)
++// printk(KERN_INFO "%s: Fn+F3/Fn+F4 - Contrast up or down pressed.\n", OMNIBOOK_MODULE_NAME);
++// if (q0a & XE3GC_BRGT_MASK)
++// printk(KERN_INFO "%s: Fn+F1/Fn+F2 - Brightness up or down pressed.\n", OMNIBOOK_MODULE_NAME);
++ break;
++ }
++
++ mod_timer(&omnibook_key_timer, jiffies + OMNIBOOK_POLL);
++}
++
++int omnibook_key_polling_enable(void)
++{
++#ifdef CONFIG_VT
++ switch (omnibook_ectype) {
++ case XE3GC:
++ printk(KERN_INFO "%s: Volume buttons do not generate scancodes on this model.\n", OMNIBOOK_MODULE_NAME);
++ init_timer(&omnibook_key_timer);
++ omnibook_key_timer.data = 0;
++ omnibook_key_timer.function = omnibook_key_poller;
++ omnibook_key_timer.expires = jiffies + OMNIBOOK_POLL;
++ add_timer(&omnibook_key_timer);
++ omnibook_key_polling_enabled = 1;
++ printk(KERN_INFO "%s: Scancode emulation for volume buttons enabled.\n", OMNIBOOK_MODULE_NAME);
++ break;
++ default:
++ omnibook_key_polling_enabled = 0;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++int omnibook_key_polling_disable(void)
++{
++#ifdef CONFIG_VT
++ switch (omnibook_ectype) {
++ case XE3GC:
++ if (&omnibook_key_timer) {
++ del_timer(&omnibook_key_timer);
++ printk(KERN_INFO "%s: Scancode emulation for volume buttons disabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++ omnibook_key_polling_enabled = 0;
++ break;
++ default:
++ omnibook_key_polling_enabled = 0;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++/*
++ * Power management handler: on resume it reenables key polling if it was enabled previously
++ */
++
++static int pm_key_polling_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
++{
++
++ switch (rqst) {
++ case PM_RESUME:
++ if (pm_omnibook_key_polling_enabled)
++ return omnibook_key_polling_enable();
++ break;
++ case PM_SUSPEND:
++ if (omnibook_key_polling_enabled)
++ pm_omnibook_key_polling_enabled = omnibook_key_polling_enabled;
++ return omnibook_key_polling_disable();
++ break;
++ }
++ return 0;
++}
++
++static int omnibook_key_polling_register(void)
++{
++ pm_key_polling_callback = pm_key_polling_handler;
++ pm_key_polling = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_key_polling_callback);
++ return (pm_key_polling ? 0 : -EFAULT);
++}
++
++static void omnibook_key_polling_unregister(void)
++{
++ pm_key_polling_callback = NULL;
++ pm_unregister(pm_key_polling);
++}
++
++static int omnibook_key_polling_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "Volume buttons handling is %s\n", (omnibook_key_polling_enabled) ? "enabled" : "disabled");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_key_polling_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char status[1] = {'\0'};
++
++ if (copy_from_user(status, buffer, 1))
++ return -EFAULT;
++ switch (*status) {
++ case '0':
++ omnibook_key_polling_disable();
++ break;
++ case '1':
++ omnibook_key_polling_enable();
++ break;
++ default:
++ count = -EINVAL;
++ }
++ return count;
++}
++
++
++int __init omnibook_key_polling_init(void)
++{
++#ifdef CONFIG_VT
++
++ int retval;
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GC:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_key_polling = create_proc_entry("key_polling", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: Key polling is unnecessary on this machine.\n", OMNIBOOK_MODULE_NAME);
++ omnibook_key_polling_enabled = 0;
++ return 0;
++ }
++ if (proc_key_polling) {
++ proc_key_polling->read_proc = omnibook_key_polling_status;
++ proc_key_polling->write_proc = omnibook_key_polling_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/key_polling.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ if ((retval = omnibook_key_polling_register()))
++ return retval;
++// if ((retval = omnibook_key_polling_enable()))
++// return retval;
++
++ printk(KERN_INFO "%s: Key polling is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++#else
++ printk(KERN_ERR "%s: Virtual terminal support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++ return -ENODEV;
++#endif
++}
++
++void __exit omnibook_key_polling_cleanup(void)
++{
++#ifdef CONFIG_VT
++ if (proc_key_polling)
++ remove_proc_entry("key_polling", omnibook_proc_root);
++ if (pm_key_polling)
++ omnibook_key_polling_unregister();
++
++ omnibook_key_polling_disable();
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_key_polling_enabled);
++EXPORT_SYMBOL(omnibook_key_polling_enable);
++EXPORT_SYMBOL(omnibook_key_polling_disable);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/temperature.c linux-2.6.1-gentoo-test/drivers/char/omnibook/temperature.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/temperature.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/temperature.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,130 @@
++/*
++ * temperature.c -- CPU temprature monitoring
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct proc_dir_entry *proc_temperature;
++
++int omnibook_get_cpu_temp(void)
++{
++ u8 temp = 0;
++ int retval;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ if ((retval = omnibook_ec_read(XE3GF_CTMP, &temp)))
++ return retval;
++ retval = temp;
++ break;
++ case XE3GC:
++ if ((retval = omnibook_ec_read(XE3GC_CTMP, &temp)))
++ return retval;
++ retval = temp;
++ break;
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ case XE2:
++ if ((retval = omnibook_ec_read(OB500_CTMP, &temp)))
++ return retval;
++ retval = temp;
++ break;
++ case OB4150:
++ if ((retval = omnibook_ec_read(OB4150_TMP, &temp)))
++ return retval;
++ retval = temp;
++ break;
++ default:
++ printk(KERN_INFO "%s: Temperature monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ retval = -ENODEV ;
++ }
++ return retval;
++}
++
++static int omnibook_proc_temperature(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++ int cpu_temp;
++
++ cpu_temp = omnibook_get_cpu_temp();
++ if (cpu_temp < 0)
++ return cpu_temp;
++
++ b += sprintf(b, "CPU temperature: %2d C\n", cpu_temp);
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++int __init omnibook_temperature_init(void)
++{
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ case OB500:
++ case OB510:
++ case OB6000:
++ case OB6100:
++ case XE4500:
++ case OB4150:
++ case XE2:
++ pmode = S_IFREG | S_IRUGO;
++ proc_temperature = create_proc_read_entry("temperature", pmode, omnibook_proc_root, omnibook_proc_temperature, NULL);
++ break;
++ default:
++ printk(KERN_INFO "%s: Temperature monitoring is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++ }
++ if (! proc_temperature) {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/temperature.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ printk(KERN_INFO "%s: Temperature monitoring is enabled.\n", OMNIBOOK_MODULE_NAME);
++ return 0;
++}
++
++void __exit omnibook_temperature_cleanup(void)
++{
++ if (proc_temperature)
++ remove_proc_entry("temperature", omnibook_proc_root);
++}
++
++EXPORT_SYMBOL(omnibook_get_cpu_temp);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/touchpad.c linux-2.6.1-gentoo-test/drivers/char/omnibook/touchpad.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/touchpad.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/touchpad.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,239 @@
++/*
++ * touchpad.c -- enable/disable touchpad
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/pm.h>
++#include <linux/proc_fs.h>
++
++#include <asm/system.h>
++#include <asm/errno.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#ifdef OMNIBOOK_STANDALONE
++#include "omnibook.h"
++#else
++#include <linux/omnibook.h>
++#endif
++
++#include "ec.h"
++#include "util.h"
++
++static struct pm_dev *pm_touchpad;
++static pm_callback pm_touchpad_callback = NULL;
++
++static struct proc_dir_entry *proc_touchpad;
++
++#ifdef CONFIG_MOUSE_PS2
++#define OMNIBOOK_TOUCHPAD
++#endif
++
++#ifdef CONFIG_PSMOUSE
++#define OMNIBOOK_TOUCHPAD
++#endif
++
++#ifdef OMNIBOOK_TOUCHPAD
++/* Touchpad is enabled by default */
++int omnibook_touchpad_enabled = 1;
++#else
++int omnibook_touchpad_enabled = 0;
++#endif
++
++static int omnibook_touchpad_on(void)
++{
++ if (omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_TOUCHPAD_ENABLE)) {
++ printk(KERN_ERR "%s: failed touchpad enable command.\n", OMNIBOOK_MODULE_NAME);
++ return -EIO;
++ }
++ return 0;
++}
++
++static int omnibook_touchpad_off(void)
++{
++ if (omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_TOUCHPAD_DISABLE)) {
++ printk(KERN_ERR "%s: failed touchpad disable command.\n", OMNIBOOK_MODULE_NAME);
++ return -EIO;
++ }
++ return 0;
++}
++
++/*
++ * Power management handler: on resume it redisables the touchpad if it was disabled previously
++ */
++
++static int pm_touchpad_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
++{
++ switch (rqst) {
++ case PM_RESUME:
++ if (! omnibook_touchpad_enabled)
++ return omnibook_touchpad_off();
++ break;
++ }
++ return 0;
++}
++
++static int omnibook_touchpad_register(void)
++{
++ pm_touchpad_callback = pm_touchpad_handler;
++ pm_touchpad = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_touchpad_callback);
++ return (pm_touchpad ? 0 : -EFAULT);
++}
++
++static void omnibook_touchpad_unregister(void)
++{
++ pm_touchpad_callback = NULL;
++ pm_unregister(pm_touchpad);
++}
++
++int omnibook_touchpad_enable(void)
++{
++#ifdef OMNIBOOK_TOUCHPAD
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ if (! omnibook_touchpad_enabled) {
++ if (omnibook_touchpad_on())
++ return -EIO;
++ omnibook_touchpad_enabled = 1;
++ printk(KERN_INFO "%s: Touchpad is enabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++ break;
++ case OB500:
++ case OB510:
++ omnibook_touchpad_enabled = 0;
++ return -ENODEV;
++ break;
++ default:
++ omnibook_touchpad_enabled = 1;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++int omnibook_touchpad_disable(void)
++{
++#ifdef OMNIBOOK_TOUCHPAD
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ if (omnibook_touchpad_enabled) {
++ if (omnibook_touchpad_off()) {
++ return -EIO;
++ }
++ omnibook_touchpad_enabled = 0;
++ printk(KERN_INFO "%s: Touchpad is disabled.\n", OMNIBOOK_MODULE_NAME);
++ }
++ break;
++ case OB500:
++ case OB510:
++ omnibook_touchpad_enabled = 0;
++ return -ENODEV;
++ break;
++ default:
++ omnibook_touchpad_enabled = 1;
++ return -ENODEV;
++ }
++#endif
++ return 0;
++}
++
++static int omnibook_touchpad_status(char *buffer, char **start, off_t off, int count, int *eof, void *data)
++{
++ char *b = buffer;
++
++ b += sprintf(b, "Touchpad is %s\n", (omnibook_touchpad_enabled) ? "enabled" : "disabled");
++
++ return omnibook_proc_len(buffer, start, off, count, eof, b);
++}
++
++static int omnibook_touchpad_set(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++ char status[1] = {'\0'};
++
++ if (copy_from_user(status, buffer, 1))
++ return -EFAULT;
++ switch (*status) {
++ case '0':
++ omnibook_touchpad_disable();
++ break;
++ case '1':
++ omnibook_touchpad_enable();
++ break;
++ default:
++ count = -EINVAL;
++ }
++ return count;
++}
++
++int __init omnibook_touchpad_init(void)
++{
++#ifdef OMNIBOOK_TOUCHPAD
++ int retval;
++ mode_t pmode;
++
++ switch (omnibook_ectype) {
++ case XE3GF:
++ case XE3GC:
++ pmode = S_IFREG | S_IWUSR | S_IRUGO;
++ if (omnibook_userset)
++ pmode = pmode | S_IWUGO;
++ proc_touchpad = create_proc_entry("touchpad", pmode, omnibook_proc_root);
++ break;
++ default:
++ printk(KERN_INFO "%s: Touchpad handling is unsupported on this machine.\n", OMNIBOOK_MODULE_NAME);
++ omnibook_touchpad_enabled = 1;
++ return 0;
++ }
++ if (proc_touchpad) {
++ proc_touchpad->read_proc = omnibook_touchpad_status;
++ proc_touchpad->write_proc = omnibook_touchpad_set;
++ } else {
++ printk(KERN_ERR "%s: Unable to create /proc/%s/touchpad.\n", OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME);
++ return -ENOENT;
++ }
++ if ((retval = omnibook_touchpad_register()))
++ return retval;
++
++ return 0;
++#else
++ printk(KERN_ERR "%s: PS/2 mouse support is not compiled into your kernel.\n", OMNIBOOK_MODULE_NAME);
++// return -ENODEV;
++ return 0;
++#endif
++}
++
++void __exit omnibook_touchpad_cleanup(void)
++{
++#ifdef OMNIBOOK_TOUCHPAD
++ if (proc_touchpad)
++ remove_proc_entry("touchpad", omnibook_proc_root);
++ if (pm_touchpad)
++ omnibook_touchpad_unregister();
++ omnibook_touchpad_enable();
++#endif
++}
++
++EXPORT_SYMBOL(omnibook_touchpad_enabled);
++EXPORT_SYMBOL(omnibook_touchpad_enable);
++EXPORT_SYMBOL(omnibook_touchpad_disable);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/util.c linux-2.6.1-gentoo-test/drivers/char/omnibook/util.c
+--- linux-2.6.1-gentoo/drivers/char/omnibook/util.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/util.c 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,35 @@
++/*
++ * util.c -- utility functions
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2003
++ */
++
++#include <linux/types.h>
++
++int omnibook_proc_len(char *buffer, char **start, off_t off, int count, int *eof, char *b)
++{
++ unsigned int len;
++
++ len = b - buffer;
++ if (len < off + count)
++ *eof = 1;
++ *start = buffer + off;
++ len -= off;
++ if (len > count)
++ len = count;
++ if (len < 0)
++ len = 0;
++ return len;
++}
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/char/omnibook/util.h linux-2.6.1-gentoo-test/drivers/char/omnibook/util.h
+--- linux-2.6.1-gentoo/drivers/char/omnibook/util.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/drivers/char/omnibook/util.h 2004-01-09 22:33:49.000000000 +0000
+@@ -0,0 +1,19 @@
++/*
++ * util.h -- Utility declarations
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2003
++ */
++
++extern int omnibook_proc_len(char *buffer, char **start, off_t off, int count, int *eof, char *b);
++
++/* End of file */
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/drivers/input/keyboard/atkbd.c linux-2.6.1-gentoo-test/drivers/input/keyboard/atkbd.c
+--- linux-2.6.1-gentoo/drivers/input/keyboard/atkbd.c 2004-01-09 23:40:12.000000000 +0000
++++ linux-2.6.1-gentoo-test/drivers/input/keyboard/atkbd.c 2004-01-09 23:32:25.000000000 +0000
+@@ -59,11 +59,11 @@
+ 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+- 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125,
++ 217,100,255,118, 97,165, 0, 0,156,117, 0, 0, 0, 0, 0,125,
+ 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127,
+ 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142,
+ 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0,
+- 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
++ 226,116, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112,
+ 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
+
+diff -Naur --exclude '*.orig' --exclude '*.rej' linux-2.6.1-gentoo/include/linux/omnibook.h linux-2.6.1-gentoo-test/include/linux/omnibook.h
+--- linux-2.6.1-gentoo/include/linux/omnibook.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.1-gentoo-test/include/linux/omnibook.h 2004-01-09 22:34:17.000000000 +0000
+@@ -0,0 +1,131 @@
++/*
++ * omnibook.h -- High level data structures and functions of omnibook
++ * support code
++ *
++ * 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, 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.
++ *
++ * Written by Soós Péter <sp@osb.hu>, 2002-2003
++ */
++
++/*
++ * Module informations
++ */
++
++#define OMNIBOOK_MODULE_NAME "omnibook"
++#define OMNIBOOK_MODULE_VERSION "2003-12-08"
++
++/*
++ * EC types
++ */
++
++extern int omnibook_ectype;
++enum {
++ NONE,
++ XE3GF, /* HP OmniBook XE3 GF, most Toshiba Satellites and more*/
++ XE3GC, /* HP OmniBook XE3 GC, GD, GE and compatible */
++ OB500, /* HP OmniBook 500 and compatible */
++ OB510, /* HP OmniBook 510 */
++ OB6000, /* HP OmniBook 6000 */
++ OB6100, /* HP OmniBook 6100 */
++ XE4500, /* HP OmniBook xe4500 and compatible */
++ OB4150, /* HP OmniBook 4150 */
++ XE2 /* HP OmniBook XE2 */
++};
++
++extern struct __init proc_dir_entry *omnibook_proc_root;
++extern int omnibook_userset;
++
++extern int omnibook_get_ac(void);
++
++struct omnibook_battery_info {
++ u8 type; /* 1 - Li-Ion, 2 NiMH */
++ u16 sn; /* Serial number */
++ u16 dv; /* Design Voltage */
++ u16 dc; /* Design Capacity */
++};
++struct omnibook_battery_status {
++ u16 pv; /* Present Voltage */
++ u16 rc; /* Remaining Capacity */
++ u16 lc; /* Last Full Capacity */
++ u8 gauge; /* Gauge in % */
++ u8 status; /* 0 - unknown, 1 - charged, 2 - discharging, 3 - charging, 4 - critical) */
++};
++enum {
++ OMNIBOOK_BATTSTAT_UNKNOWN,
++ OMNIBOOK_BATTSTAT_CHARGED,
++ OMNIBOOK_BATTSTAT_DISCHARGING,
++ OMNIBOOK_BATTSTAT_CHARGING,
++ OMNIBOOK_BATTSTAT_CRITICAL
++};
++
++extern int omnibook_battery_present(int num);
++extern int omnibook_get_battery_info(int num, struct omnibook_battery_info *battinfo);
++extern int omnibook_get_battery_status(int num, struct omnibook_battery_status *battstat);
++
++extern int omnibook_console_blank_enabled;
++extern int omnibook_lcd_blank(int blank);
++extern int omnibook_console_blank_enable(void);
++extern int omnibook_console_blank_disable(void);
++
++extern int omnibook_get_display(void);
++
++extern int omnibook_get_dock(void);
++
++extern int omnibook_get_fan(void);
++extern int omnibook_fan_on(void);
++extern int omnibook_fan_off(void);
++
++/*
++ * Default temperature limits.
++ * Danger! You may overheat your CPU!
++ * Do not change these values unless you exactly know what you do.
++ */
++
++#define OMNIBOOK_FAN_LEVELS 7
++#define OMNIBOOK_FAN_MIN 25 /* Minimal value of fan off temperature */
++#define OMNIBOOK_FOT_MAX 75 /* Maximal value of fan off temperature */
++#define OMNIBOOK_FAN_MAX 95 /* Maximal value of fan on temperature */
++#define OMNIBOOK_FOT_DEFAULT 60 /* Default value of fan off temperature */
++#define OMNIBOOK_FAN1_DEFAULT 75 /* Default value of fan on temperature */
++#define OMNIBOOK_FAN2_DEFAULT 85 /* Default value of fan level 2 temperature */
++#define OMNIBOOK_FAN3_DEFAULT 90 /* Default value of fan level 3 temperature */
++#define OMNIBOOK_FAN4_DEFAULT 95 /* Default value of fan level 4 temperature */
++#define OMNIBOOK_FAN5_DEFAULT 95 /* Default value of fan level 5 temperature */
++#define OMNIBOOK_FAN6_DEFAULT 95 /* Default value of fan level 6 temperature */
++#define OMNIBOOK_FAN7_DEFAULT 95 /* Default value of fan level 7 temperature */
++#define OMNIBOOK_FAN_POLICY_STRING 32 /* Maximal length of temperature policy control string */
++
++extern u8 omnibook_fan_policy[OMNIBOOK_FAN_LEVELS];
++
++extern int omnibook_get_fan_policy(void);
++extern int omnibook_set_fan_policy(void);
++extern int omnibook_set_fan_policy_defaults(void);
++
++extern int omnibook_get_lcd_brightness(void);
++extern int omnibook_set_lcd_brightness(u8 brgt);
++
++extern int omnibook_onetouch_enabled;
++extern int omnibook_onetouch_enable(void);
++extern int omnibook_onetouch_disable(void);
++
++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
++extern int omnibook_key_polling_enabled;
++extern int omnibook_key_polling_enable(void);
++extern int omnibook_key_polling_disable(void);
++#endif
++
++extern int omnibook_get_cpu_temp(void);
++
++extern int omnibook_touchpad_enabled;
++extern int omnibook_touchpad_enable(void);
++extern int omnibook_touchpad_disable(void);
++
++/* End of file */