aboutsummaryrefslogtreecommitdiff
path: root/ubuntu
diff options
context:
space:
mode:
authorManoj Iyer <manoj.iyer@canonical.com>2009-12-07 21:20:32 -0600
committerLeann Ogasawara <leann.ogasawara@canonical.com>2010-09-02 12:55:23 -0700
commit85082d36c414d310801fc483689ba3ff8699b183 (patch)
tree5619aebb6afad70791823d3a898f2e9274318856 /ubuntu
parentab40087fb037ab50886ea7cad75047a3a0dc8989 (diff)
UBUNTU: ubuntu: omnibook -- support Toshiba (HP) netbooks
ExternalDriver: omnibook Description: driver for HP & Toshiba laptops Url: https://omnibook.svn.sourceforge.net/svnroot/omnibook/omnibook/trunk Mask: Version: 2.20070211 Signed-off-by: Manoj Iyer <manoj.iyer@canonical.com>
Diffstat (limited to 'ubuntu')
-rw-r--r--ubuntu/Kconfig1
-rw-r--r--ubuntu/Makefile1
-rw-r--r--ubuntu/omnibook/Kconfig4
-rw-r--r--ubuntu/omnibook/Makefile171
-rw-r--r--ubuntu/omnibook/ac.c60
-rw-r--r--ubuntu/omnibook/acpi.c1158
-rw-r--r--ubuntu/omnibook/battery.c557
-rw-r--r--ubuntu/omnibook/blank.c138
-rw-r--r--ubuntu/omnibook/bluetooth.c104
-rw-r--r--ubuntu/omnibook/compal.c526
-rw-r--r--ubuntu/omnibook/compat.h71
-rw-r--r--ubuntu/omnibook/cooling.c97
-rw-r--r--ubuntu/omnibook/debian/README.Debian30
-rw-r--r--ubuntu/omnibook/debian/changelog170
-rw-r--r--ubuntu/omnibook/debian/compat1
-rw-r--r--ubuntu/omnibook/debian/control21
-rw-r--r--ubuntu/omnibook/debian/control.modules.in23
-rw-r--r--ubuntu/omnibook/debian/copyright32
-rw-r--r--ubuntu/omnibook/debian/docs4
-rwxr-xr-xubuntu/omnibook/debian/rules135
-rw-r--r--ubuntu/omnibook/display.c114
-rw-r--r--ubuntu/omnibook/doc/BUGS17
-rw-r--r--ubuntu/omnibook/doc/COPYING340
-rw-r--r--ubuntu/omnibook/doc/CREDITS39
-rw-r--r--ubuntu/omnibook/doc/ChangeLog521
-rw-r--r--ubuntu/omnibook/doc/README42
-rw-r--r--ubuntu/omnibook/dock.c84
-rw-r--r--ubuntu/omnibook/dump.c107
-rw-r--r--ubuntu/omnibook/ec.c188
-rw-r--r--ubuntu/omnibook/fan.c183
-rw-r--r--ubuntu/omnibook/fan_policy.c188
-rw-r--r--ubuntu/omnibook/hardware.h582
-rw-r--r--ubuntu/omnibook/hotkeys.c193
-rw-r--r--ubuntu/omnibook/info.c68
-rw-r--r--ubuntu/omnibook/init.c535
-rw-r--r--ubuntu/omnibook/kbc.c152
-rw-r--r--ubuntu/omnibook/laptop.h1077
-rw-r--r--ubuntu/omnibook/lcd.c207
-rw-r--r--ubuntu/omnibook/lib.c81
-rw-r--r--ubuntu/omnibook/misc/README.mmkeys9
-rw-r--r--ubuntu/omnibook/misc/dmi_strings.txt857
-rw-r--r--ubuntu/omnibook/misc/hotkeys/README.hotkeys22
-rw-r--r--ubuntu/omnibook/misc/hotkeys/nx9xxx.def28
-rw-r--r--ubuntu/omnibook/misc/hotkeys/ob5xx.def30
-rw-r--r--ubuntu/omnibook/misc/hotkeys/xe3gc.def32
-rw-r--r--ubuntu/omnibook/misc/hotkeys/xe3gf.def32
-rw-r--r--ubuntu/omnibook/misc/hotkeys/xe4xxx.def28
-rw-r--r--ubuntu/omnibook/misc/hotkeys/xt155.def23
-rw-r--r--ubuntu/omnibook/muteled.c109
-rw-r--r--ubuntu/omnibook/nbsmi.c968
-rw-r--r--ubuntu/omnibook/omnibook.h145
-rw-r--r--ubuntu/omnibook/pio.c173
-rw-r--r--ubuntu/omnibook/polling.c259
-rw-r--r--ubuntu/omnibook/sections.lds11
-rw-r--r--ubuntu/omnibook/temperature.c55
-rw-r--r--ubuntu/omnibook/throttling.c83
-rw-r--r--ubuntu/omnibook/touchpad.c126
-rw-r--r--ubuntu/omnibook/wireless.c108
58 files changed, 11120 insertions, 0 deletions
diff --git a/ubuntu/Kconfig b/ubuntu/Kconfig
index d81c542485a..3ac176daf2b 100644
--- a/ubuntu/Kconfig
+++ b/ubuntu/Kconfig
@@ -7,6 +7,7 @@ source "ubuntu/fsam7400/Kconfig"
source "ubuntu/iscsitarget/Kconfig"
source "ubuntu/lirc/Kconfig"
source "ubuntu/ndiswrapper/Kconfig"
+source "ubuntu/omnibook/Kconfig"
source "ubuntu/rfkill/Kconfig"
endmenu
diff --git a/ubuntu/Makefile b/ubuntu/Makefile
index e473594ab2c..6b8a09795ed 100644
--- a/ubuntu/Makefile
+++ b/ubuntu/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DM_RAID45) += dm-raid4-5/
obj-$(CONFIG_FSAM7400) += fsam7400/
obj-$(CONFIG_LIRC_DEV) += lirc/
obj-$(CONFIG_NDISWRAPPER) += ndiswrapper/
+obj-$(CONFIG_OMNIBOOK) += omnibook/
obj-m += rfkill/
# This is a stupid trick to get kbuild to create ubuntu/built-in.o
diff --git a/ubuntu/omnibook/Kconfig b/ubuntu/omnibook/Kconfig
new file mode 100644
index 00000000000..370b379b25a
--- /dev/null
+++ b/ubuntu/omnibook/Kconfig
@@ -0,0 +1,4 @@
+config OMNIBOOK
+ tristate "Kernel module for HP and Toshiba laptops"
+ default m
+ ---help---
diff --git a/ubuntu/omnibook/Makefile b/ubuntu/omnibook/Makefile
new file mode 100644
index 00000000000..fcde1fab866
--- /dev/null
+++ b/ubuntu/omnibook/Makefile
@@ -0,0 +1,171 @@
+#
+# 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-2004
+# Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006-2007
+#
+
+#Module informations
+
+MODULE_NAME = omnibook
+MODULE_VERSION = 2.20090707
+MODULE_BRANCH = trunk
+
+# Out-of-tree configuration
+ifndef CONFIG_OMNIBOOK
+OMNIBOOK_STANDALONE=y
+CONFIG_OMNIBOOK=m
+
+#Uncomment and set to force debug behavior
+#NOTE: Default (commented) behavior is to enable debug in trunk or branch svn
+# snapshot and to disable it for release
+#OMNIBOOK_WANT_DEBUG=n
+
+#comment to disable backlight device support
+OMNIBOOK_WANT_BACKLIGHT=y
+
+#Uncomment to force legacy (pre-ACPI system) features support
+#OMNIBOOK_WANT_LEGACY=y
+
+endif
+
+ifeq ($(KERNELRELEASE),)
+# Support for direct Makefile invocation
+
+DESTDIR =
+MODDIR = $(DESTDIR)/lib/modules
+KVERS = $(shell uname -r)
+KVER = $(KVERS)
+VMODDIR = $(MODDIR)/$(KVER)
+INSTDIR = extra
+#KSRC = /usr/src/linux
+KSRC = $(VMODDIR)/build
+KMODDIR = $(KSRC)/drivers/misc/omnibook
+KDOCDIR = $(KSRC)/Documentation/omnibook
+PWD = $(shell pwd)
+TODAY = $(shell date +%Y%m%d)
+DEPMOD = /sbin/depmod -aq
+RMMOD = /sbin/modprobe -r
+INSMOD = /sbin/modprobe
+INSTALL = install -m 644
+MKDIR = mkdir -p
+RM = rm -f
+FIND = find
+
+all: $(MODULE_NAME).ko
+
+clean:
+ make -C $(KSRC) M=$(PWD) clean
+ $(RM) -r *~ "#*#" .swp
+ $(RM) -r debian/omnibook-source *-stamp
+ $(RM) -r Module.symvers Modules.symvers
+
+install: all
+ # Removing module from locations used by previous versions
+ $(RM) $(VMODDIR)/kernel/drivers/char/$(MODULE_NAME).ko
+ $(RM) $(VMODDIR)/kernel/drivers/misc/$(MODULE_NAME).ko
+ make INSTALL_MOD_PATH=$(DESTDIR) INSTALL_MOD_DIR=$(INSTDIR) -C $(KSRC) M=$(PWD) modules_install
+
+unload:
+ $(RMMOD) $(MODULE_NAME) || :
+
+load: install unload
+ $(DEPMOD)
+ $(INSMOD) $(MODULE_NAME)
+
+uninstall: unload
+ $(FIND) $(VMODDIR) -name "$(MODULE_NAME).ko" -exec $(RM) {} \;
+ $(DEPMOD)
+
+$(MODULE_NAME).ko:
+ $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules
+
+kinstall:
+ $(RM) -r $(KMODDIR)
+ $(MKDIR) $(KMODDIR)
+ $(INSTALL) *.h *.c sections.lds $(KMODDIR)
+ $(MKDIR) $(KDOCDIR)
+ $(INSTALL) doc/README $(KDOCDIR)
+
+kpatch: kinstall
+ (cd $(KSRC); patch -p1 < $(PWD)/misc/omnibook-integration.patch)
+
+version:
+ sed -i "s|^\(MODULE_VERSION = \).*|\1 2.$(TODAY)|" Makefile
+ sed -i "s|^\(MODULE_BRANCH = \).*|\1 release|" Makefile
+ sed -i "s|^\(2\.\)X\{8\}|\1$(TODAY)|" doc/ChangeLog
+
+
+release: clean version
+ mkdir -p ../$(MODULE_NAME)-2.$(TODAY)
+ cp -a *.h *.c *.lds Makefile doc misc ../$(MODULE_NAME)-2.$(TODAY)
+ rm -f ../$(MODULE_NAME)-2.$(TODAY).tar ../$(MODULE_NAME)-2.$(TODAY).tar.gz
+ (cd ..; tar cvf $(MODULE_NAME)-2.$(TODAY).tar $(MODULE_NAME)-2.$(TODAY); gzip -9 $(MODULE_NAME)-2.$(TODAY).tar)
+
+else
+# Support for kernel build system invocation
+
+ifneq ($(MODULE_BRANCH), release)
+EXTRA_CFLAGS += -DOMNIBOOK_MODULE_VERSION='"$(MODULE_VERSION)-$(MODULE_BRANCH)"'
+else
+EXTRA_CFLAGS += -DOMNIBOOK_MODULE_VERSION='"$(MODULE_VERSION)"'
+endif
+
+ifeq ($(OMNIBOOK_STANDALONE),y)
+
+ifeq ($(OMNIBOOK_WANT_BACKLIGHT),y)
+ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+# we support backlight interface only after 2.6.16
+ifeq ($(shell if [ $(SUBLEVEL) -gt 16 ] ; then echo -n 'y'; fi),y)
+EXTRA_CFLAGS += -DCONFIG_OMNIBOOK_BACKLIGHT
+else
+$(warning "Backlight support in only supported for kernel version newer than 2.6.16")
+$(warning "Disabling backlight sysfs interface")
+endif
+endif
+endif
+
+ifeq ($(OMNIBOOK_WANT_LEGACY),y)
+EXTRA_CFLAGS += -DCONFIG_OMNIBOOK_LEGACY
+endif
+
+ifndef CONFIG_ACPI_EC
+EXTRA_CFLAGS += -DCONFIG_OMNIBOOK_LEGACY
+endif
+
+ifneq ($(MODULE_BRANCH), release)
+ifneq ($(OMNIBOOK_WANT_DEBUG),n)
+EXTRA_CFLAGS += -DCONFIG_OMNIBOOK_DEBUG # -Wa -g0
+endif
+else
+ifeq ($(OMNIBOOK_WANT_DEBUG),y)
+EXTRA_CFLAGS += -DCONFIG_OMNIBOOK_DEBUG # -Wa -g0
+endif
+
+endif
+
+endif
+
+EXTRA_CFLAGS += -DOMNIBOOK_MODULE_NAME='"$(MODULE_NAME)"'
+#EXTRA_LDFLAGS += $(src)/sections.lds
+EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds
+
+obj-$(CONFIG_OMNIBOOK) += $(MODULE_NAME).o
+omnibook-objs := init.o lib.o ec.o kbc.o pio.o compal.o acpi.o nbsmi.o \
+ ac.o battery.o blank.o bluetooth.o cooling.o display.o dock.o \
+ dump.o fan.o fan_policy.o hotkeys.o info.o lcd.o muteled.o \
+ polling.o temperature.o touchpad.o wireless.o throttling.o
+
+endif # End of kernel build system part
+
+# End of file
diff --git a/ubuntu/omnibook/ac.c b/ubuntu/omnibook/ac.c
new file mode 100644
index 00000000000..3787cdc0ffe
--- /dev/null
+++ b/ubuntu/omnibook/ac.c
@@ -0,0 +1,60 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_ac_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ u8 ac;
+ int retval;
+
+ retval = backend_byte_read(io_op, &ac);
+ if (retval < 0)
+ return retval;
+
+ len += sprintf(buffer + len, "AC %s\n", (!!ac) ? "on-line" : "off-line");
+
+ return len;
+}
+
+static struct omnibook_tbl ac_table[] __initdata = {
+ {XE3GF | TSP10 | TSM30X | TSM70, SIMPLE_BYTE(EC, XE3GF_ADP, XE3GF_ADP_MASK)},
+ {XE3GC | AMILOD, SIMPLE_BYTE(EC, XE3GC_STA1, XE3GC_ADP_MASK)},
+ {OB500 | OB510 | OB6000 | OB6100 | XE4500, SIMPLE_BYTE(EC, OB500_STA2, OB500_ADP_MASK)},
+ {OB4150, SIMPLE_BYTE(EC, OB4150_ADP, OB4150_ADP_MASK)},
+ {XE2, SIMPLE_BYTE(EC, XE2_STA1, XE2_ADP_MASK)},
+ {0,}
+};
+
+struct omnibook_feature __declared_feature ac_driver = {
+ .name = "ac",
+#ifdef CONFIG_OMNIBOOK_LEGACY
+ .enabled = 1,
+#else
+ .enabled = 0,
+#endif
+ .read = omnibook_ac_read,
+ .ectypes = XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | OB4150 | XE2 | AMILOD | TSP10 | TSM70 | TSM30X,
+ .tbl = ac_table,
+};
+
+module_param_named(ac, ac_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(ac, "Use 0 to disable, 1 to enable AC adapter status monitoring");
+
+/* End of file */
diff --git a/ubuntu/omnibook/acpi.c b/ubuntu/omnibook/acpi.c
new file mode 100644
index 00000000000..7c6a86573bb
--- /dev/null
+++ b/ubuntu/omnibook/acpi.c
@@ -0,0 +1,1158 @@
+/*
+ * acpi.c -- ACPI methods low-level access code for TSM70 class laptops
+ *
+ * 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ *
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+#ifdef CONFIG_ACPI
+
+#include <acpi/acpi_drivers.h>
+#include <linux/workqueue.h>
+
+/* copied from drivers/input/serio/i8042-io.h */
+#define I8042_KBD_PHYS_DESC "isa0060/serio0"
+
+/*
+ * ACPI backend masks and strings
+ */
+
+#define GET_WIRELESS_METHOD "ANTR"
+#define SET_WIRELESS_METHOD "ANTW"
+#define WLEX_MASK 0x4
+#define WLAT_MASK 0x1
+#define BTEX_MASK 0x8
+#define BTAT_MASK 0x2
+#define KLSW_MASK 0x10
+
+#define GET_DISPLAY_METHOD "DOSS"
+#define SET_DISPLAY_METHOD "DOSW"
+/* Display reading masks CADL = detected, CSTE = enabled */
+#define LCD_CADL 0x10
+#define CRT_CADL 0x20
+#define TVO_CADL 0x40
+#define DVI_CADL 0x80
+#define LCD_CSTE 0x1
+#define CRT_CSTE 0x2
+#define TVO_CSTE 0x4
+#define DVI_CSTE 0x8
+
+/* TSX205 Video-Out methods and return values */
+#define TSX205_SET_DISPLAY_METHOD "STBL"
+#define TSX205_SLI_DISPLAY_METHOD "SL01.VGA1.STBL"
+/* NOTE: Method DSSW seems to be some sort of auto-detect method */
+#define TSX205_AUTO_DISPLAY_METHOD "DSSW"
+#define TSX205_DSPY_DE 0x1F /* DE - Detected and Enabled */
+#define TSX205_DSPY_DN 0x1D /* DN - Detected and Not enabled */
+#define TSX205_DSPY_NE 0x0F /* NE - Not detected and Enabled */
+#define TSX205_DSPY_NN 0x0D /* NN - Not detected and Not enabled */
+
+#define GET_THROTTLE_METHOD "THRO"
+#define SET_THROTTLE_METHOD "CLCK"
+
+static char ec_dev_list[][20] = {
+ "\\_SB.PCI0.LPCB.EC0",
+ "\\_SB.PCI0.LPC0.EC0",
+};
+
+/* TSX205 HCI and display handles */
+static char tsx205_dev_list[][20] = {
+ "\\_SB.VALZ",
+ "\\_SB.PCI0.PEGP.VGA"
+};
+
+/* TSX205 GET video-out methods */
+static char tsx205_video_list[][20] = {
+ "LCD._DCS",
+ "CRT._DCS",
+ "TV._DCS",
+ "DVI._DCS",
+ "SL01.VGA1.LCD._DCS",
+ "SL01.VGA1.CRT._DCS",
+ "SL01.VGA1.TV._DCS",
+ "SL01.VGA1.DVI._DCS",
+};
+
+#define TOSHIBA_ACPI_BT_CLASS "bluetooth"
+#define TOSHIBA_ACPI_DEVICE_NAME "bluetooth adapter"
+
+#define TOSH_BT_ACTIVATE_USB "AUSB"
+#define TOSH_BT_DISABLE_USB "DUSB"
+#define TOSH_BT_POWER_ON "BTPO"
+#define TOSH_BT_POWER_OFF "BTPF"
+#define TOSH_BT_STATUS "BTST"
+#define TOSH_BT_KSST_MASK 0x1
+#define TOSH_BT_USB_MASK 0x40
+#define TOSH_BT_POWER_MASK 0x80
+
+/*
+ * ACPI driver for Toshiba Bluetooth device
+ */
+static int omnibook_acpi_bt_add(struct acpi_device *device);
+static int omnibook_acpi_bt_remove(struct acpi_device *device, int type);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+static const struct acpi_device_id omnibook_bt_ids[] = {
+ {"TOS6205", 0},
+ {"", 0},
+};
+
+static struct acpi_driver omnibook_bt_driver = {
+ .name = OMNIBOOK_MODULE_NAME,
+ .class = TOSHIBA_ACPI_BT_CLASS,
+ .ids = omnibook_bt_ids,
+ .ops = {
+ .add = omnibook_acpi_bt_add,
+ .remove = omnibook_acpi_bt_remove,
+ },
+};
+#else /* 2.6.23 */
+static struct acpi_driver omnibook_bt_driver = {
+ .name = OMNIBOOK_MODULE_NAME,
+ .class = TOSHIBA_ACPI_BT_CLASS,
+ .ids = "TOS6205",
+ .ops = {
+ .add = omnibook_acpi_bt_add,
+ .remove = omnibook_acpi_bt_remove,
+ },
+};
+#endif /* 2.6.23 */
+
+
+/*
+ * ACPI backend private data structure
+ */
+struct acpi_backend_data {
+ acpi_handle ec_handle; /* Handle on ACPI EC device */
+ acpi_handle bt_handle; /* Handle on ACPI BT device */
+ acpi_handle hci_handle; /* Handle on ACPI HCI device */
+ acpi_handle dis_handle; /* Handle on ACPI Display device */
+ unsigned has_antr_antw:1; /* Are there ANTR/ANTW methods in the EC device ? */
+ unsigned has_doss_dosw:1; /* Are there DOSS/DOSW methods in the EC device ? */
+ unsigned has_sli:1; /* Does the laptop has SLI enabled ? */
+ struct input_dev *acpi_input_dev;
+ struct work_struct fnkey_work;
+};
+
+/*
+ * Hotkeys workflow:
+ * 1. Fn+Foo pressed
+ * 2. Scancode 0x6e generated by kbd controller
+ * 3. Scancode 0x6e caught by omnibook input handler
+ * 4. INFO method has keycode of last actually pressed Fn key
+ * 5. acpi_scan_table used to associate a detected keycode with a generated one
+ * 6. Generated keycode issued using the omnibook input device
+ */
+
+/*
+ * The input handler should only bind with the standard AT keyboard.
+ * XXX: Scancode 0x6e won't be detected if the keyboard has already been
+ * grabbed (the Xorg event input driver do that)
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+static int hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#else
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ struct input_device_id *id)
+#endif
+{
+ struct input_handle *handle;
+ int error;
+
+ /* the 0x0001 vendor magic number is found in atkbd.c */
+ if(!(dev->id.bustype == BUS_I8042 && dev->id.vendor == 0x0001))
+ goto out_nobind;
+
+ if(!strstr(dev->phys, I8042_KBD_PHYS_DESC))
+ goto out_nobind;
+
+ dprintk("hook_connect for device %s.\n", dev->name);
+
+ if(dev->grab)
+ printk(O_WARN "Input device is grabbed by %s, Fn hotkeys won't work.\n",
+ dev->grab->name);
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return -ENOMEM;
+#else
+ return NULL;
+#endif
+
+ handle->dev = dev;
+ handle->handler = handler;
+ handle->name = "omnibook_scancode_hook";
+ handle->private = handler->private;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ error = input_register_handle(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ goto out_nobind_free;
+ }
+ error = input_open_device(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ input_unregister_handle(handle);
+ goto out_nobind_free;
+ }
+
+#else
+ status=input_open_device(handle);
+ if (error==0) dprintk("Input device opened\n");
+ else {
+ dprintk("opening input device failed\n");
+ goto out_nobind_free;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return 0;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return -ENODEV;
+#else
+ return handle;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return NULL;
+#endif
+}
+
+static void hook_disconnect(struct input_handle *handle)
+{
+ dprintk("hook_disconnect.\n");
+ input_close_device(handle);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ input_unregister_handle(handle);
+#endif
+ kfree(handle);
+}
+
+/*
+ * Hook for scancode 0x6e. Actual handling is done in a workqueue.
+ */
+static void hook_event(struct input_handle *handle, unsigned int event_type,
+ unsigned int event_code, int value)
+{
+ if (event_type == EV_MSC && event_code == MSC_SCAN && value == ACPI_FN_SCAN)
+ schedule_work(&((struct acpi_backend_data *)handle->private)->fnkey_work);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static const struct input_device_id hook_ids[] = {
+#else
+static struct input_device_id hook_ids[] = {
+#endif
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT(EV_KEY) },
+ },
+ { }, /* Terminating entry */
+};
+
+static struct input_handler hook_handler = {
+ .event = hook_event,
+ .connect = hook_connect,
+ .disconnect = hook_disconnect,
+ .name = OMNIBOOK_MODULE_NAME,
+ .id_table = hook_ids,
+};
+
+/*
+ * Detected scancode to keycode table
+ */
+static const struct {
+ unsigned int scancode;
+ unsigned int keycode;
+} acpi_scan_table[] = {
+ { HCI_FN_RELEASED, KEY_FN},
+ { HCI_MUTE, KEY_MUTE},
+ { HCI_BREAK, KEY_COFFEE},
+ { HCI_1, KEY_ZOOMOUT},
+ { HCI_2, KEY_ZOOMIN},
+ { HCI_SPACE, KEY_ZOOMRESET},
+ { HCI_BSM, KEY_BATTERY},
+ { HCI_SUSPEND, KEY_SLEEP},
+ { HCI_HIBERNATE, KEY_SUSPEND},
+ { HCI_VIDEOOUT, KEY_SWITCHVIDEOMODE},
+ { HCI_BRIGHTNESSDOWN, KEY_BRIGHTNESSDOWN},
+ { HCI_BRIGHTNESSUP, KEY_BRIGHTNESSUP},
+ { HCI_WLAN, KEY_WLAN},
+ { HCI_TOUCHPAD, KEY_PROG1},
+ { HCI_FN_PRESSED, KEY_FN},
+ { 0, 0},
+};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work);
+#else
+static void omnibook_handle_fnkey(void* data);
+#endif
+
+/*
+ * Register the input handler and the input device in the input subsystem
+ */
+static int register_input_subsystem(struct acpi_backend_data *priv_data)
+{
+ int i, retval = 0;
+ struct input_dev *acpi_input_dev;
+
+ acpi_input_dev = input_allocate_device();
+ if (!acpi_input_dev) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ acpi_input_dev->name = "Omnibook ACPI scancode generator";
+ acpi_input_dev->phys = "omnibook/input0";
+ acpi_input_dev->id.bustype = BUS_HOST;
+
+ set_bit(EV_KEY, acpi_input_dev->evbit);
+
+ for(i=0 ; i < ARRAY_SIZE(acpi_scan_table); i++)
+ set_bit(acpi_scan_table[i].keycode, acpi_input_dev->keybit);
+
+ retval = input_register_device(acpi_input_dev);
+ if (retval) {
+ input_free_device(acpi_input_dev);
+ goto out;
+ }
+
+ priv_data->acpi_input_dev = acpi_input_dev;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey);
+#else
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey, priv_data);
+#endif
+
+
+ hook_handler.private = priv_data;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+ retval = input_register_handler(&hook_handler);
+#else
+ input_register_handler(&hook_handler);
+#endif
+
+ out:
+ return retval;
+}
+
+/*
+ * Execute an ACPI method which return either an integer or nothing
+ * and that require 0 or 1 numerical argument
+ * (acpi_evaluate_object wrapper)
+ */
+static int omnibook_acpi_execute(acpi_handle dev_handle, char *method, const int *param, int *result)
+{
+
+ struct acpi_object_list args_list;
+ struct acpi_buffer buff;
+ union acpi_object arg, out_objs[1];
+
+ if (param) {
+ args_list.count = 1;
+ args_list.pointer = &arg;
+ arg.type = ACPI_TYPE_INTEGER;
+ arg.integer.value = *param;
+ } else
+ args_list.count = 0;
+
+ buff.length = sizeof(out_objs);
+ buff.pointer = out_objs;
+
+ if (acpi_evaluate_object(dev_handle, method, &args_list, &buff) != AE_OK) {
+ printk(O_ERR "ACPI method execution failed\n");
+ return -EIO;
+ }
+
+ if (!result) /* We don't care what the method returned here */
+ return 0;
+
+ if (out_objs[0].type != ACPI_TYPE_INTEGER) {
+ printk(O_ERR "ACPI method result is not a number\n");
+ return -EINVAL;
+ }
+
+ *result = out_objs[0].integer.value;
+ return 0;
+}
+
+/*
+ * Probe for expected ACPI devices
+ */
+static int omnibook_acpi_init(const struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ acpi_handle dev_handle, method_handle, hci_handle, dis_handle;
+ int i;
+ int has_sli = 0;
+ struct acpi_backend_data *priv_data;
+
+ if (unlikely(acpi_disabled)) {
+ printk(O_ERR "ACPI is disabled: feature unavailable.\n");
+ return -ENODEV;
+ }
+
+ if (!io_op->backend->data) {
+ dprintk("Try to init ACPI backend\n");
+ mutex_init(&io_op->backend->mutex);
+ mutex_lock(&io_op->backend->mutex);
+ kref_init(&io_op->backend->kref);
+ priv_data = kzalloc(sizeof(struct acpi_backend_data), GFP_KERNEL);
+ if (!priv_data) {
+ retval = -ENOMEM;
+ goto error0;
+ }
+
+ /* Locate ACPI EC device, acpi_get_handle set dev_handle to NULL if not found */
+ for (i = 0; i < ARRAY_SIZE(ec_dev_list); i++) {
+ if (acpi_get_handle(NULL, ec_dev_list[i], &dev_handle) == AE_OK) {
+ dprintk("ACPI EC device found\n");
+ priv_data->ec_handle = dev_handle;
+ break;
+ }
+ }
+
+ if (!dev_handle) {
+ printk(O_ERR "Can't get handle on ACPI EC device.\n");
+ retval = -ENODEV;
+ goto error1;
+ }
+
+ /* Probe for HCI and Display devices only on TSX205 models */
+ if (omnibook_ectype & TSX205) {
+ if (acpi_get_handle(NULL, tsx205_dev_list[0], &hci_handle) == AE_OK) {
+ dprintk("Toshiba X205 HCI device found\n");
+ priv_data->hci_handle = hci_handle;
+ }
+
+ if (!hci_handle) {
+ printk(O_ERR "Couldn't get HCI handle.\n");
+ retval = -ENODEV;
+ goto error1;
+ }
+
+ if (acpi_get_handle(NULL, tsx205_dev_list[1], &dis_handle) == AE_OK)
+ priv_data->dis_handle = dis_handle;
+
+ if (!dis_handle) {
+ printk(O_ERR "Couldn't get X205 Display handle.\n");
+ retval = -ENODEV;
+ goto error1;
+ }
+
+ /* Does the laptop has SLI enabled? */
+ omnibook_acpi_execute(dis_handle, (char *)TSX205_SLIVDO_METHOD, NULL, &has_sli);
+ if (has_sli)
+ dprintk("Toshiba X205 Display device found (SLI).\n");
+ else
+ dprintk("Toshiba X205 Display device found.\n");
+
+ priv_data->has_sli = has_sli;
+ }
+
+ if ((acpi_get_handle( dev_handle, GET_WIRELESS_METHOD, &method_handle) == AE_OK) &&
+ (acpi_get_handle( dev_handle, SET_WIRELESS_METHOD, &method_handle) == AE_OK))
+ priv_data->has_antr_antw = 1;
+
+ if (omnibook_ectype & TSX205) {
+ if ((acpi_get_handle(dis_handle, TSX205_AUTO_DISPLAY_METHOD, &method_handle) == AE_OK) &&
+ (acpi_get_handle(dis_handle, TSX205_AUTO_DISPLAY_METHOD, &method_handle) == AE_OK))
+ priv_data->has_doss_dosw = 1;
+ } else {
+ if ((acpi_get_handle( dev_handle, GET_DISPLAY_METHOD, &method_handle) == AE_OK) &&
+ (acpi_get_handle( dev_handle, SET_DISPLAY_METHOD, &method_handle) == AE_OK))
+ priv_data->has_doss_dosw = 1;
+ }
+
+ retval = register_input_subsystem(priv_data);
+ if(retval)
+ goto error1;
+
+ io_op->backend->data = (void *) priv_data;
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ /* attempt to register Toshiba bluetooth ACPI driver */
+ acpi_bus_register_driver(&omnibook_bt_driver);
+
+ dprintk("ACPI backend init OK\n");
+
+ return 0;
+
+ } else {
+ dprintk("ACPI backend has already been initialized\n");
+ kref_get(&io_op->backend->kref);
+ return 0;
+ }
+
+ error1:
+ kfree(priv_data);
+ io_op->backend->data = NULL;
+ error0:
+ mutex_unlock(&io_op->backend->mutex);
+ mutex_destroy(&io_op->backend->mutex);
+ return retval;
+}
+
+static void omnibook_acpi_free(struct kref *ref)
+{
+ struct omnibook_backend *backend;
+ struct acpi_backend_data *priv_data;
+
+ backend = container_of(ref, struct omnibook_backend, kref);
+ priv_data = backend->data;
+
+ dprintk("ACPI backend not used anymore: disposing\n");
+
+
+ dprintk("ptr addr: %p driver name: %s\n",&omnibook_bt_driver, omnibook_bt_driver.name);
+ acpi_bus_unregister_driver(&omnibook_bt_driver);
+
+ flush_scheduled_work();
+ input_unregister_handler(&hook_handler);
+ input_unregister_device(priv_data->acpi_input_dev);
+
+ mutex_lock(&backend->mutex);
+ kfree(backend->data);
+ backend->data = NULL;
+ mutex_unlock(&backend->mutex);
+ mutex_destroy(&backend->mutex);
+}
+
+static void omnibook_acpi_exit(const struct omnibook_operation *io_op)
+{
+ dprintk("Trying to dispose ACPI backend\n");
+ kref_put(&io_op->backend->kref, omnibook_acpi_free);
+}
+
+/* forward declaration */
+struct omnibook_backend acpi_backend;
+
+/* Function taken from toshiba_acpi */
+static acpi_status hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS])
+{
+ struct acpi_backend_data *priv_data = acpi_backend.data;
+ struct acpi_object_list params;
+ union acpi_object in_objs[HCI_WORDS];
+ struct acpi_buffer results;
+ union acpi_object out_objs[HCI_WORDS + 1];
+ acpi_status status;
+ int i;
+
+ params.count = HCI_WORDS;
+ params.pointer = in_objs;
+ for (i = 0; i < HCI_WORDS; ++i) {
+ in_objs[i].type = ACPI_TYPE_INTEGER;
+ in_objs[i].integer.value = in[i];
+ }
+
+ results.length = sizeof(out_objs);
+ results.pointer = out_objs;
+
+ status = acpi_evaluate_object(priv_data->hci_handle, (char *)HCI_METHOD, &params,
+ &results);
+ if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) {
+ for (i = 0; i < out_objs->package.count; ++i) {
+ out[i] = out_objs->package.elements[i].integer.value;
+ }
+ }
+
+ return status;
+}
+
+/*
+ * Set Bluetooth device state using the Toshiba BT device
+ */
+static int set_bt_status(const struct acpi_backend_data *priv_data, unsigned int state)
+{
+ int retval = 0;
+
+ if (state) {
+ retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_ACTIVATE_USB, NULL, NULL);
+ if (retval)
+ goto out;
+ retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_POWER_ON, NULL, NULL);
+ if (retval)
+ goto out;
+ } else {
+ retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_DISABLE_USB, NULL, NULL);
+ if (retval)
+ goto out;
+ retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_POWER_OFF, NULL, NULL);
+ if (retval)
+ goto out;
+ }
+ out:
+ return retval;
+}
+
+static int omnibook_acpi_bt_add(struct acpi_device *device)
+{
+ int retval;
+ struct acpi_backend_data *priv_data = acpi_backend.data;
+
+ dprintk("Enabling Toshiba Bluetooth ACPI device.\n");
+ strcpy(acpi_device_name(device), TOSHIBA_ACPI_DEVICE_NAME);
+ strcpy(acpi_device_class(device), TOSHIBA_ACPI_BT_CLASS);
+
+ /* Save handle in backend private data structure. ugly. */
+
+ mutex_lock(&acpi_backend.mutex);
+ priv_data->bt_handle = device->handle;
+ retval = set_bt_status(priv_data, 1);
+ mutex_unlock(&acpi_backend.mutex);
+
+ return retval;
+}
+
+static int omnibook_acpi_bt_remove(struct acpi_device *device, int type)
+{
+ int retval;
+ struct acpi_backend_data *priv_data = acpi_backend.data;
+
+ mutex_lock(&acpi_backend.mutex);
+ dprintk("Disabling Toshiba Bluetooth ACPI device.\n");
+ retval = set_bt_status(priv_data, 0);
+ priv_data->bt_handle = NULL;
+ mutex_unlock(&acpi_backend.mutex);
+
+ return retval;
+}
+
+/*
+ * Get Bluetooth status using the BTST method
+ */
+static int get_bt_status(const struct acpi_backend_data *priv_data, unsigned int *state)
+{
+ int retval = 0;
+ int raw_state;
+
+ if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, NULL, &raw_state)))
+ return retval;
+
+ dprintk("BTST raw_state: %x\n", raw_state);
+
+ *state = BT_EX;
+ *state |= ((raw_state & TOSH_BT_USB_MASK) && (raw_state & TOSH_BT_POWER_MASK)) ? BT_STA : 0;
+
+ return retval;
+}
+
+/*
+ * Get the Bluetooth + Wireless status using the ANTR method
+ * FIXME: what if ANTR and BTST disagree ? we thrust ANTR for now
+ */
+static int get_wireless_status(const struct acpi_backend_data *priv_data, unsigned int *state)
+{
+ int retval = 0;
+ int raw_state;
+
+ if ((retval = omnibook_acpi_execute(priv_data->ec_handle, GET_WIRELESS_METHOD, NULL, &raw_state)))
+ return retval;
+
+ dprintk("get_wireless raw_state: %x\n", raw_state);
+
+ *state = (raw_state & WLEX_MASK) ? WIFI_EX : 0;
+ *state |= (raw_state & WLAT_MASK) ? WIFI_STA : 0;
+ *state |= (raw_state & KLSW_MASK) ? KILLSWITCH : 0;
+ *state |= (raw_state & BTEX_MASK) ? BT_EX : 0;
+ *state |= (raw_state & BTAT_MASK) ? BT_STA : 0;
+
+ return retval;
+}
+
+static int get_tsx205_wireless_status(const struct acpi_backend_data *priv_data, unsigned int *state)
+{
+ int retval = 0;
+ int raw_state;
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_RF_CONTROL, 0, HCI_WIRELESS_CHECK, 0, 0 };
+ u32 out[HCI_WORDS];
+
+ hci_raw(in, out);
+
+ /* Now let's check the killswitch */
+ if ((retval = omnibook_acpi_execute(priv_data->ec_handle, TSX205_KILLSW_METHOD, NULL, &raw_state)))
+ return retval;
+
+ dprintk("get_wireless raw_state: %x\n", out[2]);
+
+ *state = ((out[2] & 0xff)) ? WIFI_EX : 0;
+ *state |= (raw_state) ? WIFI_STA : 0;
+ *state |= (!raw_state) ? KILLSWITCH : 0;
+
+ /* And finally BT */
+ if ((retval = omnibook_acpi_execute(priv_data->bt_handle, TOSH_BT_STATUS, NULL, &raw_state)))
+ return retval;
+
+ *state |= BT_EX;
+ *state |= ((raw_state & TOSH_BT_USB_MASK) && (raw_state & TOSH_BT_POWER_MASK)) ? BT_STA : 0;
+
+ return retval;
+}
+
+static int omnibook_acpi_get_wireless(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval;
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+
+ /* use BTST (BT device) if we don't have ANTR/ANTW (EC device) */
+ if (omnibook_ectype & TSX205)
+ retval = get_tsx205_wireless_status(priv_data, state);
+ else if (priv_data->has_antr_antw)
+ retval = get_wireless_status(priv_data, state);
+ else if(priv_data->bt_handle)
+ retval = get_bt_status(priv_data, state);
+ else
+ retval = -ENODEV;
+
+ return retval;
+}
+
+/*
+ * Set the Bluetooth + Wireless status using the ANTW method
+ */
+static int set_wireless_status(const struct acpi_backend_data *priv_data, unsigned int state)
+{
+ int retval;
+ int raw_state;
+
+ raw_state = !!(state & WIFI_STA); /* bit 0 */
+ raw_state |= !!(state & BT_STA) << 0x1; /* bit 1 */
+
+ dprintk("set_wireless raw_state: %x\n", raw_state);
+
+ retval = omnibook_acpi_execute(priv_data->ec_handle, SET_WIRELESS_METHOD, &raw_state, NULL);
+
+ return retval;
+}
+
+static int set_tsx205_wireless_status(const struct acpi_backend_data *priv_data, unsigned int state)
+{
+ int retval;
+ int raw_state = !!(state & WIFI_STA);
+
+ dprintk("set_wireless raw_state: %x\n", raw_state);
+
+ u32 in[HCI_WORDS] = { HCI_SET, HCI_RF_CONTROL, raw_state, HCI_WIRELESS_POWER, 0, 0 };
+ u32 out[HCI_WORDS];
+ hci_raw(in, out);
+
+ raw_state |= !!(state & BT_STA) << 0x1; /* bit 1 */
+
+ /* BT status */
+ retval = set_bt_status(priv_data->bt_handle, state);
+
+ return retval;
+}
+
+static int omnibook_acpi_set_wireless(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval = -ENODEV;
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+
+ /* First try the TSX205 methods */
+ if(omnibook_ectype & TSX205)
+ retval = set_tsx205_wireless_status(priv_data, state);
+
+ /* Then try the ANTR/ANTW methods */
+ if(priv_data->has_antr_antw)
+ retval = set_wireless_status(priv_data, state);
+
+ /* Then try the bluetooth ACPI device if present */
+ if(priv_data->bt_handle)
+ retval = set_bt_status(priv_data, (state & BT_STA));
+
+ return retval;
+}
+
+static int tsx205_get_display(const struct acpi_backend_data *priv_data, unsigned int *state, unsigned int device)
+{
+ int retval = 0;
+ int raw_state = 0;
+
+ retval = omnibook_acpi_execute(priv_data->dis_handle, tsx205_video_list[device], NULL, &raw_state);
+ if (retval < 0) {
+ dprintk(O_ERR "Failed to get video device (%d) state.\n", device);
+ return retval;
+ }
+
+ /* Ugly, but better than nothing... */
+ switch (device) {
+ case 0:
+ case 4: /* LCD device */
+ dprintk("get_display LCD (%d) raw_state: %x\n", device, raw_state);
+ if (raw_state == TSX205_DSPY_DE) {
+ *state |= DISPLAY_LCD_DET;
+ *state |= DISPLAY_LCD_ON;
+ } else
+ if (raw_state == TSX205_DSPY_DN)
+ *state |= DISPLAY_LCD_DET;
+ else if (raw_state == TSX205_DSPY_NE)
+ *state |= DISPLAY_LCD_ON;
+ break;
+ case 1:
+ case 5: /* CRT device */
+ dprintk("get_display CRT (%d) raw_state: %x\n", device, raw_state);
+ if (raw_state == TSX205_DSPY_DE) {
+ *state |= DISPLAY_CRT_DET;
+ *state |= DISPLAY_CRT_ON;
+ } else
+ if (raw_state == TSX205_DSPY_DN)
+ *state |= DISPLAY_CRT_DET;
+ else if (raw_state == TSX205_DSPY_NE)
+ *state |= DISPLAY_CRT_ON;
+ break;
+ case 2:
+ case 6: /* TV-OUT device */
+ dprintk("get_display TV-OUT (%d) raw_state: %x\n", device, raw_state);
+ if (raw_state == TSX205_DSPY_DE) {
+ *state |= DISPLAY_TVO_DET;
+ *state |= DISPLAY_TVO_ON;
+ } else
+ if (raw_state == TSX205_DSPY_DN)
+ *state |= DISPLAY_TVO_DET;
+ else if (raw_state == TSX205_DSPY_NE)
+ *state |= DISPLAY_TVO_ON;
+ break;
+ case 3:
+ case 7: /* DVI device */
+ dprintk("get_display DVI (%d) raw_state: %x\n", device, raw_state);
+ if (raw_state == TSX205_DSPY_DE) {
+ *state |= DISPLAY_DVI_DET;
+ *state |= DISPLAY_DVI_ON;
+ } else
+ if (raw_state == TSX205_DSPY_DN)
+ *state |= DISPLAY_DVI_DET;
+ else if (raw_state == TSX205_DSPY_NE)
+ *state |= DISPLAY_DVI_ON;
+ break;
+ }
+
+ return retval;
+}
+
+static int omnibook_acpi_get_display(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval = 0;
+ int raw_state = 0;
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+
+ if(!priv_data->has_doss_dosw)
+ return -ENODEV;
+
+ if (omnibook_ectype & TSX205) {
+ int i;
+
+ /* Loop 'tru the different Video-Out devices */
+ if (priv_data->has_sli)
+ for (i = 4; i < ARRAY_SIZE(tsx205_video_list); i++)
+ retval = tsx205_get_display(priv_data, state, i);
+ else
+ for (i = 0; i < 4; i++)
+ retval = tsx205_get_display(priv_data, state, i);
+
+ if (retval < 0)
+ return -EIO;
+
+ goto vidout;
+ }
+
+ retval = omnibook_acpi_execute(priv_data->ec_handle, GET_DISPLAY_METHOD, NULL, &raw_state);
+ if (retval < 0)
+ return retval;
+
+ dprintk("get_display raw_state: %x\n", raw_state);
+
+ /* Backend specific to backend-neutral conversion */
+ *state = (raw_state & LCD_CSTE) ? DISPLAY_LCD_ON : 0;
+ *state |= (raw_state & CRT_CSTE) ? DISPLAY_CRT_ON : 0;
+ *state |= (raw_state & TVO_CSTE) ? DISPLAY_TVO_ON : 0;
+ *state |= (raw_state & DVI_CSTE) ? DISPLAY_DVI_ON : 0;
+
+ *state |= (raw_state & LCD_CADL) ? DISPLAY_LCD_DET : 0;
+ *state |= (raw_state & CRT_CADL) ? DISPLAY_CRT_DET : 0;
+ *state |= (raw_state & TVO_CADL) ? DISPLAY_TVO_DET : 0;
+ *state |= (raw_state & DVI_CADL) ? DISPLAY_DVI_DET : 0;
+
+vidout:
+ return DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON | DISPLAY_DVI_ON
+ | DISPLAY_LCD_DET | DISPLAY_CRT_DET | DISPLAY_TVO_DET | DISPLAY_DVI_DET;
+}
+
+static const unsigned int acpi_display_mode_list[] = {
+ DISPLAY_LCD_ON,
+ DISPLAY_CRT_ON,
+ DISPLAY_LCD_ON | DISPLAY_CRT_ON,
+ DISPLAY_TVO_ON,
+ DISPLAY_LCD_ON | DISPLAY_TVO_ON,
+ DISPLAY_CRT_ON | DISPLAY_TVO_ON,
+ DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON,
+ DISPLAY_DVI_ON,
+ DISPLAY_LCD_ON | DISPLAY_DVI_ON,
+};
+
+static int omnibook_acpi_set_display(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval = 0;
+ int i;
+ int matched = -1;
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+
+ if(!priv_data->has_doss_dosw)
+ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(acpi_display_mode_list); i++) {
+ if (acpi_display_mode_list[i] == state) {
+ matched = i + 1; /* raw state is array row number + 1 */
+ break;
+ }
+ }
+ if (matched == -1) {
+ printk("Display mode %x is unsupported.\n", state);
+ return -EINVAL;
+ }
+
+ dprintk("set_display raw_state: %x\n", matched);
+
+ if (omnibook_ectype & TSX205) {
+ if (priv_data->has_sli)
+ retval = omnibook_acpi_execute(priv_data->dis_handle, TSX205_SLI_DISPLAY_METHOD, &matched, NULL);
+ else
+ retval = omnibook_acpi_execute(priv_data->dis_handle, TSX205_SET_DISPLAY_METHOD, &matched, NULL);
+ } else
+ retval = omnibook_acpi_execute(priv_data->ec_handle, SET_DISPLAY_METHOD, &matched, NULL);
+ if (retval < 0)
+ return retval;
+
+ return DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON | DISPLAY_DVI_ON;
+}
+
+static int omnibook_acpi_get_throttle(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval;
+ int thtl_en = 0, thtl_dty = 0;
+ int param;
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+
+ param = 0;
+ /* Read THEN aka THTL_EN in ICH6M datasheets */
+ retval = omnibook_acpi_execute(priv_data->ec_handle, GET_THROTTLE_METHOD, &param, &thtl_en);
+ if ( thtl_en == 0 ) {
+ *state = 0;
+ return retval;
+ }
+ param = 1;
+ /* Read DUTY aka THTL_DTY in ICH6M datasheets */
+ retval = omnibook_acpi_execute(priv_data->ec_handle, GET_THROTTLE_METHOD, &param, &thtl_dty);
+ WARN_ON(thtl_dty > 7); /* We shouldn't encounter more than 7 throttling level */
+ *state = 8 - thtl_dty; /* THTL_DTY and ACPI T-state are reverse mapped */
+ return retval;
+}
+
+static int omnibook_acpi_set_throttle(const struct omnibook_operation *io_op, unsigned int state)
+{
+ struct acpi_backend_data *priv_data = io_op->backend->data;
+ /* THTL_DTY and ACPI T-state are reverse mapped */
+ /* throttling.c already clamped state between 0 and 7 */
+ if (state)
+ state = 8 - state;
+
+ return omnibook_acpi_execute(priv_data->ec_handle, SET_THROTTLE_METHOD, &state, NULL);
+}
+
+/*
+ * Fn+foo hotkeys handling
+ */
+static int omnibook_hci_get_hotkeys(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ u32 in[HCI_WORDS] = { HCI_GET, HCI_HOTKEY_EVENT, 0, 0, 0, 0 };
+ u32 out[HCI_WORDS];
+ acpi_status status = hci_raw(in, out);
+
+ if (status != AE_OK)
+ return HCI_FAILURE;
+
+ dprintk("get_hotkeys raw_state: %x\n", out[2]);
+
+ *state = (out[2] & ACPI_FN_MASK) ? HKEY_FN : 0;
+
+ return 0;
+}
+
+static int omnibook_hci_set_hotkeys(const struct omnibook_operation *io_op, unsigned int state)
+{
+ u32 in[HCI_WORDS] = { 0, 0, 0, 0, 0, 0 };
+ u32 out[HCI_WORDS];
+ in[0] = HCI_SET;
+ in[1] = HCI_HOTKEY_EVENT;
+ in[2] = (state & HKEY_FN) ? 1 : 0;
+ acpi_status status = hci_raw(in, out);
+
+ dprintk("set_hotkeys (Fn interface) raw_state: %x\n", in[2]);
+
+ return (status == AE_OK) ? out[0] : HCI_FAILURE;
+}
+
+static int omnibook_acpi_get_events(unsigned int *state)
+{
+ acpi_status status;
+ struct acpi_backend_data *priv_data = acpi_backend.data;
+
+ /* We need to call the NTFY method first so it can activate the TECF variable */
+ status = omnibook_acpi_execute(priv_data->ec_handle, TSX205_NOTIFY_METHOD, NULL, NULL);
+ if (status != AE_OK) {
+ dprintk(O_ERR "Failed to activate NTFY method.\n");
+ return -EIO;
+ }
+
+ /* Now we can poll the INFO method to get last pressed hotkey */
+ status = omnibook_acpi_execute(priv_data->hci_handle, TSX205_EVENTS_METHOD, NULL, state);
+ if (status != AE_OK) {
+ dprintk(O_ERR "Failed to get Hotkey event.\n");
+ return -EIO;
+ }
+
+ /* We only care about a key press, so just report the Fn key Press/Release */
+ if ( ((*state & ~0x80) == 0x100) || ((*state & ~0x80) == 0x17f) )
+ *state &= ~0x80;
+
+ return status;
+}
+
+/*
+ * Adjust the lcd backlight level by delta.
+ * Used for Fn+F6/F7 keypress
+ */
+static int adjust_brighness(int delta)
+{
+ struct omnibook_feature *lcd_feature = omnibook_find_feature("lcd");
+ struct omnibook_operation *io_op;
+ int retval = 0;
+ u8 brgt;
+
+ if(!lcd_feature)
+ return -ENODEV;
+
+ io_op = lcd_feature->io_op;
+
+ mutex_lock(&io_op->backend->mutex);
+
+ if(( retval = __backend_byte_read(io_op, &brgt)))
+ goto out;
+
+ dprintk("Fn-F6/F7 pressed: adjusting brightness.\n");
+
+ if (((int) brgt + delta) < 0)
+ brgt = 0;
+ else if ((brgt + delta) > omnibook_max_brightness)
+ brgt = omnibook_max_brightness;
+ else
+ brgt += delta;
+
+ retval = __backend_byte_write(io_op, brgt);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Workqueue handler for Fn hotkeys
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work)
+#else
+static void omnibook_handle_fnkey(void* data)
+#endif
+{
+ int i;
+ u32 gen_scan;
+ struct input_dev *input_dev;
+ acpi_status status;
+
+ status = omnibook_acpi_get_events(&gen_scan);
+ if (status != AE_OK)
+ return;
+
+ dprintk("detected scancode 0x%x.\n", gen_scan);
+ switch(gen_scan) {
+ case HCI_BRIGHTNESSDOWN:
+ adjust_brighness(-1);
+ break;
+ case HCI_BRIGHTNESSUP:
+ adjust_brighness(+1);
+ break;
+ }
+
+ for (i = 0 ; i < ARRAY_SIZE(acpi_scan_table); i++) {
+ if (gen_scan == acpi_scan_table[i].scancode) {
+ dprintk("generating keycode %i.\n", acpi_scan_table[i].keycode);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ input_dev = container_of(work, struct acpi_backend_data, fnkey_work)->acpi_input_dev;
+#else
+ input_dev = ((struct acpi_backend_data *) data)->acpi_input_dev;
+#endif
+ omnibook_report_key(input_dev, acpi_scan_table[i].keycode);
+ break;
+ }
+ }
+}
+
+struct omnibook_backend acpi_backend = {
+ .name = "acpi",
+ .hotkeys_read_cap = HKEY_FN,
+ .hotkeys_write_cap = HKEY_FN,
+ .init = omnibook_acpi_init,
+ .exit = omnibook_acpi_exit,
+ .aerial_get = omnibook_acpi_get_wireless,
+ .aerial_set = omnibook_acpi_set_wireless,
+ .display_get = omnibook_acpi_get_display,
+ .display_set = omnibook_acpi_set_display,
+ .throttle_get = omnibook_acpi_get_throttle,
+ .throttle_set = omnibook_acpi_set_throttle,
+ .hotkeys_get = omnibook_hci_get_hotkeys,
+ .hotkeys_set = omnibook_hci_set_hotkeys,
+};
+
+#else /* CONFIG_ACPI */
+
+/* dummy backend for non-ACPI systems */
+static int _fail_probe(const struct omnibook_operation *io_op)
+{
+ return -ENODEV;
+}
+
+struct omnibook_backend acpi_backend = {
+ .name = "acpi",
+ .init = _fail_probe,
+};
+
+#endif /* CONFIG_ACPI */
diff --git a/ubuntu/omnibook/battery.c b/ubuntu/omnibook/battery.c
new file mode 100644
index 00000000000..c9191fc2146
--- /dev/null
+++ b/ubuntu/omnibook/battery.c
@@ -0,0 +1,557 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+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_state {
+ 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
+};
+
+#define BAT_OFFSET 0x10
+
+static int __backend_u16_read(struct omnibook_operation *io_op, u16 *data)
+{
+ int retval;
+ u8 byte;
+
+ retval = __backend_byte_read(io_op, &byte);
+ if (retval)
+ return retval;
+ *data = byte;
+ io_op->read_addr += 1;
+ retval = __backend_byte_read(io_op, &byte);
+ *data += (byte << 8);
+ return retval;
+}
+
+static int omnibook_battery_present(struct omnibook_operation *io_op, int num)
+{
+ int retval;
+ u8 bat;
+ int i;
+
+ /*
+ * XE3GF
+ * TSP10
+ * TSM30X
+ * TSM70
+ */
+ if (omnibook_ectype & (XE3GF | TSP10 | TSM70 | TSM30X)) {
+ io_op->read_addr = XE3GF_BAL;
+ io_op->read_mask = XE3GF_BAL0_MASK;
+ for (i = 0; i < num; i++)
+ io_op->read_mask = io_op->read_mask << 1;
+ retval = __backend_byte_read(io_op, &bat);
+ /*
+ * XE3GC
+ * AMILOD
+ */
+ } else if (omnibook_ectype & (XE3GC | AMILOD)) {
+ io_op->read_addr = XE3GC_BAT;
+ io_op->read_mask = XE3GC_BAT0_MASK;
+ for (i = 0; i < num; i++)
+ io_op->read_mask = io_op->read_mask << 1;
+ retval = __backend_byte_read(io_op, &bat);
+ } else
+ retval = -ENODEV;
+
+ /* restore default read_mask */
+ io_op->read_mask = 0;
+
+ return !!bat;
+}
+
+/*
+ * 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
+ */
+static int omnibook_get_battery_info(struct omnibook_operation *io_op,
+ int num,
+ struct omnibook_battery_info *battinfo)
+{
+ int retval;
+ /*
+ * XE3GF
+ * TSP10
+ * TSM70
+ * TSM30X
+ */
+ if (omnibook_ectype & (XE3GF | TSP10 | TSM70 | TSM30X)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = XE3GF_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
+ return retval;
+ io_op->read_addr = XE3GF_BSN0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).sn)))
+ return retval;
+ io_op->read_addr = XE3GF_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
+ return retval;
+ io_op->read_addr = XE3GF_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
+ return retval;
+
+ (*battinfo).type = ((*battinfo).type & XE3GF_BTY_MASK) ? 1 : 0;
+ } else
+ return 1;
+ /*
+ * XE3GC
+ */
+ } else if (omnibook_ectype & (XE3GC)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = XE3GC_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
+ return retval;
+ io_op->read_addr = XE3GC_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
+ return retval;
+ io_op->read_addr = XE3GC_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
+ return retval;
+
+ (*battinfo).type = ((*battinfo).type & XE3GC_BTY_MASK) ? 1 : 0;
+ (*battinfo).sn = 0; /* Unknown */
+ } else
+ return 1;
+ /*
+ * AMILOD
+ */
+ } else if (omnibook_ectype & (AMILOD)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = AMILOD_BDV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dv)))
+ return retval;
+ io_op->read_addr = AMILOD_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battinfo).dc)))
+ return retval;
+ io_op->read_addr = AMILOD_BTY0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*battinfo).type)))
+ return retval;
+
+ (*battinfo).type = ((*battinfo).type & AMILOD_BTY_MASK) ? 1 : 0;
+ (*battinfo).sn = 0; /* Unknown */
+ } else
+ return 1;
+ /*
+ * FIXME
+ * OB500
+ * OB510
+ */
+ } else if (omnibook_ectype & (OB500 | OB510)) {
+ switch (num) {
+ case 0:
+ case 1:
+ case 2:
+ break;
+ default:
+ return -EINVAL;
+ }
+ /*
+ * OB6000
+ * OB6100
+ * XE4500
+ */
+ } else if (omnibook_ectype & (OB6000 | OB6100 | XE4500)) {
+ switch (num) {
+ case 0:
+ case 1:
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else
+ return 2;
+
+ return 0;
+}
+
+/*
+ * Get battery status
+ * return values:
+ * < 0 - ERROR
+ * 0 - OK
+ * 1 - Battery is not present
+ * 2 - Not supported
+ */
+static int omnibook_get_battery_status(struct omnibook_operation *io_op,
+ int num,
+ struct omnibook_battery_state *battstat)
+{
+ int retval;
+ u8 status;
+ u16 dc;
+ int gauge;
+
+ /*
+ * XE3GF
+ * TSP10
+ * TSM70
+ */
+ if (omnibook_ectype & (XE3GF | TSP10 | TSM70 | TSM30X)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = XE3GF_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = XE3GF_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = XE3GF_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ io_op->read_addr = XE3GF_BFC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).lc)))
+ return retval;
+ io_op->read_addr = XE3GF_GAU0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &(*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;
+ /*
+ * XE3GC
+ */
+ } else if (omnibook_ectype & (XE3GC)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = XE3GC_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = XE3GC_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = XE3GC_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ io_op->read_addr = XE3GC_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &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;
+ /*
+ * AMILOD
+ */
+ } else if (omnibook_ectype & (AMILOD)) {
+ retval = omnibook_battery_present(io_op, num);
+ if (retval < 0)
+ return retval;
+ if (retval) {
+ io_op->read_addr = AMILOD_BST0 + (BAT_OFFSET * num);
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = AMILOD_BRC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = AMILOD_BPV0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ io_op->read_addr = AMILOD_BDC0 + (BAT_OFFSET * num);
+ if ((retval = __backend_u16_read(io_op, &dc)))
+ return retval;
+
+ if (status & AMILOD_BST_MASK_CRT)
+ (*battstat).status = OMNIBOOK_BATTSTAT_CRITICAL;
+ else if (status & AMILOD_BST_MASK_CHR)
+ (*battstat).status = OMNIBOOK_BATTSTAT_CHARGING;
+ else if (status & AMILOD_BST_MASK_DSC)
+ (*battstat).status = OMNIBOOK_BATTSTAT_DISCHARGING;
+ else if (status & (AMILOD_BST_MASK_CHR | AMILOD_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;
+ /*
+ * OB500
+ * OB510
+ */
+ } else if (omnibook_ectype & (OB500 | OB510)) {
+ switch (num) {
+ case 0:
+ io_op->read_addr = OB500_BT1S;
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = OB500_BT1C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = OB500_BT1V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ break;
+ case 1:
+ io_op->read_addr = OB500_BT2S;
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = OB500_BT2C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = OB500_BT2V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ break;
+ case 2:
+ io_op->read_addr = OB500_BT3S;
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = OB500_BT3C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = OB500_BT3V;
+ if ((retval = __backend_u16_read(io_op, &(*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;
+ }
+ /*
+ * OB6000
+ * OB6100
+ * XE4500
+ */
+ } else if (omnibook_ectype & (OB6000 | OB6100 | XE4500)) {
+ switch (num) {
+ case 0:
+ io_op->read_addr = OB500_BT1S;
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = OB500_BT1C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = OB500_BT1V;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).pv)))
+ return retval;
+ break;
+ case 1:
+ io_op->read_addr = OB500_BT3S;
+ if ((retval = __backend_byte_read(io_op, &status)))
+ return retval;
+ io_op->read_addr = OB500_BT3C;
+ if ((retval = __backend_u16_read(io_op, &(*battstat).rc)))
+ return retval;
+ io_op->read_addr = OB500_BT3V;
+ if ((retval = __backend_u16_read(io_op, &(*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;
+ }
+ } else {
+ return 2;
+ }
+ return 0;
+}
+
+static int omnibook_battery_read(char *buffer, struct omnibook_operation *io_op)
+{
+ char *statustr;
+ char *typestr;
+ int max = 0;
+ int num = 0;
+ int len = 0;
+ int retval;
+ int i;
+ struct omnibook_battery_info battinfo;
+ struct omnibook_battery_state battstat;
+ /*
+ * XE3GF
+ * XE3GC
+ * 0B6000
+ * 0B6100
+ * XE4500
+ * AMILOD
+ * TSP10
+ */
+ if (omnibook_ectype & (XE3GF | XE3GC | OB6000 | OB6100 | XE4500 | AMILOD | TSP10))
+ max = 2;
+ /*
+ * OB500
+ * 0B510
+ */
+ else if (omnibook_ectype & (OB500 | OB510))
+ max = 3;
+ /*
+ * TSM30X
+ * TSM70
+ */
+ else if (omnibook_ectype & (TSM70 | TSM30X))
+ max = 1;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ for (i = 0; i < max; i++) {
+ retval = omnibook_get_battery_info(io_op, i, &battinfo);
+ if (retval == 0) {
+ num++;
+ omnibook_get_battery_status(io_op, 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";
+ }
+
+ len += sprintf(buffer + len, "Battery: %11d\n", i);
+ len += sprintf(buffer + len, "Type: %11s\n", typestr);
+ if (battinfo.sn)
+ len +=
+ sprintf(buffer + len, "Serial Number: %11d\n",
+ battinfo.sn);
+ len += sprintf(buffer + len, "Present Voltage: %11d mV\n", battstat.pv);
+ len += sprintf(buffer + len, "Design Voltage: %11d mV\n", battinfo.dv);
+ len += sprintf(buffer + len, "Remaining Capacity: %11d mAh\n", battstat.rc);
+ if (battstat.lc)
+ len +=
+ sprintf(buffer + len, "Last Full Capacity: %11d mAh\n",
+ battstat.lc);
+ len += sprintf(buffer + len, "Design Capacity: %11d mAh\n", battinfo.dc);
+ len +=
+ sprintf(buffer + len, "Gauge: %11d %%\n", battstat.gauge);
+ len += sprintf(buffer + len, "Status: %11s\n", statustr);
+ len += sprintf(buffer + len, "\n");
+ }
+ }
+ if (num == 0)
+ len += sprintf(buffer + len, "No battery present\n");
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ return len;
+}
+
+static struct omnibook_tbl battery_table[] __initdata = {
+ {XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X, {EC,}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature battery_driver = {
+ .name = "battery",
+#ifdef CONFIG_OMNIBOOK_LEGACY
+ .enabled = 1,
+#else
+ .enabled = 0,
+#endif
+ .read = omnibook_battery_read,
+ .ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X, /* FIXME: OB500|OB6000|OB6100|XE4500 */
+ .tbl = battery_table,
+};
+
+module_param_named(battery, battery_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(battery, "Use 0 to disable, 1 to enable battery status monitoring");
+/* End of file */
diff --git a/ubuntu/omnibook/blank.c b/ubuntu/omnibook/blank.c
new file mode 100644
index 00000000000..1bad34c3793
--- /dev/null
+++ b/ubuntu/omnibook/blank.c
@@ -0,0 +1,138 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <asm/io.h>
+#include "hardware.h"
+
+static struct omnibook_feature blank_driver;
+
+/*
+ * console_blank_hook pointer manipulation is lock protected
+ */
+extern int (*console_blank_hook) (int);
+static DEFINE_SPINLOCK(blank_spinlock);
+
+
+int omnibook_lcd_blank(int blank)
+{
+ struct omnibook_feature *blank_feature = omnibook_find_feature("blank");
+
+ if(!blank_feature)
+ return -ENODEV;
+
+ return omnibook_apply_write_mask(blank_feature->io_op, blank);
+}
+
+static int console_blank_register_hook(void)
+{
+ spin_lock(&blank_spinlock);
+ if (console_blank_hook != omnibook_lcd_blank) {
+ if (console_blank_hook == NULL) {
+ console_blank_hook = omnibook_lcd_blank;
+ printk(O_INFO "LCD backlight turn off at console blanking is enabled.\n");
+ } else
+ printk(O_INFO "There is a console blanking solution already registered.\n");
+ }
+ spin_unlock(&blank_spinlock);
+ return 0;
+}
+
+static int console_blank_unregister_hook(void)
+{
+ int retval;
+ spin_lock(&blank_spinlock);
+ if (console_blank_hook == omnibook_lcd_blank) {
+ console_blank_hook = NULL;
+ printk(O_INFO "LCD backlight turn off at console blanking is disabled.\n");
+ } else if (console_blank_hook) {
+ printk(O_WARN "You can not disable another console blanking solution.\n");
+ retval = -EBUSY;
+ } else {
+ printk(O_INFO "Console blanking already disabled.\n");
+ }
+ spin_unlock(&blank_spinlock);
+ return retval;
+}
+
+static int omnibook_console_blank_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ spin_lock(&blank_spinlock);
+
+ len +=
+ sprintf(buffer + len, "LCD console blanking hook is %s\n",
+ (console_blank_hook == omnibook_lcd_blank) ? "enabled" : "disabled");
+
+ spin_unlock(&blank_spinlock);
+
+ return len;
+}
+
+static int omnibook_console_blank_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+
+ switch (*buffer) {
+ case '0':
+ retval = console_blank_unregister_hook();
+ break;
+ case '1':
+ retval = console_blank_register_hook();
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+static int __init omnibook_console_blank_init(struct omnibook_operation *io_op)
+{
+ return console_blank_register_hook();
+}
+
+static void __exit omnibook_console_blank_cleanup(struct omnibook_operation *io_op)
+{
+ console_blank_unregister_hook();
+}
+
+static struct omnibook_tbl blank_table[] __initdata = {
+ {TSM70 | TSX205, {CDI, 0, TSM100_BLANK_INDEX, 0, TSM100_LCD_OFF, TSM100_LCD_ON}},
+ {XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X,
+ COMMAND(KBC, OMNIBOOK_KBC_CMD_LCD_OFF, OMNIBOOK_KBC_CMD_LCD_ON)},
+ {OB500 | OB6000 | XE2, {PIO, OB500_GPO1, OB500_GPO1, 0, -OB500_BKLT_MASK, OB500_BKLT_MASK}},
+ {OB510 | OB6100, {PIO, OB510_GPO2, OB510_GPO2, 0, -OB510_BKLT_MASK, OB510_BKLT_MASK}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature blank_driver = {
+ .name = "blank",
+ .enabled = 1,
+ .read = omnibook_console_blank_read,
+ .write = omnibook_console_blank_write,
+ .init = omnibook_console_blank_init,
+ .exit = omnibook_console_blank_cleanup,
+ .ectypes =
+ XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE2 | AMILOD | TSP10 | TSM70 | TSM30X | TSX205,
+ .tbl = blank_table,
+};
+
+module_param_named(blank, blank_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(blank, "Use 0 to disable, 1 to enable lcd console blanking");
+/* End of file */
diff --git a/ubuntu/omnibook/bluetooth.c b/ubuntu/omnibook/bluetooth.c
new file mode 100644
index 00000000000..1095eecb9f7
--- /dev/null
+++ b/ubuntu/omnibook/bluetooth.c
@@ -0,0 +1,104 @@
+/*
+ * wireless.c Bluetooth feature
+ *
+ * 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ *
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_bt_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int retval;
+ unsigned int state;
+
+ if ((retval = backend_aerial_get(io_op, &state)))
+ return retval;
+
+ len +=
+ sprintf(buffer + len, "Bluetooth adapter is %s",
+ (state & BT_EX) ? "present" : "absent");
+ if (state & BT_EX)
+ len += sprintf(buffer + len, " and %s", (state & BT_STA) ? "enabled" : "disabled");
+ len += sprintf(buffer + len, ".\n");
+ return len;
+
+}
+
+static int omnibook_bt_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ unsigned int state;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if ((retval = __backend_aerial_get(io_op, &state)))
+ goto out;
+
+ if (*buffer == '0')
+ state &= ~BT_STA;
+ else if (*buffer == '1')
+ state |= BT_STA;
+ else {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ retval = __backend_aerial_set(io_op, state);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static struct omnibook_feature bt_driver;
+
+static int __init omnibook_bt_init(struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ unsigned int state;
+
+/*
+ * Refuse enabling/disabling a non-existent device
+ */
+
+ if ((retval = backend_aerial_get(io_op, &state)))
+ return retval;
+
+ if (!(state & BT_EX))
+ bt_driver.write = NULL;
+
+ return retval;
+}
+
+static struct omnibook_tbl wireless_table[] __initdata = {
+ {TSM70 | TSA105 | TSX205, {ACPI,}}, /* stubs to select backend */
+ {TSM40, {SMI,}}, /* stubs to select backend */
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature bt_driver = {
+ .name = "bluetooth",
+ .enabled = 1,
+ .read = omnibook_bt_read,
+ .write = omnibook_bt_write,
+ .init = omnibook_bt_init,
+ .ectypes = TSM70 | TSM40 | TSA105 | TSX205,
+ .tbl = wireless_table,
+};
+
+module_param_named(bluetooth, bt_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(bluetooth, "Use 0 to disable, 1 to enable bluetooth adapter control");
diff --git a/ubuntu/omnibook/compal.c b/ubuntu/omnibook/compal.c
new file mode 100644
index 00000000000..766aec531a5
--- /dev/null
+++ b/ubuntu/omnibook/compal.c
@@ -0,0 +1,526 @@
+/*
+ * compal.c -- EC PIO Command/Data/Index mode low-level access 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ *
+ */
+
+#include "omnibook.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kref.h>
+
+#include <asm/io.h>
+#include "hardware.h"
+
+/*
+ * ATI's IXP PCI-LPC bridge
+ */
+#define PCI_DEVICE_ID_ATI_SB400 0x4377
+
+/*
+ * PCI Config space regiser
+ * Laptop with Intel ICH Chipset
+ * See ICH6M and ICH7M spec
+ */
+#define INTEL_LPC_GEN1_DEC 0x84
+#define INTEL_LPC_GEN4_DEC 0x90
+#define INTEL_IOPORT_BASE 0xff2c
+
+/*
+ * PCI Config space regiser
+ * Laptop with ATI Chipset
+ * FIXME Untested, name unknown
+ */
+#define ATI_LPC_REG 0x4a
+#define ATI_IOPORT_BASE 0xfd60
+
+/*
+ *This interface uses 2 ports for command and 1 port for data
+ *These are relative to the ioport_base address
+ */
+
+#define PIO_PORT_COMMAND1 0x1
+#define PIO_PORT_COMMAND2 0x2
+#define PIO_PORT_DATA 0x3
+
+/*
+ * Private data of this backend
+ */
+static struct pci_dev *lpc_bridge; /* Southbridge chip ISA bridge/LPC interface PCI device */
+static u32 ioport_base; /* PIO base adress */
+static union {
+ u16 word;
+ u32 dword;
+} pci_reg_state; /* Saved state of register in PCI config spave */
+
+/*
+ * Possible list of supported southbridges
+ * Here mostly to implement a more or less clean PCI probing
+ * Works only because of previous DMI probing.
+ * Shared with nbsmi backend
+ */
+const struct pci_device_id lpc_bridge_table[] = {
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_4, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SB400, PCI_ANY_ID, PCI_ANY_ID, 0, 0,},
+ {0,}, /* End of list */
+};
+
+/*
+ * Low-level Read function:
+ * Write a 2-bytes wide command to the COMMAND ports
+ * Read the result in the DATA port
+ */
+static unsigned char lowlevel_read(u16 command)
+{
+ unsigned char data;
+ outb((command & 0xff00) >> 8, ioport_base + PIO_PORT_COMMAND1);
+ outb(command & 0x00ff, ioport_base + PIO_PORT_COMMAND2);
+ data = inb(ioport_base + PIO_PORT_DATA);
+ return data;
+}
+
+/*
+ * Low-level Write function:
+ * Write a 2-bytes wide command to the COMMAND ports
+ * Write the result in the DATA port
+ */
+static void lowlevel_write(u16 command, u8 data)
+{
+ outb((command & 0xff00) >> 8, ioport_base + PIO_PORT_COMMAND1);
+ outb(command & 0x00ff, ioport_base + PIO_PORT_COMMAND2);
+ outb(data, ioport_base + PIO_PORT_DATA);
+}
+
+/*
+ * Probe for a state of the PIO Command/Data/Index interface
+ * Give some time for the controler to settle in the desired state
+ * mode significance:
+ * 0: Waiting for command
+ * 1,2,3: I am confused FIXME
+ */
+static int check_cdimode_flag(unsigned int mode)
+{
+ int i;
+ int retval;
+
+ /*dprintk("Index mode:");*/
+ for (i = 1; i <= 250; i++) {
+ retval = lowlevel_read(0xfbfc);
+ /*dprintk_simple(" [%i]", retval);*/
+ if (retval == mode) {
+ /*dprintk_simple(".\n");
+ dprintk("Index Mode Ok (%i) after %i iter\n", mode, i);*/
+ return 0;
+ }
+ udelay(100);
+ }
+ printk(O_ERR "check_cdimode_flag timeout.\n");
+ return -ETIME;
+}
+
+/*
+ * Check for conventional default (0xf432) state in Commad ports
+ */
+static int check_default_state(void)
+{
+ int i;
+
+ for (i = 1; i <= 250; i++) {
+ if ((inb(ioport_base + PIO_PORT_COMMAND1) == 0xf4)
+ && (inb(ioport_base + PIO_PORT_COMMAND2) == 0x32))
+ return 0;
+ udelay(100);
+ }
+ printk(O_ERR "check_default_state timeout.\n");
+ return -ETIME;
+}
+
+/*
+ * Enable EC Command/Data/Index PIO Access and then check EC state.
+ * Enabling is done in PCI config space of the LPC bridge.
+ *
+ * Just after Enabling, the EC should be in a precisly defined state:
+ * - PIO should be in a conventional default state (0xf432 in the Command ports)
+ * - Command/Data/Index interface waiting for command
+ * The EC is expected to be in that state prior to any attempt to use the interface.
+ *
+ */
+static int enable_cdimode(void)
+{
+ union {
+ u16 word;
+ u32 dword;
+ } value;
+
+ switch (lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ switch (lpc_bridge->device) {
+ case PCI_DEVICE_ID_INTEL_ICH7_0: /* ICH7 */
+ case PCI_DEVICE_ID_INTEL_ICH7_1:
+ case PCI_DEVICE_ID_INTEL_ICH7_30:
+ case PCI_DEVICE_ID_INTEL_ICH7_31:
+ case PCI_DEVICE_ID_INTEL_ICH8_4: /* ICH8 */
+ pci_read_config_dword(lpc_bridge, INTEL_LPC_GEN4_DEC, &(value.dword));
+ pci_reg_state.dword = value.dword;
+ value.dword = 0x3CFF21;
+ pci_write_config_dword(lpc_bridge, INTEL_LPC_GEN4_DEC, value.dword);
+ break;
+ default: /* All other Intel chipset */
+ pci_read_config_word(lpc_bridge, INTEL_LPC_GEN1_DEC, &(value.word));
+ pci_reg_state.word = value.word;
+ value.word = (INTEL_IOPORT_BASE & 0xfff1) | 0x1;
+ pci_write_config_word(lpc_bridge, INTEL_LPC_GEN1_DEC, value.word);
+ }
+ break;
+ case PCI_VENDOR_ID_ATI:
+ pci_read_config_dword(lpc_bridge, ATI_LPC_REG, &(value.dword));
+ pci_reg_state.dword = value.dword;
+ value.dword = ((pci_reg_state.dword & 0x7f) | 0x80) << 0x10;
+ pci_write_config_dword(lpc_bridge, ATI_LPC_REG, value.dword);
+ break;
+ default:
+ BUG();
+ }
+ dprintk("Saved state of PCI register: [%x].\n", pci_reg_state.dword);
+
+ if (check_default_state() || check_cdimode_flag(0)) {
+ printk(O_ERR "EC state check failure, please report.\n");
+ return -EIO;
+ }
+
+ return 0;
+
+}
+
+/*
+ * Send a write command and associated data code to be written
+ * Known commands an associated code significance:
+ * 0xfbfd: Select Index with 'code' ordinal
+ * 0xfbfe: Set to 'code' a previously selected Index
+ * 0xfbfc: Set CDI mode flag
+ */
+static int send_ec_cmd(unsigned int command, u8 code)
+{
+ lowlevel_write(0xfbfc, 0x2);
+ lowlevel_write(command, code);
+ lowlevel_write(0xfbfc, 0x1);
+ if (check_cdimode_flag(2))
+ return -ETIME;
+ return 0;
+}
+
+/*
+ * Send a read command
+ * Known commands an associated code significance:
+ * 0xfbfe: Read a previously selected Index
+ * 0xfbfc: Set CDI mode flag
+ */
+static int read_ec_cmd(unsigned int command, u8 * value)
+{
+ *value = lowlevel_read(command);
+ lowlevel_write(0xfbfc, 0x1);
+ if (check_cdimode_flag(2))
+ return -ETIME;
+ return 0;
+}
+
+/*
+ * Disable EC Command/Data/Index PIO Access
+ * Step 1: clear_cdimode
+ * Send Disable command
+ * Revert PIO interface to conventional default state (0xf432 in the Command ports)
+ * Step 2: clear_cdimode_pci
+ * Disable the interface in the PCI config space of the Southbridge
+ * These steps are separated due to constrains in error path treatement
+ */
+static void clear_cdimode(void)
+{
+ lowlevel_write(0xfbfc, 0x0);
+ outb(0xf4, ioport_base + PIO_PORT_COMMAND1);
+ outb(0x32, ioport_base + PIO_PORT_COMMAND2);
+}
+
+static void clear_cdimode_pci(void)
+{
+ switch (lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ switch (lpc_bridge->device) {
+ case PCI_DEVICE_ID_INTEL_ICH7_0: /* ICH7 */
+ case PCI_DEVICE_ID_INTEL_ICH7_1:
+ case PCI_DEVICE_ID_INTEL_ICH7_30:
+ case PCI_DEVICE_ID_INTEL_ICH7_31:
+ case PCI_DEVICE_ID_INTEL_ICH8_4: /* ICH8 */
+ pci_write_config_dword(lpc_bridge, INTEL_LPC_GEN4_DEC, pci_reg_state.dword);
+ break;
+ default: /* All other Intel chipset */
+ pci_write_config_word(lpc_bridge, INTEL_LPC_GEN1_DEC, pci_reg_state.word);
+ }
+ break;
+ case PCI_VENDOR_ID_ATI:
+ pci_write_config_dword(lpc_bridge, ATI_LPC_REG, pci_reg_state.dword);
+ break;
+ default:
+ BUG();
+ }
+}
+
+/*
+ * Try to init the backend
+ * This function can be called blindly as it use a kref
+ * to check if the init sequence was already done.
+ */
+static int omnibook_cdimode_init(const struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ int i;
+
+ /* ectypes other than TSM70 have no business with this backend */
+ if (!(omnibook_ectype & (TSM70 | TSX205)))
+ return -ENODEV;
+
+ if (io_op->backend->already_failed) {
+ dprintk("CDI backend init already failed, skipping.\n");
+ return -ENODEV;
+ }
+
+ if (!lpc_bridge) {
+ /* Fist use of the backend */
+ dprintk("Try to init cdimode\n");
+ mutex_init(&io_op->backend->mutex);
+ mutex_lock(&io_op->backend->mutex);
+ kref_init(&io_op->backend->kref);
+
+ /* PCI probing: find the LPC Super I/O bridge PCI device */
+ for (i = 0; !lpc_bridge && lpc_bridge_table[i].vendor; ++i)
+ lpc_bridge =
+ pci_get_device(lpc_bridge_table[i].vendor, lpc_bridge_table[i].device,
+ NULL);
+
+ if (!lpc_bridge) {
+ printk(O_ERR "Fail to find a supported LPC I/O bridge, please report\n");
+ retval = -ENODEV;
+ goto error1;
+ }
+
+ if ((retval = pci_enable_device(lpc_bridge))) {
+ printk(O_ERR "Unable to enable PCI device.\n");
+ goto error2;
+ }
+
+ switch (lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ ioport_base = INTEL_IOPORT_BASE;
+ break;
+ case PCI_VENDOR_ID_ATI:
+ ioport_base = ATI_IOPORT_BASE;
+ break;
+ default:
+ BUG();
+ }
+
+ if (!request_region(ioport_base, 4, OMNIBOOK_MODULE_NAME)) {
+ printk(O_ERR "Request I/O region error\n");
+ retval = -ENODEV;
+ goto error2;
+ }
+
+ /*
+ * Make an enable-check disable cycle for testing purpose
+ */
+
+ retval = enable_cdimode();
+ if (retval)
+ goto error3;
+
+ clear_cdimode();
+ clear_cdimode_pci();
+
+ dprintk("Cdimode init ok\n");
+ mutex_unlock(&io_op->backend->mutex);
+ return 0;
+ } else {
+ dprintk("Cdimode has already been initialized\n");
+ kref_get(&io_op->backend->kref);
+ return 0;
+ }
+
+ error3:
+ clear_cdimode_pci();
+ release_region(ioport_base, 4);
+ error2:
+ pci_dev_put(lpc_bridge);
+ lpc_bridge = NULL;
+ error1:
+ io_op->backend->already_failed = 1;
+ mutex_unlock(&io_op->backend->mutex);
+ mutex_destroy(&io_op->backend->mutex);
+ return retval;
+}
+
+static void cdimode_free(struct kref *ref)
+{
+ struct omnibook_backend *backend;
+
+ dprintk("Cdimode not used anymore: disposing\n");
+
+ backend = container_of(ref, struct omnibook_backend, kref);
+
+ mutex_lock(&backend->mutex);
+ pci_dev_put(lpc_bridge);
+ release_region(ioport_base, 4);
+ lpc_bridge = NULL;
+ mutex_unlock(&backend->mutex);
+ mutex_destroy(&backend->mutex);
+}
+
+static void omnibook_cdimode_exit(const struct omnibook_operation *io_op)
+{
+ /* ectypes other than TSM70 have no business with this backend */
+ BUG_ON(!(omnibook_ectype & (TSM70 | TSX205)));
+ dprintk("Trying to dispose cdimode\n");
+ kref_put(&io_op->backend->kref, cdimode_free);
+}
+
+/*
+ * Read EC index and write result to value
+ * 'EC index' here is unrelated to an index in the EC registers
+ */
+static int omnibook_cdimode_read(const struct omnibook_operation *io_op, u8 * value)
+{
+ int retval = 0;
+
+ if (!lpc_bridge)
+ return -ENODEV;
+
+ retval = enable_cdimode();
+ if (retval)
+ goto out;
+ retval = send_ec_cmd(0xfbfd, (unsigned int)io_op->read_addr);
+ if (retval)
+ goto error;
+ retval = read_ec_cmd(0xfbfe, value);
+
+ if (io_op->read_mask)
+ *value &= io_op->read_mask;
+
+ error:
+ clear_cdimode();
+ out:
+ clear_cdimode_pci();
+ return retval;
+}
+
+/*
+ * Write value
+ * 'EC index' here is unrelated to an index in the EC registers
+ */
+static int omnibook_cdimode_write(const struct omnibook_operation *io_op, u8 value)
+{
+ int retval = 0;
+
+ if (!lpc_bridge)
+ return -ENODEV;
+
+ retval = enable_cdimode();
+ if (retval)
+ goto out;
+ retval = send_ec_cmd(0xfbfd, (unsigned int)io_op->write_addr);
+ if (retval)
+ goto error;
+ retval = send_ec_cmd(0xfbfe, value);
+ error:
+ clear_cdimode();
+ out:
+ clear_cdimode_pci();
+ return retval;
+
+}
+
+/*
+ * Fn+foo and multimedia hotkeys handling
+ */
+static int omnibook_cdimode_hotkeys(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval;
+
+ struct omnibook_operation hotkeys_op =
+ { CDI, 0, TSM70_FN_INDEX, 0, TSM70_FN_ENABLE, TSM70_FN_DISABLE};
+
+ /* Fn+foo handling */
+ retval = __omnibook_toggle(&hotkeys_op, !!(state & HKEY_FN));
+ if (retval < 0)
+ return retval;
+
+ /* Multimedia keys handling */
+ hotkeys_op.write_addr = TSM70_HOTKEYS_INDEX;
+ hotkeys_op.on_mask = TSM70_HOTKEYS_ENABLE;
+ hotkeys_op.off_mask = TSM70_HOTKEYS_DISABLE;
+ retval = __omnibook_toggle(&hotkeys_op, !!(state & HKEY_MULTIMEDIA));
+
+ return retval;
+}
+
+/* Scan index space, this hard locks my machine */
+#if 0
+static int compal_scan(char *buffer)
+{
+ int len = 0;
+ int i, j;
+ u8 v;
+
+ for (i = 0; i < 255; i += 16) {
+ for (j = 0; j < 16; j++) {
+ omnibook_compal_read(i + j, &v);
+ len += sprintf(buffer + len, "Read index %02x: %02x\n", i + j, v);
+ mdelay(500);
+ }
+ if (j != 16)
+ break;
+ }
+
+ return len;
+}
+#endif
+
+struct omnibook_backend compal_backend = {
+ .name = "compal",
+ .hotkeys_write_cap = HKEY_MULTIMEDIA | HKEY_FN,
+ .init = omnibook_cdimode_init,
+ .exit = omnibook_cdimode_exit,
+ .byte_read = omnibook_cdimode_read,
+ .byte_write = omnibook_cdimode_write,
+ .hotkeys_set = omnibook_cdimode_hotkeys,
+};
+
+/* End of file */
diff --git a/ubuntu/omnibook/compat.h b/ubuntu/omnibook/compat.h
new file mode 100644
index 00000000000..d45605371d5
--- /dev/null
+++ b/ubuntu/omnibook/compat.h
@@ -0,0 +1,71 @@
+/*
+ * compat.h -- Older kernel (=> 2.6.11) 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include <linux/version.h>
+
+/*
+ * For compatibility with kernel older than 2.6.16
+ * Mutex to Semaphore fallback
+ */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+#include <asm/semaphore.h>
+#define DEFINE_MUTEX(lock) DECLARE_MUTEX(lock)
+#define mutex_init(lock) init_MUTEX(lock)
+#define mutex_lock(lock) down(lock)
+#define mutex_lock_interruptible(lock) down_interruptible(lock)
+#define mutex_unlock(lock) up(lock)
+#define mutex_destroy(lock) do { } while(0)
+#else
+#include <linux/mutex.h>
+#endif
+
+/*
+ * For compatibility with kernel older than 2.6.14
+ */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
+static void inline *kzalloc(size_t size, int flags)
+{
+ void *ret = kmalloc(size, flags);
+ if (ret)
+ memset(ret, 0, size);
+ return ret;
+}
+#endif
+
+/*
+ * For compatibility with kernel older than 2.6.11
+ */
+
+#ifndef DEFINE_SPINLOCK
+#define DEFINE_SPINLOCK(s) spinlock_t s = SPIN_LOCK_UNLOCKED
+#endif
+
+/*
+ * Those kernel don't have ICH7 southbridge pcids
+ */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
+#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
+#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
+#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
+#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
+#endif
+
+
+
+/* End of file */
diff --git a/ubuntu/omnibook/cooling.c b/ubuntu/omnibook/cooling.c
new file mode 100644
index 00000000000..a9a935e7e6f
--- /dev/null
+++ b/ubuntu/omnibook/cooling.c
@@ -0,0 +1,97 @@
+/*
+ * colling.c -- cooling methods feature
+ *
+ * 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 Mathieu Bérard <mathieu.berard@crans.org>, 2007
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_cooling_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ len += sprintf(buffer + len, "Cooling method : %s\n",
+ io_op->backend->cooling_state ? "Performance" : "Powersave" );
+
+ mutex_unlock(&io_op->backend->mutex);
+ return len;
+}
+
+static int omnibook_cooling_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+
+ if (*buffer == '0') {
+ retval = __backend_byte_write(io_op,
+ TSM70_COOLING_OFFSET + TSM70_COOLING_POWERSAVE);
+ } else if (*buffer == '1') {
+ retval = __backend_byte_write(io_op,
+ TSM70_COOLING_OFFSET + TSM70_COOLING_PERF);
+ } else {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ /* *buffer is either '0' or '1' here */
+ if (!retval)
+ io_op->backend->cooling_state = *buffer - '0' ;
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ out:
+ return retval;
+}
+
+static int __init omnibook_cooling_init(struct omnibook_operation *io_op)
+{
+ mutex_lock(&io_op->backend->mutex);
+ /* XXX: Assumed default cooling method: performance */
+ io_op->backend->cooling_state = TSM70_COOLING_PERF;
+ mutex_unlock(&io_op->backend->mutex);
+ return 0;
+}
+
+static void __exit omnibook_cooling_exit(struct omnibook_operation *io_op)
+{
+ /* Set back cooling method to performance */
+ backend_byte_write(io_op, TSM70_COOLING_OFFSET + TSM70_COOLING_PERF);
+}
+
+static struct omnibook_tbl cooling_table[] __initdata = {
+ {TSM70 | TSX205, {CDI, 0, TSM70_FN_INDEX, 0, 0, 0 }},
+ {0,}
+};
+
+struct omnibook_feature __declared_feature cooling_driver = {
+ .name = "cooling",
+ .enabled = 1,
+ .read = omnibook_cooling_read,
+ .write = omnibook_cooling_write,
+ .init = omnibook_cooling_init,
+ .exit = omnibook_cooling_exit,
+ .ectypes = TSM70 | TSX205,
+ .tbl = cooling_table,
+};
+
+module_param_named(cooling, cooling_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(cooling, "Use 0 to disable, 1 to enable CPU cooling method control");
+
+/* End of file */
diff --git a/ubuntu/omnibook/debian/README.Debian b/ubuntu/omnibook/debian/README.Debian
new file mode 100644
index 00000000000..4978147dcfe
--- /dev/null
+++ b/ubuntu/omnibook/debian/README.Debian
@@ -0,0 +1,30 @@
+omnibook for Debian
+-------------------
+
+Please see docs/README for a description of the omnibook kernel module.
+
+The Debian omnibook source package provides omnibook-source, package
+which provides the source for the kernel module.
+
+The omnibook-source package can be used in several ways,
+
+ - Using the make-kpkg(1) command provided by the kernel-package Debian
+ package. This will produce a corresponding omnibook-modules package for
+ the Debian kernel-image package that you are using.
+ See the "modules_image" section of the make-kpkg(1) man page.
+
+ - Using module-assistant. Simply issue the following command (as root):
+ $ module-assistant auto-install omnibook
+ Please see the module-assistant documentation for futher details.
+
+ - Changing to the /usr/src/modules/omnibook/ directory and building as
+ the README file instructs using "make; make install". This will build
+ and install a module specific to the system you are building on and is
+ not under control of the packaging system.
+
+If your are not using module-assisatant, you have to unpack
+/usr/src/omnibook-source.tar.bz2 to /usr/src.
+
+ -- Peter Soos <sp@osb.hu>, Wed, 25 Jan 2006 21:06:28 +0100
+ -- Julien Valroff <julien@kirya.net> Sun, 07 Oct 2007 10:38:07 +0200
+
diff --git a/ubuntu/omnibook/debian/changelog b/ubuntu/omnibook/debian/changelog
new file mode 100644
index 00000000000..896a82bfb0a
--- /dev/null
+++ b/ubuntu/omnibook/debian/changelog
@@ -0,0 +1,170 @@
+omnibook (2:2.20070211+svn20090714b-1) unstable; urgency=low
+
+ * New SVN snapshot:
+ + fix build issue induced by previous patches
+ + fix build with kernel >= 2.6.30
+
+ -- Julien Valroff <julien@kirya.net> Tue, 14 Jul 2009 18:17:49 +0200
+
+omnibook (2:2.20070211+svn20090714-1) unstable; urgency=low
+
+ * New SVN snapshot:
+ + Applied patches from Azael Avalos <coproscefalo@gmail.com>
+ to add support to Satellite X205 and other laptops based on
+ ICH8
+ * New Standards version 3.8.2
+ * Bumped DH compat to 7
+ * Updated copyright information
+ * Now use dh_prep instead of dh_clean -k
+
+ -- Julien Valroff <julien@kirya.net> Tue, 14 Jul 2009 10:03:00 +0200
+
+omnibook (2:2.20070211+svn20090227-1) unstable; urgency=low
+
+ * New SVN snapshot
+ + Applied patch from Danny Kukawka <dkukawka@suse.de> to
+ fix compiler warning about use uninitialized variable
+ + Applied patch from Danny Kukawka <dkukawka@suse.de> to
+ fix build the driver on older kernel versions
+
+ * New Standards version 3.8.0 - no further changes needed
+ * Updated copryight information
+
+ -- Julien Valroff <julien@kirya.net> Fri, 27 Feb 2009 19:57:35 +0100
+
+omnibook (2:2.20070211+svn20071217-1) unstable; urgency=low
+
+ * New SVN snapshot (r271)
+ * Added amd64 as a compatible architecture for the module
+ * New Standards version 3.7.3 - no further changes needed
+
+ -- Julien Valroff <julien@kirya.net> Mon, 17 Dec 2007 18:00:29 +0100
+
+omnibook (2:2.20070211+svn20071006-1) unstable; urgency=low
+
+ * New SVN snapshot (r264):
+ + Update for acpi and backlight API changes in linux 2.6.23
+ * First upload to Debian (Closes: #445602):
+ + Improved debian/copyright
+ + Bumped debhelper compat to version 5
+ + Added myself as maintainer
+ + Updated README.Debian
+ * debian/control:
+ + Moved Homepage to own field (from pseudo-field in long description)
+ + Added Vcs-* fields
+
+ -- Julien Valroff <julien@kirya.net> Thu, 29 Nov 2007 18:30:27 +0100
+
+omnibook (2:2.20070211+svn20070905-1) unstable; urgency=low
+
+ * Added dependency on dpatch
+ * [debian/rules]:
+ - Fixed lintian warning in the clean target
+
+ -- Julien Valroff <julien@kirya.net> Wed, 05 Sep 2007 20:25:13 +0200
+
+omnibook (2:2.20070211+svn20070526-1) unstable; urgency=low
+
+ * New SVN snapshot (r259):
+ + Fixed compilation issue with kernel 2.6.21
+ + DMI signature added:
+ Toshiba Satellite P25 (ectype 11)
+ Toshiba Satellite M60 (ectype 12)
+ * Added patch to disable debug for SVN snasphot
+
+ -- Julien Valroff <julien@kirya.net> Sat, 26 May 2007 15:19:57 +0200
+
+omnibook (2:2.20070211-1) unstable; urgency=low
+
+ * New upstream release:
+ + For ectype 12 (Satellite M40X, M70, M100, ...):
+ - improved bluetooth control
+ - cooling method control
+ - CPU throttling ( ACPI T-States)
+ + Full hotkeys support for Tecra S1
+ + Bluetooth control for Ectype 14 (Satellite A100, A105, M115, ...)
+ * Updated homepage in long description
+
+ -- Julien Valroff <julien@kirya.net> Mon, 12 Feb 2007 18:50:05 +0100
+
+omnibook (2:2.20060921+svn20061202-1) unstable; urgency=low
+
+ * New SVN snapshot (r228)
+
+ -- Julien Valroff <julien@kirya.net> Sat, 2 Dec 2006 10:17:07 +0100
+
+omnibook (2:2.20060921+svn20061112-1) unstable; urgency=low
+
+ * SVN snapshot:
+ + Disabled Acer support
+ + Fixed and improved bluetooth handling for TSM30X class laptop
+ + DMI signature added:
+ HP Pavilion ze4500 (ectype 7)
+ Toshiba Satellite 1130 (ectype 1)
+ Toshiba Satellite A75 (ectype 12)
+ Toshiba Tecra A4 (ectype 13)
+ + Implemented Volume down,up and Mute buttons polling for ectype 2
+ + Implemented ectype 13 Fn hotkeys handling.
+ * changed compression of the sources in /usr/src/ to bzip2
+
+ -- Julien Valroff <julien@kirya.net> Sat, 11 Nov 2006 14:08:47 +0100
+
+omnibook (2:2.20060921-1) unstable; urgency=low
+
+ * New upstream release:
+ + Expand display and hotkeys features
+ + Added support for more laptops
+ + Code cleanups
+ + Minor bug fixes
+
+ -- Julien Valroff <julien@kirya.net> Mon, 25 Sep 2006 08:14:59 +0200
+
+omnibook (2:2.20060817-1) unstable; urgency=low
+
+ * New upstream release
+ * [01_makfefile.dpatch] Removed - fixed upstream
+ * Changed defaut STEM value to linux (follows kernel-package)
+ * Uses dh_installmodules for maintainance scripts
+
+ -- Julien Valroff <julien@kirya.net> Mon, 11 Sep 2006 18:00:50 +0200
+
+omnibook (2:2.20060809-2) unstable; urgency=low
+
+ * Include copyright and Debian changelog in omnibook-module
+ * Fix Makefile issue in a more elegant way
+
+ -- Julien Valroff <julien@kirya.net> Thu, 10 Aug 2006 10:16:47 +0200
+
+omnibook (2:2.20060809-1) unstable; urgency=low
+
+ * New upstream release:
+ + Addeed autodetection of the Toshiba Satellite M40X laptop
+
+ -- Julien Valroff <julien@kirya.net> Thu, 10 Aug 2006 09:40:45 +0200
+
+omnibook (2:2.20060806-1) unstable; urgency=low
+
+ * New upstream branch - Mathieu Bérard launched new project
+ * Added myself as co-maintainer
+ * Bumped upstream version and use epoch to ensure upgrades
+ * [debian/rules]:
+ + Clean-ups
+ + Recommends linux-image or kernel-image
+ * [debian/control] Improved long description
+ * [debian/post*.modules.in] Fixed bashisms
+ * Added patch to fix install target in Makefile
+
+ -- Julien Valroff <julien@kirya.net> Thu, 10 Aug 2006 01:35:38 +0200
+
+omnibook (20060126-1) unstable; urgency=low
+
+ * Minor build inconveniences corrected.
+
+ -- Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us> Sun, 18 Jun 2006 12:28:55 -0700
+
+omnibook (20060126-0) unstable; urgency=low
+
+ * Locally built.
+
+ -- Péter Soós <sp@osb.hu> Wed, 25 Jan 2006 21:06:28 +0100
+
diff --git a/ubuntu/omnibook/debian/compat b/ubuntu/omnibook/debian/compat
new file mode 100644
index 00000000000..7f8f011eb73
--- /dev/null
+++ b/ubuntu/omnibook/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/ubuntu/omnibook/debian/control b/ubuntu/omnibook/debian/control
new file mode 100644
index 00000000000..bbcd4e733c3
--- /dev/null
+++ b/ubuntu/omnibook/debian/control
@@ -0,0 +1,21 @@
+Source: omnibook
+Section: misc
+Priority: optional
+Maintainer: Julien Valroff <julien@kirya.net>
+Build-Depends: debhelper (>> 7.0.0), dpatch, bzip2
+Standards-Version: 3.8.2
+Homepage: http://omnibook.sf.net
+Vcs-Svn: https://omnibook.svn.sourceforge.net/svnroot/omnibook/omnibook/trunk
+Vcs-Browser: http://omnibook.svn.sourceforge.net/viewvc/omnibook/
+
+Package: omnibook-source
+Architecture: all
+Depends: debhelper (>= 4.0.0), make, module-assistant, kernel-package, bzip2, dpatch
+Description: Source for the omnibook driver
+ This package contains the loadable kernel modules for the HP OmniBooks,
+ Pavilions, Toshiba Satellites and some other laptops manufactured by
+ Compal Electronics, Inc as ODM.
+ .
+ This module is only compatible with Linux kernels >= 2.6.9
+ .
+ Kernel source is required to compile this module.
diff --git a/ubuntu/omnibook/debian/control.modules.in b/ubuntu/omnibook/debian/control.modules.in
new file mode 100644
index 00000000000..a06acc2c304
--- /dev/null
+++ b/ubuntu/omnibook/debian/control.modules.in
@@ -0,0 +1,23 @@
+Source: omnibook
+Section: misc
+Priority: optional
+Maintainer: Julien Valroff <julien@kirya.net>
+Build-Depends: debhelper (>> 7.0.0)
+Standards-Version: 3.8.2
+
+Package: omnibook-module-_KVERS_
+Architecture: i386 amd64
+Recommends: _STEM_-image-_KVERS_
+Provides: omnibook-module
+Description: omnibook module for Linux (kernel _KVERS_)
+ This package contains the loadable kernel modules for the HP OmniBooks,
+ Pavilions, Toshiba Satellites and some other laptops manufactured by
+ Compal Electronics, Inc as ODM.
+ .
+ This package contains the compiled kernel modules for _KVERS_
+ .
+ If you have compiled your own kernel, you will most likely need to build
+ your own omnibook-module. The omnibook-source package has been
+ provided for use with the Debian kernel-package utility to produce a version
+ of omnibook-module for your kernel.
+
diff --git a/ubuntu/omnibook/debian/copyright b/ubuntu/omnibook/debian/copyright
new file mode 100644
index 00000000000..3011f9100f1
--- /dev/null
+++ b/ubuntu/omnibook/debian/copyright
@@ -0,0 +1,32 @@
+This package was debianized by Peter Soos <sp@osb.hu> on
+Wed, 25 Jan 2006 21:06:28 +0100.
+Debian package was improved by Julien Valroff <julien@kirya.net>
+
+It was downloaded from http://sourceforge.net/projects/omnibook
+
+Copyright Holder: 2006-2007 Mathieu Bérard <math_b@users.sourceforge.net>
+
+dump.c:
+ Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
+
+License:
+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This package 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.
+
+The Debian packaging is
+ Copyright (C) 2006 Peter Soos <sp@osb.hu>
+ Copyright (C) 2006-2009 Julien Valroff <julien@kirya.net>
+It is licensed under the GPL, version 2.
+
+You should have received a copy of the GNU General Public License with
+the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL-2;
+if not, write to the Free Software Foundation, Inc., 51 Franklin St,
+Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/ubuntu/omnibook/debian/docs b/ubuntu/omnibook/debian/docs
new file mode 100644
index 00000000000..92b96855904
--- /dev/null
+++ b/ubuntu/omnibook/debian/docs
@@ -0,0 +1,4 @@
+doc/BUGS
+doc/CREDITS
+doc/README
+misc/hotkeys
diff --git a/ubuntu/omnibook/debian/rules b/ubuntu/omnibook/debian/rules
new file mode 100755
index 00000000000..187600424be
--- /dev/null
+++ b/ubuntu/omnibook/debian/rules
@@ -0,0 +1,135 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+include /usr/share/dpatch/dpatch.make
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+# Name of the source package
+psource := omnibook-source
+
+# The short upstream name, used for the module source directory
+sname := omnibook
+
+# prefix of the target package name
+PACKAGE=omnibook-module
+
+### end KERNEL SETUP
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ touch configure-stamp
+
+
+build-arch: configure-stamp build-arch-stamp
+build-arch-stamp:
+ dh_testdir
+ touch build-arch-stamp
+
+build-indep: patch configure-stamp build-indep-stamp
+build-indep-stamp:
+ dh_testdir
+
+ touch build-indep-stamp
+
+build: patch build-arch build-indep
+
+clean: unpatch
+ dh_testdir
+ rm -f build-arch-stamp build-indep-stamp configure-stamp
+
+ dh_clean
+
+install: DH_OPTIONS=
+install: patch build
+ dh_testdir
+ dh_testroot
+ dh_prep
+ dh_installdirs
+
+ # Create the directories to install the source into
+ dh_installdirs -p$(psource) usr/src/modules/$(sname)/debian
+ cp debian/compat debian/rules debian/changelog \
+ debian/control debian/copyright debian/*.modules.in \
+ debian/$(psource)/usr/src/modules/$(sname)/debian
+ cp Makefile *.c *.h *.lds debian/$(psource)/usr/src/modules/$(sname)
+
+ cd debian/$(psource)/usr/src && tar c modules | bzip2 -9 > $(sname).tar.bz2 && rm -rf modules
+ dh_install
+
+# Build architecture-independent files here.
+# Pass -i to all debhelper commands in this target to reduce clutter.
+binary-indep: build install
+ dh_testdir -i
+ dh_testroot -i
+ dh_installchangelogs -i doc/ChangeLog
+ dh_installdocs -i
+ dh_installexamples -i
+ dh_installman -i
+ dh_link -i
+ dh_compress -i
+ dh_fixperms -i
+ dh_installdeb -i
+ dh_installdeb -i
+ dh_shlibdeps -i
+ dh_gencontrol -i
+ dh_md5sums -i
+ dh_builddeb -i
+
+# Build architecture-dependent files here.
+binary-arch: build install
+
+# modifieable for experiments or debugging m-a
+MA_DIR ?= /usr/share/modass
+# load generic variable handling
+-include $(MA_DIR)/include/generic.make
+# load default rules, including kdist, kdist_image, ...
+-include $(MA_DIR)/include/common-rules.make
+
+ifndef KPKG_STEM
+STEM:=linux
+else
+STEM:=${KPKG_STEM}
+endif
+
+kdist_clean: prep-deb-files
+ [ ! -f Makefile ] || $(MAKE) KSRC=$(KSRC) clean
+ dh_clean
+
+kdist_config: prep-deb-files
+ sed -i -e 's/_STEM_/$(STEM)/g' debian/control
+
+binary-modules: kdist_config prep-deb-files
+ dh_testroot
+ dh_prep
+ dh_installdirs lib/modules/$(KVERS)/extra
+
+ # Build the module
+ $(MAKE) KSRC=$(KSRC) KVERS=$(KVERS)
+
+ # Install the module
+ $(MAKE) install KSRC=$(KSRC) DESTDIR=$(CURDIR)/debian/$(PKGNAME) INSTDIR=extra DEPMOD="/bin/true"
+
+ dh_installdocs
+ dh_compress
+ dh_installmodules
+ dh_installchangelogs
+ dh_fixperms
+ dh_installdeb
+ dh_gencontrol -- -v$(VERSION)
+ dh_md5sums
+ dh_builddeb --destdir=$(DEB_DESTDIR)
+ dh_prep
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure binary-modules kdist kdist_config kdist_image kdist_clean
diff --git a/ubuntu/omnibook/display.c b/ubuntu/omnibook/display.c
new file mode 100644
index 00000000000..1c5d4d79d72
--- /dev/null
+++ b/ubuntu/omnibook/display.c
@@ -0,0 +1,114 @@
+/*
+ * display.c -- External display (LCD,VGA,TV-OUT) feature
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static const char display_name[][16] = {
+ "Internal LCD",
+ "External VGA",
+ "External TV-OUT",
+ "External DVI",
+};
+
+static int omnibook_display_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int retval;
+ unsigned int sta, en_mask, det_mask;
+
+ retval = backend_display_get(io_op, &sta);
+ if (retval < 0)
+ return retval;
+
+ for (en_mask = DISPLAY_LCD_ON; en_mask <= DISPLAY_DVI_ON; en_mask = en_mask << 1) {
+ det_mask = en_mask << 4; /* see display masks in omnibook.h */
+ if (!(retval & en_mask) && !(retval & det_mask))
+ continue; /* not supported */
+ len += sprintf(buffer + len, "%s:", display_name[ffs(en_mask) - 1]);
+ if (retval & det_mask)
+ len +=
+ sprintf(buffer + len, " display %s",
+ (sta & det_mask) ? "present" : "absent");
+ if (retval & en_mask)
+ len +=
+ sprintf(buffer + len, " port %s",
+ (sta & en_mask) ? "enabled" : "disabled");
+ len += sprintf(buffer + len, "\n");
+ }
+
+ return len;
+}
+
+static int omnibook_display_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+ unsigned int state;
+ char *endp;
+
+ state = simple_strtoul(buffer, &endp, 16);
+ if (endp == buffer)
+ return -EINVAL;
+ else
+ retval = backend_display_set(io_op, state);
+
+ return retval;
+}
+
+static struct omnibook_feature display_driver;
+
+static int __init omnibook_display_init(struct omnibook_operation *io_op)
+{
+ int retval;
+ unsigned int state;
+
+ /* Disable file writing if unsuported by backend */
+ if (!io_op->backend->display_set)
+ display_driver.write = NULL;
+
+ retval = backend_display_get(io_op, &state);
+ if (retval < 0)
+ return retval;
+ else
+ return 0;
+}
+
+static struct omnibook_tbl display_table[] __initdata = {
+ {TSM70 | TSX205, {ACPI,}},
+ {TSM40, {SMI, SMI_GET_DISPLAY_STATE, SMI_SET_DISPLAY_STATE, 0, 0, 0}},
+ {XE3GF | TSP10 | TSM70 | TSM30X | TSM40, SIMPLE_BYTE(EC, XE3GF_STA1, XE3GF_SHDD_MASK)},
+ {XE3GC, SIMPLE_BYTE(EC, XE3GC_STA1, XE3GC_CRTI_MASK)},
+ {OB500 | OB510 | OB6000 | OB6100 | XE4500, SIMPLE_BYTE(EC, OB500_STA1, OB500_CRTS_MASK)},
+ {OB4150, SIMPLE_BYTE(EC, OB4150_STA2, OB4150_CRST_MASK)},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature display_driver = {
+ .name = "display",
+ .enabled = 1,
+ .init = omnibook_display_init,
+ .read = omnibook_display_read,
+ .write = omnibook_display_write,
+ .ectypes =
+ XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | OB4150 | TSP10 | TSM70 | TSM30X |
+ TSM40 | TSX205,
+ .tbl = display_table,
+};
+
+module_param_named(display, display_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(display, "Use 0 to disable, 1 to enable display status handling");
+/* End of file */
diff --git a/ubuntu/omnibook/doc/BUGS b/ubuntu/omnibook/doc/BUGS
new file mode 100644
index 00000000000..c629259c5b4
--- /dev/null
+++ b/ubuntu/omnibook/doc/BUGS
@@ -0,0 +1,17 @@
+Bugs and problems in omnibook module code
+=========================================
+
+* Volume Control buttons on machine (not on docking station) do not generate
+ scancodes on OB500 style models. It is unhandled yet.
+* Setting the LCD brightness on HP OmniBook XE3 GF via /proc/omnibook/lcd
+ is working if you press one of the brightness control keys once after
+ writing the value into /proc/omnibook/lcd.
+* I'm not a native English speaker so text corrections are welcome.
+* obtest can BADLY confuse the in-kernel ACPI code due to its racy
+ implementation.
+* Reenabling wifi adapter after previous disabling is broken on
+ Toshiba Satellite M100 (ipw3945)
+* Real support of ectype 14 is still missing
+* See http://sourceforge.net/tracker/?atid=868542&group_id=174260&func=browse
+ for sf.net bug tracking system.
+
diff --git a/ubuntu/omnibook/doc/COPYING b/ubuntu/omnibook/doc/COPYING
new file mode 100644
index 00000000000..d60c31a97a5
--- /dev/null
+++ b/ubuntu/omnibook/doc/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ubuntu/omnibook/doc/CREDITS b/ubuntu/omnibook/doc/CREDITS
new file mode 100644
index 00000000000..c525a4b548b
--- /dev/null
+++ b/ubuntu/omnibook/doc/CREDITS
@@ -0,0 +1,39 @@
+The module was originally written by
+
+* Soós Péter <sp@osb.hu>
+
+Special thanks to the following persons and/or organisations (without
+particular order):
+
+* Al Stone <ahs3@fc.hp.com> and Linux Systems Operation at HP for lending
+ an HP OmniBook 500 for the project purposes.
+* Pavel Mihaylov <bin@bash.info> for his omke project discovering a lot of
+ OmniBook features, providing some code for XE3 GC machines and testing.
+* Ducrot Bruno <ducrot@poupinou.org> sharing lots of information about
+ embedded controller and related code, added lots of Toshiba support,
+ writing tosh3k code, sending patches etc.
+
+Thanks to the following people (without particular order):
+
+* Al Stone <ahs3@fc.hp.com> for sharing some programming information.
+* Guido Guenther <agx@sigxcpu.org> for initial OneTouch enabling code.
+* Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> for initial
+ OneTouch power management code.
+* Maciek Gorniak <mago@acn.waw.pl> for initial HP Pavilion N5415 detecting
+ code and initial lcd brighness code.
+* Rick Richardson <rickr@mn.rr.com> for some bugfixes and useful patches.
+* Bob McElrath <mcelrath@draal.physics.wisc.edu> for initial Compal ACL00
+ code.
+* Luisimi Moya <luismimoya@eresmas.net> for Acer Aspire 1400 support.
+* Bernhard Kaindl <bernhard.kaindl@gmx.de> for bugfixes and patches
+* Gabriele Vivinetto <gabriele.mailing@rvmgroup.it> for documentation
+ enhancements and testing.
+* Mark Chappell <nslm@nslm.fsnet.co.uk> for building on kernel 2.6.
+* Massimo Dal Zotto <dz@debian.org> for his i8k code.
+* Jonathan A. Buzzard <jonathan@buzzard.org.uk> for his toshiba code.
+* Some others on OmniBook mailing list at
+ http://zurich.ai.mit.edu/mailman/listinfo/omnibook
+ for providing information and testing.
+
+Last but not least thanks to Linus Torvald and more for creating and
+maintaining the Linux kernel.
diff --git a/ubuntu/omnibook/doc/ChangeLog b/ubuntu/omnibook/doc/ChangeLog
new file mode 100644
index 00000000000..38749b9cd76
--- /dev/null
+++ b/ubuntu/omnibook/doc/ChangeLog
@@ -0,0 +1,521 @@
+Changelog file for omnibook package:
+------------------------------------
+
+2.XXXXXXXX Mathieu Bérard <math_b@users.sourceforge.net>
+* DMI signature added:
+ Toshiba Satellite P25 (ectype 11)
+ Toshiba Satellite M60 (ectype 12)
+* Applied patch from Danny Kukawka <dkukawka@suse.de> to
+ fix compiler warning about use uninitialized variable
+* Applied patch from Danny Kukawka <dkukawka@suse.de> to
+ fix build the driver on older kernel versions
+* Applied patches from Azael Avalos <coproscefalo@gmail.com>
+ to add support to Satellite X205 and other laptops based on
+ ICH8
+* Fix build with kernel >= 2.6.30
+
+2.20070211 Mathieu Bérard <math_b@users.sourceforge.net>
+* Disable Acer support, acerhk module should provided better
+ support with a far more complete autodetection database
+ (see http://www2.informatik.hu-berlin.de/~tauber/acerhk/)
+* Fix and improve bluetooth handling for TSM30X class laptops
+ bluetooth now also works for TSA105
+* Implement Volume down,up and Mute buttons polling for ectype 2
+ It was the last missing part from the "omke" module which never
+ got ported to linux 2.6
+* Implement ectype 13 Fn hotkeys handling.
+* DMI signature added:
+ HP Pavilion ze4500 (ectype 7)
+ Toshiba Satellite 1130 (ectype 1)
+ Toshiba Satellite A75 (ectype 12)
+ Toshiba Tecra A4 (ectype 13)
+ Toshiba Satellite A80 (ectype 12)
+ Toshiba Satellite P100 (ectype 14)
+* Split TSM30X (ectype 12) : this ectype was reimplemented and if the
+ new implementation works with Toshiba M40X, M70, M100... it does not
+ (and will never, due to hardware) with Toshiba M30X, the only way
+ to fix this is to split TSM30X (ectype 12) in :
+ -TSM70 (ectype 12) => new implementation (compal.c & acpi.c backends)
+ -TSM30X (ectype 15) => old implementation (legacy backends)
+ This is done by renaming TSM30X to TSM40 and restore old TSM30X
+ The state of the Toshiba M35X is unknown and is assigned to TSM70, one
+ should send a bug report if that fail.
+ Fix bugs 1617818 and 1605278
+* New features for TSM70 class laptops:
+ -Cooling method control (can tune fan behaviour to 'Save power' or
+ to 'Maximize performance') provided in /proc/omnibook/cooling
+ -CPU Throttling status&control (also known as ACPI T-States) should
+ be supported out of the box via /proc/acpi/processor/CPU0/throttling
+ but at least Toshiba Satellite M70 as a deficient ACPI FADT table
+ which prevent than, thus a custom access to ACPI Throttling is
+ provided in /proc/omnibook/throttling
+
+2.20060921 Mathieu Bérard <math_b@users.sourceforge.net>
+* The minimal required kernel version is now 2.6.9 (kref API)
+* Convert semaphore to mutex with fallback for pre 2.6.16 kernel
+* Kill CONFIG_OMNIBOOK_APMEMU and introduce OMNIBOOK_LEGACY:
+ pre-ACPI features now depends on it.
+ Default enabling of ac and battery features also
+ depends on it. It is _disabled_ by default.
+* Introduce ACPI methods execution backend: TSM70 needs it
+ for Display and Wifi/Bluetooth features
+* Expand display and hotkeys features
+* Introduce experimental NbSmi backend for TSM40. It is
+ based on technical documentation provided by Toshiba.
+ Thanks Toshiba !
+* Kill unused omnibook_mem_read/write function for mmio
+ access
+* Cleanup in blank.c fan.c temperature.c
+* Unbreak Pio backend: use request/release_region
+* Introduce bluetooth and wifi frontend features : they allow
+ adapter state querry and control (existence probing, wifi
+ kill switch probing and adapter enabling/disabling).
+ Supported by TSM30X and TSM40
+* Introduce omnibook_backend struct as a uniform way of
+ communication between backend and frontend, this
+ kill omnibook_io_{read/write} and friends.
+* Modify ombibook_feature struct to incorporate pointers
+ to an omnibook_table table and to a omnibook_operation
+ struct which is picked-up from the ectype matching
+ omnibook_table entry upon feature initialization
+* Add muteled resume handler
+* Add touchpad handling for TSM30X
+* Add proper display handling for TSM30X
+* Change all features struct name from foo_feature to
+ foo_driver to kept modpost section mismatch detection
+ silent. Put tbl, init and exit entries to their relevant
+ sections.
+* Many bugfix and dock support for TSM40 by Holger Nelson.
+* Add DMI Signature for Toshiba Satellite 1700-Series, with ectype 10.
+ LCD does not work.
+* Add DMI Signature for Toshiba Equium A110, added with
+ ectype 1, until implementation of a better backend
+* Add DMI Signature for Toshiba _Satellite_ M100, Satellite A70
+ and Tecra S2. added with ectype 12
+* Add DMI Signature for Toshiba Tecra S1, added with
+ ectype 13
+
+2.200608017 Mathieu Bérard <math_b@users.sourceforge.net>
+* Fix bug un omnibook_io_match
+* Fix DMI handling behaviour: we stop on the FIRST matched
+ DMI entry. This is restoring pre-20060806 behaviour.
+ Invert M40 vs. M40X entry position.
+
+2.20060816 Mathieu Bérard <math_b@users.sourceforge.net>
+* Merge from the new-backend branch: Add new backend code
+ (in compal.c) used with TSM30X class laptops:
+ Used for lcd access
+ Used for hotkeys support: now most Fn+key generate a scancode,
+ as well as the wifi kill switch.
+ Warning: tested only on TSM40X an TSM70 laptops.
+* Create omnibook_io_operation struct and omnibook_io_{read/write}
+ funtions to simplify implementation of some simple features.
+ Used with ac display dock and led features.
+* Rename onetouch feature to "hotkeys" which is a vendor neutral name.
+* The minimal required kernel version is now 2.6.9 (kref API)
+* Convert semaphore to mutex with fallback for pre 2.6.16 kernel
+* Kill CONFIG_OMNIBOOK_APMEMU and introduce OMNIBOOK_LEGACY:
+ pre-ACPI features now depends on it.
+ Default enabling of ac and battery features also
+ depends on it. It is _disabled_ by default.
+* Introduce ACPI methods execution backend: TSM70 needs it
+ for Display and Wifi/Bluetooth features
+* Expand display and hotkeys features
+* Introduce experimental NbSmi backend for TSM40. It is
+ based on technical documentation provided by Toshiba.
+ Thanks Toshiba !
+* Kill unused omnibook_mem_read/write function for mmio
+ access
+* Cleanup in blank.c fan.c temperature.c
+* Unbreak Pio backend: use request/release_region
+* Introduce bluetooth and wifi frontend features : they allow
+ adapter state querry and control (existence probing, wifi
+ kill switch probing and adapter enabling/disabling).
+ Supported by TSM30X and TSM40
+* Introduce omnibook_backend struct as a uniform way of
+ communication between backend and frontend, this
+ kill omnibook_io_{read/write} and friends.
+* Modify ombibook_feature struct to incorporate pointers
+ to an omnibook_table table and to a omnibook_operation
+ struct which is picked-up from the ectype matching
+ omnibook_table entry upon feature initialization
+* Add muteled resume handler
+* Add touchpad handling for TSM30X
+* Add proper display handling for TSM30X
+* Change all features struct name from foo_feature to
+ foo_driver to kept modpost section mismatch detection
+ silent. Put tbl, init and exit entries to their relevant
+ sections.
+
+2.20060809 Mathieu Bérard <math_b@users.sourceforge.net>
+* Add dmi info for Toshiba Satellite M40X (Thanks Julien Valroff)
+* Fix two brown paper bag bugs in Debian/Ubuntu support
+
+2.20060806 Mathieu Bérard <math_b@users.sourceforge.net>
+* Make the module linux 2.6 only
+ Kernel versions from 2.6.8 to a least 2.6.17 are supported
+ Code for compatibility with kernels older than 2.6.17 is
+ mostly implemented in compat.h
+* Integrate with Driver Model:
+ register as a platform device and optional
+ registration as a backlight device (2.6.17+ required here)
+* Get rid of deprecated pm_legacy functions
+* Use kernel-provided DMI information:
+ Use kernel-provided dmi_check_system for system identification
+ omnibook_tc_t and omnibook_models_t are merged and converted into a
+ dmi_system_id struct and moved from init.c to laptop.h
+* MODULE_PARAM -> 2.6-style module_parm_*
+* Move some code from "feature".c files back to init.c
+ Interface is provided by the new omnibook_feature struct
+ Enabled features are now in placed in a linked list
+ This eliminate util.c
+ Rationale: Reduce code duplication and create a standard template for features
+* Move dmi and version display into their own file: info.c
+* Remove all (as unneeded) EXPORT_SYMBOL
+* Misc fixes in Makefile
+ Also make more use of Kbuild
+* Use sscanf and simple_stro{u}l for strings parsing instead of custom code
+* Run lindent for better conformance with kernel coding style
+* Add very limited support for some Toshiba M40 (more info needed)
+* Use bitmasks for EC types matching, this change is transparent for the user
+ (e.g. one can still use ectype=num module parameter)
+ Rationale: Reduce the size of the omnibook_feature struct
+* Polish Debian support: Use module-assistant and fix all Lintian warning
+ Fix building against non-running kernel (Thanks to Daniel Gimpelevich)
+* Update documentation and omnibook-integration.patch
+* Fix spinlock usage: they can be used unconditionally as they are automatically
+ optimized out at build-time on UP. This should improve PREEMPT safety
+* Spinlock protect omnibook_mem_* and use ioread8 and iowrite8
+* Fix: Custom EC access function are also used if ACPI is compiled but disabled
+* Cleanup: remove lots of unneeded #ifdef
+* Add a new feature for testers: dump
+ Dump was stolen from the ibm_acpi driver
+ It is disabled by default
+* Bump version to 2.YYYYMMDD
+
+2006-05-15 Thomas Perl <thp@perli.net>
+* Added support for xe4500's "audio mute" led
+
+2006-01-26 Soós Péter <sp@osb.hu>
+* Added support for kernels >= 2.6.15 (pm_legacy.h)
+* Added Toshiba Satellite M30X
+* Added support for Toshiba Satellite M70
+* Added support for HP Pavilion ze4300 series
+* Fixed module unloading on 2.6 series kernels (thanks to
+ math_b@users.sourceforge.net)
+* Changed version number to +%Y%m%d format
+* Added Debian support
+
+2005-02-17 Soós Péter <sp@osb.hu>
+* Fixed Makefile
+* Updated Toshiba 1115 information
+
+2004-12-15 Scott Barnes <reeve@users.sourceforge.net>
+* Added Toshiba Satellite M35X
+
+2004-09-16 Soós Péter <sp@osb.hu>
+* Added INSTALL-2.6 file
+* Little spelling fixes in documentation
+* Little bugfixes
+* Added Compal ACL10
+
+2004-07-01 Soós Péter <sp@osb.hu>
+* Added new technology codes
+* Added some new HP nx9000 detection string
+* Added Toshiba Satellite P20
+
+2004-06-07 Chris Green <cmg@dok.org>
+* Added Toshiba Satellite P15
+
+2004-06-01 Soós Péter <sp@osb.hu>
+* Added Toshiba Satellite 1955
+* Added Toshiba Satellite 2435
+* Added Toshiba Satellite P10 (new ectype)
+* Acer Aspire 1350
+
+2004-01-23 Soós Péter <sp@osb.hu>
+* Added HP Pavilion ze8500 (HP nx9010)
+* fixed PM handler for OneTouch keys and touchpad
+
+2004-01-20 Soós Péter <sp@osb.hu>
+* Only fan status supported on HP OmniBook 4150, XE2 and
+ Fujitsu-Siemens Amilo D, fan control is unsupported
+* #include fixes in ec.c
+
+2004-01-16 Soós Péter <sp@osb.hu>
+* Added fan support for Fujitsu-Siemens Amilo D series laptops
+
+2004-01-14 Soós Péter <sp@osb.hu>
+* Fixed Makefile for kernels 2.6
+* Added Fujitsu-Siemens Amilo D series laptops (new ectype)
+
+2003-12-08 Soós Péter <sp@osb.hu>
+
+* Fixed tecnology code detection
+* Added HP/Compaq nx9005
+* Fixed Makefile for kernel 2.4
+
+2003-11-12 Soós Péter <sp@osb.hu>
+
+* Fixed KERNEL_WARNING in init.c
+
+2003-11-10 Soós Péter <sp@osb.hu>
+
+* Fixed timeout bugs in ec.c
+* Fixed touchpad dependency code for kernel 2.6
+* Added Compaq nx9000
+
+2003-11-10 Mark Chappell <mark@nslm.fsnet.co.uk>
+
+* Added kernel 2.6 support to Makefile
+
+2003-10-23 Soós Péter <sp@osb.hu>
+
+* Totally removed key polling code for kernels >= 2.5.0 but 2.5/2.6 kernels
+ is unsuported yet
+* proc_battery is static
+* Added HP OmniBook 900 B support
+* Added HP OmniBook XE2 support (added new ectype value for it)
+* Added Compaq nx9010
+* Reversed ChangeLog
+* Some documentation changes
+
+2003-08-28 Soós Péter <sp@osb.hu>
+
+* Added Toshiba Satellite 2430
+* Documentation enhancements
+
+2003-04-03 Soós Péter <sp@osb.hu>
+
+* Really fixed __init bug in user parameter code
+* Fixed omnibook_dmi_ident (it was static)
+
+2003-03-31 Soós Péter <sp@osb.hu>
+
+* Fixed HP technology code detection
+* Key polling is disabled by default on XE3GC style machines
+* Fixed PM code in polling.c
+* Added util.c
+* Fixed __init bug in user parameter code
+* Cleaned up ec.h
+* Added Toshiba Satellite 1950 detection
+* Documentation enhancements
+
+2003-03-13 Soós Péter <sp@osb.hu>
+
+* Added HP Pavilion ZU1155 and ZU1175 detection
+
+2003-03-11 Soós Péter <sp@osb.hu>
+
+* Fixed bogus version information
+
+2003-03-06 Ducrot Bruno <ducrot@poupinou.org>
+
+* Fan off hack for XE3GF style machines
+
+2003-03-04 Ducrot Bruno <ducrot@poupinou.org>
+
+* Fixed spinlock problem
+
+2003-02-28 Soós Péter <sp@osb.hu>
+
+* Added /proc/omnibook/version
+* Added OMNIBOOK_ prefix to MODULE_NAME and MODULE_VERSION definitions
+* Fixed bugs in lcd.c (thanks to Bernhard Kaindl <bernhard.kaindl@gmx.de>)
+* Some code tuning and cosmetic changes
+* Fixed OmniBook 4150 support
+
+2003-02-26 Soós Péter <sp@osb.hu>
+
+* Fixed kernel Oops in technology code identification
+* Some minor changes in logging
+
+2003-02-25 Soós Péter <sp@osb.hu>
+
+* Try to identify HP laptops by technology code if machine is unsupported
+* Fixed dmi identification code
+
+2003-02-14 Soós Péter <sp@osb.hu>
+
+* Added HP Pavilion ze4100 support
+* Added HP Pavilion ze4200 support
+* Fixed HP Pavilion xt155 detection
+* Added Acer Aspire 1400 series laptop support
+* Fixed APM status detection bug
+* Cleaned up dmi identification code
+* Removed "Asset Tag:" field from dmi string structure
+
+2003-01-27 Soós Péter <sp@osb.hu>
+
+* Added HP Pavilion N5430 support
+* EC functions are work even if boot parameter acpi=off is given
+* Improved error handling in externally callable functions
+* Fixed kernel integration patch
+* Removed unreliable undocking feature for OB500
+* Fixed HP Pavilion N5415 support
+* Added new format hotkeys sample files
+
+2003-01-09 Ducrot Bruno <ducrot@poupinou.org>
+
+* Added to use ACPI_EC if available
+
+2003-01-09 Soós Péter <sp@osb.hu>
+
+* Fixed reverse console blanking bug on OB5xx and OB6xxx
+* Disabled unreliable undocking feature on OB500
+
+2003-01-08 Ducrot Bruno <ducrot@poupinou.org>
+
+* Added Toshiba Satellite 3000, 3005, 1000, 1005, 1110, 1115, 1900, 1905
+ support
+
+2003-01-08 Soós Péter <sp@osb.hu>
+
+* The ectype values changed again! See the README!
+* Fixed new ectypes detection bug
+* Added OmniBook xe4400 support
+* Added LCD display turn off at console blanking on OB5xx and OB6xxx
+* Documentation fixes
+
+2003-01-07 Soós Péter <sp@osb.hu>
+
+* Fixed bit level negation bug in fan.c
+* Added turn fan on for Toshiba 3000
+* Corrected OmniBook 4150 support code
+
+2003-01-06 Soós Péter <sp@osb.hu>
+
+* Changed ectype values! See the README!
+* Fixed some bugs in obtest utility
+* Fixed second battery status bug in battery.c
+* Added textual descriptions to some functions in /proc/omnibook
+* Fix APM emulation to work when APM support is present but APM power
+ status reporting flagged broken
+* Added docking station support
+* Added fan support
+* Added module parameter: user
+* Added OmniBook xe155, xe4100 and ze4125 support
+* Fan policy moved to /proc/omnibook/fan_policy
+* Reorganized scancode emulation code for XE3 GC
+* Polling of volume buttons on XE3CG style models can be enabled/disabled
+ via /proc/omnibook/key_polling
+* Finished abstraction layer
+* Some minor changes in Rick's model detection code
+* New kernel integration code
+
+2002-12-22 Rick Richardson <rickr@mn.rr.com>
+
+* Added on and off as valid input to /proc/omnibook/lcd, to turn
+ the LCD backlight on and off.
+
+2002-12-15 Rick Richardson <rickr@mn.rr.com>
+
+* Reimplemented model detection so you only have to modify one file
+ to add a new model. features.h is now deprecated.
+* Added the Toshiba Satellite 1115/S103 to the supported models
+* Fixed bug in apmemu.c which caused /proc/apm to report the battery
+ status as critical when the battery was charging.
+
+2002-10-16 Soós Péter <sp@osb.hu>
+
+* Added HP Pavilion N5415 support
+* Corrected HP Pavilion N5441 support
+* Fix values of OB500 type machines in ec.h
+* LCD brightness support added for XE3GC and XE3GF style machines
+* Added HP OmniBook 510 FB support
+* AC adapter status monitoring is working on all machines
+* External display status monitoring is working on all machines
+* CPU temperature monitoring is working on all machines
+* __init functions gone to init.h
+* Added an abstraction layer between the low level, hardware dependent
+ functions and the applications (not yet finished). See omnibook.h for
+ details.
+
+2002-09-20 Soós Péter <sp@osb.hu>
+
+* Using save_flags()/cli() instead spinlocks in ec.c because of laptops do
+ not have more than one CPU (yet ;)). This improves performance and
+ eliminates packet loss in ppp stack
+* The previous version of XE3 GC scancode emulation was buggy: it worked only
+ when ACPI enabled. Current version is working ACPI independent way
+
+2002-09-05 Soós Péter <sp@osb.hu>
+
+* Added secondary battery support (untested, please report!)
+* Added ectype module parameter to specify the type of embedded
+ controller firmware
+* Added some OmniBook XE3 GC support code
+* Added some OmniBook 500 style embedded controller firmware support code
+ (OmniBook 5xx, 6xxx and some Pavilions)
+* Reorganized features matrix (again): the features depends on the embedded
+ controller firmware, not the model
+* Added external display status monitoring on some machine
+* Added scancode emulation on OmniBook XE3 GC
+
+2002-08-14 Soós Péter <sp@osb.hu>
+
+* Added HP OmniBook 6000 EA support (OneTouch only)
+* Added HP OmniBook 6100 EB support (OneTouch only)
+* Fixed Toshiba Satellite 3000-100 detection
+* Fixed timeout and locking bugs in ec.c
+* Added HP Pavilion Notebook ZT1141
+* Reorganized the feature matrix and parameter detection code to make easy
+ to add new features differents machine by machine
+
+2002-08-11 Soós Péter <sp@osb.hu>
+
+* Fixed removing of procfs entries
+* Fixed APM detection
+* Added kernel source integration
+* Fixed __initdata bugs
+* Handling difference between untesed and unsupported features
+
+2002-08-09 Soós Péter <sp@osb.hu>
+
+* Added Compal ACL00 laptop support
+* Updated documentation
+* Added touchpad support
+* Some bugfixes
+* /proc/apm emulation added
+
+2002-08-06 Soós Péter <sp@osb.hu>
+
+* Corrected full charged battery info
+* Added OneTouch handling via procfs
+* Added console blank handling via procfs
+* Added temperature policy handling via procfs
+* Corrected the bug in DMI code to report the serial number
+* Added module parameter support
+* Added HP Pavilion Notebook N5490, ZT1195 (and probably other Pavilions)
+
+2002-07-17 Soós Péter <sp@osb.hu>
+
+* Improved error handling
+* Some text corrections
+* Added Toshiba Satellite 3000-100 support
+* Some code tuning
+* Added omnibook prefix for variables and functions to prevent conflicts
+ with another code
+* Added /proc filesystem support
+* Added battery status monitoring
+* Added CPU temperature monitoring
+
+2002-06-03 Soós Péter <sp@osb.hu>
+
+* Some code tuning
+
+2002-05-07 Soós Péter <sp@osb.hu>
+
+* Added missing #include <linux/sched.h> to main.c
+* Some text corrections
+* Added HP OmniBook 500 FA support (OneTouch only)
+
+2002-05-06 Soós Péter <sp@osb.hu>
+
+* LCD display turn off at console blanking added
+* Code cleanup
+
+2002-05-02 Soós Péter <sp@osb.hu>
+
+* The first release of omnibook module
+* OneTouch button support
diff --git a/ubuntu/omnibook/doc/README b/ubuntu/omnibook/doc/README
new file mode 100644
index 00000000000..e8fb7cdfd97
--- /dev/null
+++ b/ubuntu/omnibook/doc/README
@@ -0,0 +1,42 @@
+===============================================================
+Kernel Support for HP OmniBooks, Pavilions and Compal laptops
+===============================================================
+
+This package is intended to provide Linux kernel support for many laptops such as:
+- HP OmniBook and Pavilion
+- Toshiba Satellite and Tecra which are not supported by the toshiba_acpi module
+- Compal ACL00
+- Many laptops manufactured by Compal Electronics, Inc as ODM
+
+Supported features depends on the exact laptop model but may include:
+- Enabling hotkey buttons
+- Console (LCD display) blanking
+- Battery status monitoring.
+- Fan and fan policy support
+- Touchpad control
+- AC Adapter status monitoring
+- External display monitors status monitoring and control
+- LCD brightness (backlight) monitoring and control
+- Docking station/port replicator status
+- CPU temperature monitoring
+- Mute LED monitoring and control
+- Wifi and Bluetooth adapters monitoring and control
+- Cooling method control
+- CPU Throttling control
+
+Useful links:
+
+Full documentation (HOWTO, Installation instructions, Supported laptops list... ):
+http://omnibook.sourceforge.net/doku.php?id=start
+
+Sourceforge project page:
+http://sourceforge.net/projects/omnibook
+
+Other links not related to the project:
+
+For HP Omnibook specific issues ou can see the OmniBook mailing list:
+http://zurich.ai.mit.edu/mailman/listinfo/omnibook
+
+or the Toshiba linux mailing list:
+http://linux.toshiba-dme.co.jp/linux/
+
diff --git a/ubuntu/omnibook/dock.c b/ubuntu/omnibook/dock.c
new file mode 100644
index 00000000000..3264f70e4c6
--- /dev/null
+++ b/ubuntu/omnibook/dock.c
@@ -0,0 +1,84 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_dock_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ u8 dock;
+ int retval;
+
+ if ((retval = backend_byte_read(io_op, &dock)))
+ return retval;
+
+ len += sprintf(buffer + len, "Laptop is %s\n", (dock) ? "docked" : "undocked");
+
+ return len;
+}
+
+static int omnibook_dock_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+
+ switch (*buffer) {
+ case '0':
+ retval = backend_byte_write(io_op, 0);
+ break;
+ case '1':
+ retval = backend_byte_write(io_op, 1);
+ break;
+ default:
+ retval = -EINVAL;
+ }
+
+ return retval;
+}
+
+static struct omnibook_feature dock_driver;
+
+static int __init omnibook_dock_init(struct omnibook_operation *io_op)
+{
+ /* writing is only supported on ectype 13 */
+ if(!(omnibook_ectype & TSM40))
+ dock_driver.write = NULL;
+
+ return 0;
+}
+
+static struct omnibook_tbl dock_table[] __initdata = {
+ {XE3GF, SIMPLE_BYTE(EC, XE3GF_CSPR, XE3GF_CSPR_MASK)},
+ {OB500 | OB510 | OB6000 | OB6100, SIMPLE_BYTE(EC, OB500_STA1, OB500_DCKS_MASK)},
+ {OB4150, SIMPLE_BYTE(EC, OB4150_DCID, 0)},
+ {TSM40, {SMI, SMI_GET_DOCK, SMI_SET_DOCK, 0, 0, 0}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature dock_driver = {
+ .name = "dock",
+ .enabled = 0,
+ .init = omnibook_dock_init,
+ .read = omnibook_dock_read,
+ .write = omnibook_dock_write,
+ .ectypes = XE3GF | OB500 | OB510 | OB6000 | OB6100 | OB4150 | TSM40,
+ .tbl = dock_table,
+};
+
+module_param_named(dock, dock_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(dock, "Use 0 to disable, 1 to enable docking station support");
+/* End of file */
diff --git a/ubuntu/omnibook/dump.c b/ubuntu/omnibook/dump.c
new file mode 100644
index 00000000000..ff959e96a8d
--- /dev/null
+++ b/ubuntu/omnibook/dump.c
@@ -0,0 +1,107 @@
+/*
+ * dump.c - Raw dump of EC register, stolen from ibm_acpi.c
+ *
+ *
+ * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static u8 ecdump_regs[256];
+
+static int ecdump_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int i, j;
+ u8 v;
+
+ len +=
+ sprintf(buffer + len,
+ "EC " " +00 +01 +02 +03 +04 +05 +06 +07"
+ " +08 +09 +0a +0b +0c +0d +0e +0f\n");
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ for (i = 0; i < 255; i += 16) {
+ len += sprintf(buffer + len, "EC 0x%02x:", i);
+ for (j = 0; j < 16; j++) {
+ io_op->read_addr = i +j;
+ if (__backend_byte_read(io_op, &v))
+ break;
+ if (v != ecdump_regs[i + j])
+ len += sprintf(buffer + len, " *%02x", v);
+ else
+ len += sprintf(buffer + len, " %02x", v);
+ ecdump_regs[i + j] = v;
+ }
+ len += sprintf(buffer + len, "\n");
+ if (j != 16)
+ break;
+ }
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ /* These are way too dangerous to advertise openly... */
+#if 0
+ len +=
+ sprintf(buffer + len,
+ "commands:\t0x<offset> 0x<value>" " (<offset> is 00-ff, <value> is 00-ff)\n");
+ len +=
+ sprintf(buffer + len,
+ "commands:\t0x<offset> <value> " " (<offset> is 00-ff, <value> is 0-255)\n");
+#endif
+ return len;
+}
+
+static int ecdump_write(char *buffer, struct omnibook_operation *io_op)
+{
+
+ int i, v;
+
+ if (sscanf(buffer, "0x%x 0x%x", &i, &v) == 2) {
+ /* i and v set */
+ } else if (sscanf(buffer, "0x%x %u", &i, &v) == 2) {
+ /* i and v set */
+ } else
+ return -EINVAL;
+ if (i >= 0 && i < 256 && v >= 0 && v < 256) {
+ io_op->write_addr = i;
+ return backend_byte_write(io_op, v);
+ } else
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct omnibook_tbl dump_table[] __initdata = {
+ {ALL_ECTYPES, {EC,}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature dump_driver = {
+ .name = "dump",
+ .enabled = 0,
+ .read = ecdump_read,
+ .write = ecdump_write,
+ .tbl = dump_table,
+};
+
+module_param_named(dump, dump_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(dump, "Use 0 to disable, 1 to enable embedded controller register dump support");
+/* End of file */
diff --git a/ubuntu/omnibook/ec.c b/ubuntu/omnibook/ec.c
new file mode 100644
index 00000000000..714ce4ac0d9
--- /dev/null
+++ b/ubuntu/omnibook/ec.c
@@ -0,0 +1,188 @@
+/*
+ * ec.c -- low level functions to access Embedded Controller,
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include "hardware.h"
+
+/*
+ * Interrupt control
+ */
+
+static DEFINE_SPINLOCK(omnibook_ec_lock);
+
+/*
+ * 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 */
+
+
+/*
+ * Embedded controller commands
+ */
+
+#define OMNIBOOK_EC_CMD_READ 0x80
+#define OMNIBOOK_EC_CMD_WRITE 0x81
+
+/*
+ * 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
+ * Decide at run-time if we can use the much cleaner ACPI EC driver instead of
+ * this implementation, this is the case if ACPI has been compiled and is not
+ * disabled.
+ */
+
+static int omnibook_ec_read(const struct omnibook_operation *io_op, u8 * data)
+{
+ int retval;
+
+#ifdef CONFIG_ACPI_EC
+ if (likely(!acpi_disabled)) {
+ retval = ec_read((u8) io_op->read_addr, data);
+ if (io_op->read_mask)
+ *data &= io_op->read_mask;
+// dprintk("ACPI EC read at %lx success %i.\n", io_op->read_addr, retval);
+ return retval;
+ }
+#endif
+ spin_lock_irq(&omnibook_ec_lock);
+ 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((u8) io_op->read_addr, OMNIBOOK_EC_DATA);
+ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_OBF);
+ if (retval)
+ goto end;
+ *data = inb(OMNIBOOK_EC_DATA);
+ if (io_op->read_mask)
+ *data &= io_op->read_mask;
+ end:
+ spin_unlock_irq(&omnibook_ec_lock);
+// dprintk("Custom EC read at %lx success %i.\n", io_op->read_addr, retval);
+ return retval;
+}
+
+/*
+ * Write to the embedded controller:
+ * If OMNIBOOK_LEGACY is set, decide at run-time if we can use the much cleaner
+ * ACPI EC driver instead of this legacy implementation.
+ * This is the case if ACPI has been compiled and is not
+ * disabled.
+ * If OMNIBOOK_LEGACY is unset, we drop our custoim implementation
+ */
+
+static int omnibook_ec_write(const struct omnibook_operation *io_op, u8 data)
+{
+ int retval;
+
+#ifdef CONFIG_ACPI_EC
+ if (likely(!acpi_disabled)) {
+ retval = ec_write((u8) io_op->write_addr, data);
+// dprintk("ACPI EC write at %lx success %i.\n", io_op->write_addr, retval);
+ return retval;
+ }
+#endif
+
+ spin_lock_irq(&omnibook_ec_lock);
+ 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((u8) io_op->write_addr, OMNIBOOK_EC_DATA);
+ retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF);
+ if (retval)
+ goto end;
+ outb(data, OMNIBOOK_EC_DATA);
+ end:
+ spin_unlock_irq(&omnibook_ec_lock);
+// dprintk("Custom EC write at %lx success %i.\n", io_op->write_addr, retval);
+ return retval;
+}
+
+static int omnibook_ec_display(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval;
+ u8 raw_state;
+
+ retval = __backend_byte_read(io_op, &raw_state);
+ if (retval < 0)
+ return retval;
+
+ *state = !!(raw_state) & DISPLAY_CRT_DET;
+
+ return DISPLAY_CRT_DET;
+}
+
+/*
+ * Backend interface declarations
+ */
+
+struct omnibook_backend ec_backend = {
+ .name = "ec",
+ .byte_read = omnibook_ec_read,
+ .byte_write = omnibook_ec_write,
+ .display_get = omnibook_ec_display,
+};
+
+/* End of file */
diff --git a/ubuntu/omnibook/fan.c b/ubuntu/omnibook/fan.c
new file mode 100644
index 00000000000..d8129935dee
--- /dev/null
+++ b/ubuntu/omnibook/fan.c
@@ -0,0 +1,183 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "hardware.h"
+
+static const struct omnibook_operation ctmp_io_op = { EC, XE3GF_CTMP, 0, 0, 0, 0 };
+static const struct omnibook_operation fot_io_op = { EC, XE3GF_FOT, XE3GF_FOT, 0, 0, 0 };
+
+static int omnibook_get_fan(struct omnibook_operation *io_op)
+{
+ u8 fan;
+ int retval;
+
+ if ((retval = backend_byte_read(io_op, &fan)))
+ return retval;
+
+ /*
+ * For most models the reading is a bool
+ * It as to be inverted on all but OB6000|OB6100|OB4150|AMILOD
+ * TSP10|XE3GF|TSX205 return an integer
+ */
+
+ if (omnibook_ectype & (TSP10 | XE3GF | TSX205))
+ retval = fan;
+ else if (omnibook_ectype & (OB6000 | OB6100 | OB4150 | AMILOD))
+ retval = !!fan;
+ else
+ retval = !fan;
+
+ return retval;
+}
+
+static int omnibook_fan_on(struct omnibook_operation *io_op)
+{
+ return omnibook_apply_write_mask(io_op, 1);
+}
+
+static int omnibook_fan_off(struct omnibook_operation *io_op)
+{
+ int i, retval = 0;
+
+ if (!(omnibook_ectype & (XE3GF | TSP10 | TSX205))) {
+ retval = omnibook_apply_write_mask(io_op, 0);
+ return retval;
+ } else {
+ /*
+ * Special handling for XE3GF & TSP10
+ */
+ u8 fot, temp, fan;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ retval = __backend_byte_read(io_op, &fan);
+
+ /* error or fan is already off */
+ if (retval || !fan)
+ goto out;
+
+ /* now we set FOT to current temp, then reset to initial value */
+ if ((retval = __backend_byte_read(&fot_io_op, &fot)))
+ goto out;
+ if ((retval = __backend_byte_read(&ctmp_io_op, &temp)))
+ goto out;
+
+ /* Wait for no longer than 250ms (this is arbitrary). */
+ for (i = 0; i < 250; i++) {
+ __backend_byte_write(&fot_io_op, temp);
+ mdelay(1);
+ __backend_byte_read(io_op, &fan);
+ if (!fan) /* Fan is off */
+ break;
+ }
+ __backend_byte_write(&fot_io_op, fot);
+
+ if(i == 250 ) {
+ printk(O_ERR "Attempt to switch off the fan failed.\n");
+ retval = -EIO;
+ }
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ }
+
+
+ return retval;
+}
+
+static int omnibook_fan_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int fan;
+ int len = 0;
+ char *str;
+
+ fan = omnibook_get_fan(io_op);
+ if (fan < 0)
+ return fan;
+ str = (fan) ? "on" : "off";
+
+ if (fan > 1)
+ len += sprintf(buffer + len, "Fan is %s (level %d)\n", str, fan);
+ else
+ len += sprintf(buffer + len, "Fan is %s\n", str);
+
+ return len;
+}
+
+static int omnibook_fan_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+
+ switch (*buffer) {
+ case '0':
+ retval = omnibook_fan_off(io_op);
+ break;
+ case '1':
+ retval = omnibook_fan_on(io_op);
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+static struct omnibook_feature fan_driver;
+
+static int __init omnibook_fan_init(struct omnibook_operation *io_op)
+{
+ /*
+ * OB4150
+ * XE2
+ * AMILOD
+ * They only support fan reading
+ */
+ if (omnibook_ectype & (OB4150 | XE2 | AMILOD))
+ fan_driver.write = NULL;
+ return 0;
+}
+
+static struct omnibook_tbl fan_table[] __initdata = {
+ {XE3GF | TSP10 | TSM70 | TSX205, {EC, XE3GF_FSRD, XE3GF_FSRD, 0, XE3GF_FAN_ON_MASK, 0}},
+ {OB500,
+ {PIO, OB500_GPO1, OB500_GPO1, OB500_FAN_OFF_MASK, -OB500_FAN_ON_MASK, OB500_FAN_OFF_MASK}},
+ {OB510,
+ {PIO, OB510_GPIO, OB510_GPIO, OB510_FAN_OFF_MASK, -OB510_FAN_ON_MASK, OB510_FAN_OFF_MASK}},
+ {OB6000 | OB6100,
+ {EC, OB6000_STA1, OB6000_STA1, OB6000_FAN_MASK, OB6000_FAN_MASK, -OB6000_FAN_MASK}},
+ {OB4150 | AMILOD, {EC, OB4150_STA1, 0, OB4150_FAN_MASK, 0, 0}},
+ {XE2, {PIO, OB500_GPO1, 0, XE2_FAN_MASK, 0, 0}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature fan_driver = {
+ .name = "fan",
+ .enabled = 1,
+ .read = omnibook_fan_read,
+ .write = omnibook_fan_write,
+ .init = omnibook_fan_init,
+ .ectypes = XE3GF | OB500 | OB510 | OB6000 | OB6100 | OB4150 | XE2 | AMILOD | TSP10 | TSX205,
+ .tbl = fan_table,
+};
+
+module_param_named(fan, fan_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(fan, "Use 0 to disable, 1 to enable fan status monitor and control");
+/* End of file */
diff --git a/ubuntu/omnibook/fan_policy.c b/ubuntu/omnibook/fan_policy.c
new file mode 100644
index 00000000000..67915ffedbb
--- /dev/null
+++ b/ubuntu/omnibook/fan_policy.c
@@ -0,0 +1,188 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/ctype.h>
+#include "hardware.h"
+
+/*
+ * 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 8
+#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 */
+
+static const 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,
+};
+
+static int omnibook_get_fan_policy(struct omnibook_operation *io_op, u8 *fan_policy)
+{
+ int retval ;
+ int i;
+
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ io_op->read_addr = XE3GF_FOT + i;
+ if ((retval = __backend_byte_read(io_op, &fan_policy[i])))
+ return retval;
+ }
+
+ return 0;
+}
+
+static int omnibook_set_fan_policy(struct omnibook_operation *io_op, const u8 *fan_policy)
+{
+ int retval;
+ int i;
+
+ if (fan_policy[0] > OMNIBOOK_FOT_MAX)
+ return -EINVAL;
+
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ if ((fan_policy[i] > fan_policy[i + 1])
+ || (fan_policy[i] < OMNIBOOK_FAN_MIN)
+ || (fan_policy[i] > OMNIBOOK_FAN_MAX))
+ return -EINVAL;
+ }
+ for (i = 0; i < OMNIBOOK_FAN_LEVELS; i++) {
+ io_op->write_addr = XE3GF_FOT + i;
+ if ((retval = __backend_byte_write(io_op, fan_policy[i])))
+ return retval;
+ }
+
+ return 0;
+}
+
+static int omnibook_fan_policy_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+ int len = 0;
+ u8 i;
+ u8 fan_policy[OMNIBOOK_FAN_LEVELS];
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ retval = omnibook_get_fan_policy(io_op, &fan_policy[0]);
+
+ mutex_unlock(&io_op->backend->mutex);
+
+ if(retval)
+ return retval;
+
+ len += sprintf(buffer + len, "Fan off temperature: %2d C\n", fan_policy[0]);
+ len += sprintf(buffer + len, "Fan on temperature: %2d C\n", fan_policy[1]);
+ for (i = 2; i < OMNIBOOK_FAN_LEVELS; i++) {
+ len +=
+ sprintf(buffer + len, "Fan level %1d temperature: %2d C\n", i,
+ fan_policy[i]);
+ }
+ len += sprintf(buffer + len, "Minimal temperature to set: %2d C\n", OMNIBOOK_FAN_MIN);
+ len += sprintf(buffer + len, "Maximal temperature to set: %2d C\n", OMNIBOOK_FAN_MAX);
+
+ return len;
+}
+
+static int omnibook_fan_policy_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int n = 0;
+ char *b;
+ char *endp;
+ int retval;
+ int temp;
+ u8 fan_policy[OMNIBOOK_FAN_LEVELS];
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if ((retval = omnibook_get_fan_policy(io_op, &fan_policy[0])))
+ goto out;
+
+ /*
+ * Could also be done much simpler using sscanf(,"%u %u ...
+ * but this would hardcode OMNIBOOK_FAN_LEVELS.
+ * The parsed format is "%u " repeated OMNIBOOK_FAN_LEVELS+1 times
+ */
+
+ b = buffer;
+ do {
+ dprintk("n=[%i] b=[%s]\n", n, b);
+ if (n > OMNIBOOK_FAN_LEVELS) {
+ retval = -EINVAL;
+ goto out;
+ }
+ if (!isspace(*b)) {
+ temp = simple_strtoul(b, &endp, 10);
+ if (endp != b) { /* there was a match */
+ fan_policy[n++] = temp;
+ b = endp;
+ } else {
+ retval = -EINVAL;
+ goto out;
+ }
+ } else
+ b++;
+ } while ((*b != '\0') && (*b != '\n'));
+
+ /* A zero value set the defaults */
+ if ((fan_policy[0] == 0) && (n == 1))
+ retval = omnibook_set_fan_policy(io_op, &fan_defaults[0]);
+ else
+ retval = omnibook_set_fan_policy(io_op, &fan_policy[0]);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static struct omnibook_tbl fan_policy_table[] __initdata = {
+ {XE3GF, {EC,}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature fan_policy_driver = {
+ .name = "fan_policy",
+ .enabled = 1,
+ .read = omnibook_fan_policy_read,
+ .write = omnibook_fan_policy_write,
+ .ectypes = XE3GF,
+ .tbl = fan_policy_table,
+};
+
+module_param_named(fan_policy, fan_policy_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(fan_policy, "Use 0 to disable, 1 to enable fan control policy support");
+/* End of file */
diff --git a/ubuntu/omnibook/hardware.h b/ubuntu/omnibook/hardware.h
new file mode 100644
index 00000000000..aa12a4363f8
--- /dev/null
+++ b/ubuntu/omnibook/hardware.h
@@ -0,0 +1,582 @@
+/*
+ * hardware.h -- low level definitions to access Embedded Controller and co.
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006-2007
+ */
+
+#include <linux/acpi.h>
+#include "compat.h"
+
+/*
+ * Quite ugly:
+ * on_mask and off_maks are also used to store the i8042 data for kbc backend.
+ * an union seemed overkilled
+ */
+
+struct omnibook_backend;
+
+struct omnibook_operation {
+ struct omnibook_backend *backend;
+ unsigned long read_addr; /* address for data reading */
+ unsigned long write_addr; /* address for data writing */
+ u8 read_mask; /* read mask */
+ int on_mask; /* mask to set (pos value) or unset (neg value) to put feature in on state */
+ int off_mask; /* mask to set (pos value) or unset (neg value) to put feature in off state */
+};
+
+#define COMMAND(backend,data_on,data_off) { backend, 0, 0, 0, data_on, data_off }
+#define SIMPLE_BYTE(backend,addr,mask) { backend, addr, addr, mask, 0, 0 }
+
+struct omnibook_tbl {
+ enum omnibook_ectype_t ectypes;
+ struct omnibook_operation io_op;
+};
+
+/*
+ * Backend interface definition
+ */
+
+struct omnibook_backend {
+ const char *name; /* backend name */
+ struct mutex mutex; /* serializes all access to backend functions */
+ const unsigned int hotkeys_read_cap; /* hotkey probing mask */
+ const unsigned int hotkeys_write_cap; /* hotkey setting mask */
+
+ /* Public data fields, access with mutex held */
+ unsigned int hotkeys_state; /* saved hotkeys state */
+ unsigned int touchpad_state; /* saved touchpad state */
+ unsigned int muteled_state; /* saved muteled state */
+ unsigned int cooling_state; /* saved cooling method state */
+
+ /* Public function pointers */
+ int (*init) (const struct omnibook_operation *);
+ void (*exit) (const struct omnibook_operation *);
+ int (*byte_read) (const struct omnibook_operation *, u8 *);
+ int (*byte_write) (const struct omnibook_operation *, u8);
+ int (*aerial_get) (const struct omnibook_operation *, unsigned int *);
+ int (*aerial_set) (const struct omnibook_operation *, unsigned int);
+ int (*hotkeys_get) (const struct omnibook_operation *, unsigned int *);
+ int (*hotkeys_set) (const struct omnibook_operation *, unsigned int);
+ int (*display_get) (const struct omnibook_operation *, unsigned int *);
+ int (*display_set) (const struct omnibook_operation *, unsigned int);
+ int (*throttle_get) (const struct omnibook_operation *, unsigned int *);
+ int (*throttle_set) (const struct omnibook_operation *, unsigned int);
+
+ /* Private fields, never to be accessed outside backend code */
+ struct kref kref; /* Reference counter of this backend */
+ void *data; /* private data pointer */
+ int already_failed; /* Backend init already failed at least once */
+};
+
+extern struct omnibook_backend kbc_backend;
+extern struct omnibook_backend pio_backend;
+extern struct omnibook_backend ec_backend;
+extern struct omnibook_backend acpi_backend;
+extern struct omnibook_backend nbsmi_backend;
+extern struct omnibook_backend compal_backend;
+
+#define KBC &kbc_backend
+#define PIO &pio_backend
+#define EC &ec_backend
+#define ACPI &acpi_backend
+#define SMI &nbsmi_backend
+#define CDI &compal_backend
+
+int __omnibook_apply_write_mask(const struct omnibook_operation *io_op, int toggle);
+int __omnibook_toggle(const struct omnibook_operation *io_op, int toggle);
+
+/*
+ * Lock helper functions. Defines locking and __prefixed non locking variants.
+ */
+
+#define helper_func(func) \
+static inline int backend_##func##_get(const struct omnibook_operation *io_op, unsigned int *data) \
+{ \
+ int retval; \
+ if(mutex_lock_interruptible(&io_op->backend->mutex)) \
+ return -ERESTARTSYS; \
+ retval = io_op->backend->func##_get(io_op, data); \
+ mutex_unlock(&io_op->backend->mutex); \
+ return retval; \
+} \
+static inline int backend_##func##_set(const struct omnibook_operation *io_op, unsigned int data) \
+{ \
+ int retval; \
+ if(mutex_lock_interruptible(&io_op->backend->mutex)) \
+ return -ERESTARTSYS; \
+ retval = io_op->backend->func##_set(io_op, data); \
+ mutex_unlock(&io_op->backend->mutex); \
+ return retval; \
+}\
+static inline int __backend_##func##_get(const struct omnibook_operation *io_op, unsigned int *data) \
+{ \
+ int retval; \
+ WARN_ON(!mutex_is_locked(&io_op->backend->mutex)); \
+ retval = io_op->backend->func##_get(io_op, data); \
+ return retval; \
+} \
+static inline int __backend_##func##_set(const struct omnibook_operation *io_op, unsigned int data) \
+{ \
+ int retval; \
+ WARN_ON(!mutex_is_locked(&io_op->backend->mutex)); \
+ retval = io_op->backend->func##_set(io_op, data); \
+ return retval; \
+}
+
+helper_func(aerial)
+helper_func(hotkeys)
+helper_func(display)
+helper_func(throttle)
+
+static inline int backend_byte_read(const struct omnibook_operation *io_op, u8 *data)
+{
+ int retval;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+ retval = io_op->backend->byte_read(io_op, data);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static inline int backend_byte_write(const struct omnibook_operation *io_op, u8 data)
+{
+ int retval;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+ retval = io_op->backend->byte_write(io_op, data);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static inline int __backend_byte_read(const struct omnibook_operation *io_op, u8 *data)
+{
+ int retval;
+ WARN_ON(!mutex_is_locked(&io_op->backend->mutex));
+ retval = io_op->backend->byte_read(io_op, data);
+ return retval;
+}
+
+static inline int __backend_byte_write(const struct omnibook_operation *io_op, u8 data)
+{
+ int retval;
+ WARN_ON(!mutex_is_locked(&io_op->backend->mutex));
+ retval = io_op->backend->byte_write(io_op, data);
+ return retval;
+}
+
+static inline int omnibook_apply_write_mask(const struct omnibook_operation *io_op, int toggle)
+{
+ int retval;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+ retval = __omnibook_apply_write_mask(io_op, toggle);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static inline int omnibook_toggle(const struct omnibook_operation *io_op, int toggle)
+{
+ int retval;
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+ retval = __omnibook_toggle(io_op, toggle);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Timeout in ms for sending to controller
+ */
+
+#define OMNIBOOK_TIMEOUT 250
+
+
+/*
+ * 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 1 status, 3 bit */
+#define XE3GC_BPR1 0x51 /* Battery 1 present rate, 16 bit ? */
+#define XE3GC_BRC1 0x53 /* Battery 1 remaining capacity, 16 bit */
+#define XE3GC_BPV1 0x55 /* Battery 1 present voltage, 16 bit */
+#define XE3GC_BDV1 0x57 /* Battery 1 design voltage 16 bit */
+#define XE3GC_BDC1 0x59 /* Battery 1 design capacity 16 bit */
+#define XE3GC_BTY1 0x5A /* Battery 1 type, 1 bit ? */
+#define XE3GC_BTP1 0x5B /* Battery 1 ?, 1 bit */
+#define XE3GC_BSN1 0x5C /* Battery 1 serial number, 8 bit ? */
+#define XE3GC_BMF1 0x5D /* Battery 1 ?,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 */
+
+/*
+ * Toshiba Satellite A105 values and mask
+ */
+
+#define A105_BNDT 0xA3 /* LCD brightness */
+#define A105_BNDT_MASK 0x0F
+
+/*
+ * Fujitsu Amilo D values
+ */
+
+#define AMILOD_TMP 0x28 /* CPU tempetature, 8 bit */
+#define AMILOD_STA1 0x30 /* Various status bits */
+#define AMILOD_BAT 0x3E /* Battery present status */
+#define AMILOD_BDC0 0x40 /* Battery 0 design capacity 16 bit */
+#define AMILOD_BDV0 0x42 /* Battery 0 design voltage 16 bit */
+#define AMILOD_BTY0 0x44 /* Battery 0 type, 1 bit ? */
+#define AMILOD_BST0 0x45 /* Battery 0 status, 3 bit */
+#define AMILOD_BPR0 0x46 /* Battery 0 present rate, 16 bit ? */
+#define AMILOD_BRC0 0x48 /* Battery 0 remaining capacity, 16 bit */
+#define AMILOD_BPV0 0x4A /* Battery 0 present voltage, 16 bit */
+#define AMILOD_BTP0 0x4C /* Battery 0 ?, 1 bit */
+#define AMILOD_BDC1 0x50 /* Battery 1 design capacity 16 bit */
+#define AMILOD_BDV1 0x52 /* Battery 1 design voltage 16 bit */
+#define AMILOD_BTY1 0x54 /* Battery 1 type, 1 bit ? */
+#define AMILOD_BST1 0x55 /* Battery 1 status, 3 bit */
+#define AMILOD_BPR1 0x56 /* Battery 1 present rate, 16 bit ? */
+#define AMILOD_BRC1 0x58 /* Battery 1 remaining capacity, 16 bit */
+#define AMILOD_BPV1 0x5A /* Battery 1 present voltage, 16 bit */
+#define AMILOD_BTP1 0x5C /* Battery 1 ?, 1 bit */
+#define AMILOD_CBRG 0x6F /* LCD brightness, 4 bit */
+
+/*
+ * Bitmasks for sub byte values
+ */
+
+#define AMILOD_ADP_MASK 0x40 /* AC acapter status */
+#define AMILOD_BAT0_MASK 0x01 /* Battery 0 present */
+#define AMILOD_BAT1_MASK 0x02 /* Battery 1 present */
+#define AMILOD_BTY_MASK 0x01 /* Type: Ni-MH or Li-Ion */
+#define AMILOD_BST_MASK_DSC 0x01 /* Discarging */
+#define AMILOD_BST_MASK_CHR 0x02 /* Charging */
+#define AMILOD_BST_MASK_CRT 0x04 /* Critical */
+#define AMILOD_CBRG_MASK 0x0F /* LCD brightness */
+
+/*
+ * 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 touchpad */
+#define OMNIBOOK_KBC_CMD_TOUCHPAD_DISABLE 0xA9 /* Disables touchpad */
+#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_MUTELED_ON 0x94 /* Turns (xe4500) Mute LED on */
+#define OMNIBOOK_KBC_CMD_MUTELED_OFF 0x95 /* Turns (xe4500) Mute LED 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
+
+/*
+ * Toshiba Satellite A105 values and mask
+ */
+
+#define A105_BNDT 0xA3 /* LCD brightness */
+#define A105_BNDT_MASK 0x0F
+
+/*
+ * Index and values for Command/Data/Index interface
+ * Notice similitudes with commands code for kbc
+ */
+
+#define TSM70_FN_INDEX 0x45
+#define TSM70_FN_ENABLE 0x75
+#define TSM70_FN_DISABLE 0x74
+#define TSM70_HOTKEYS_INDEX 0x59
+#define TSM70_HOTKEYS_ENABLE 0x90
+#define TSM70_HOTKEYS_DISABLE 0x91
+#define TSM70_LCD_READ 0x5C
+#define TSM70_LCD_WRITE 0x5D
+#define TSM70_TOUCHPAD_ON 0x80
+#define TSM70_TOUCHPAD_OFF 0x81
+#define TSM100_BLANK_INDEX 0x59
+#define TSM100_LCD_ON 0xe1
+#define TSM100_LCD_OFF 0xe2
+#define TSM70_COOLING_OFFSET 0xb0
+#define TSM70_COOLING_POWERSAVE 0x0
+#define TSM70_COOLING_PERF 0x2
+
+/* Toshiba SMI funtions and constants*/
+#define SMI_FN_PRESSED 0x8f
+#define SMI_SET_LCD_BRIGHTNESS 0xa2
+#define SMI_GET_LCD_BRIGHTNESS 0xa3
+#define SMI_GET_KILL_SWITCH 0xa4
+#define SMI_SET_AERIAL 0xa5
+#define SMI_GET_AERIAL 0xa6
+#define SMI_SET_DISPLAY_STATE 0xa7
+#define SMI_GET_DISPLAY_STATE 0xa8
+#define SMI_SET_FN_INTERFACE 0xa9
+#define SMI_GET_FN_INTERFACE 0xaa
+#define SMI_GET_FN_LAST_SCAN 0xab
+#define SMI_SET_DOCK 0xac /* Undocumented */
+#define SMI_GET_DOCK 0xad /* Undocumented */
+#define SMI_SET_FN_F5_INTERFACE 0xc2
+
+#define SMI_FN_KEYS_MASK 0x01
+#define SMI_STICK_KEYS_MASK 0x02
+#define SMI_FN_TWICE_LOCK_MASK 0x04
+#define SMI_FN_DOCK_MASK 0x08
+
+#define SMI_FN_SCAN 0x6d /* Fn key scancode */
+#define SMI_DOCK_SCAN 0x6e /* Dock scancode */
+
+/* Toshiba HCI method and constants */
+#define HCI_METHOD "SPFC"
+#define HCI_WORDS 6
+
+#define HCI_GET 0xfe00
+#define HCI_SET 0xff00
+
+#define HCI_HOTKEY_EVENT 0x001e
+#define HCI_RF_CONTROL 0x0056
+
+#define HCI_ENABLE 0x0001
+#define HCI_DISABLE 0x0000
+
+#define HCI_WIRELESS_CHECK 0x0001
+#define HCI_WIRELESS_POWER 0x0200
+
+#define HCI_SUCCESS 0x0000
+#define HCI_FAILURE 0x1000
+#define HCI_NOT_SUPPORTED 0x8000
+
+/* Toshiba Satellite X205 methods */
+#define TSX205_EVENTS_METHOD "INFO"
+#define TSX205_NOTIFY_METHOD "NTFY"
+#define TSX205_KILLSW_METHOD "KLSW"
+#define TSX205_SLIVDO_METHOD "CSLI"
+
+#define ACPI_FN_MASK 0x01
+#define ACPI_FN_SCAN 0x6e /* Fn key scancode */
+
+/* HCI key definitions */
+#define HCI_FN_RELEASED 0x100
+#define HCI_MUTE 0x101
+#define HCI_1 0x102
+#define HCI_2 0x103
+#define HCI_SPACE 0x139
+#define HCI_BREAK 0x13b
+#define HCI_BSM 0x13c
+#define HCI_SUSPEND 0x13d
+#define HCI_HIBERNATE 0x13e
+#define HCI_VIDEOOUT 0x13f
+#define HCI_BRIGHTNESSDOWN 0x140
+#define HCI_BRIGHTNESSUP 0x141
+#define HCI_WLAN 0x142
+#define HCI_TOUCHPAD 0x143
+#define HCI_FN_PRESSED 0x17f
diff --git a/ubuntu/omnibook/hotkeys.c b/ubuntu/omnibook/hotkeys.c
new file mode 100644
index 00000000000..7d541e12adb
--- /dev/null
+++ b/ubuntu/omnibook/hotkeys.c
@@ -0,0 +1,193 @@
+/*
+ * hotkeys.c -- code to handling Hotkey/E-Key/EasyAccess 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+/* Predefined convinient on/off states */
+#define HKEY_ON HKEY_ONETOUCH|HKEY_MULTIMEDIA|HKEY_FN|HKEY_DOCK|HKEY_FNF5
+#define HKEY_OFF 0
+
+/*
+ * Set hotkeys status and update recorded saved state
+ */
+static int hotkeys_set_save(struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ retval = __backend_hotkeys_set(io_op, state);
+ if (retval < 0)
+ goto out;
+
+ /* Update saved state */
+ io_op->backend->hotkeys_state = state & io_op->backend->hotkeys_write_cap;
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Read hotkeys status, fallback to reading saved state if real probing is not
+ * supported.
+ */
+static int hotkeys_get_save(struct omnibook_operation *io_op, unsigned int *state)
+{
+ unsigned int read_state = 0;
+ int retval = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if (io_op->backend->hotkeys_get)
+ retval = __backend_hotkeys_get(io_op, &read_state);
+ if (retval < 0)
+ goto out;
+
+ /* Return previously set state for the fields that are write only */
+ *state = (read_state & io_op->backend->hotkeys_read_cap) +
+ (io_op->backend->hotkeys_state & ~io_op->backend->hotkeys_read_cap);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return 0;
+}
+
+/*
+ * Power management handlers
+ */
+
+/*
+ * Restore previously saved state
+ */
+static int omnibook_hotkeys_resume(struct omnibook_operation *io_op)
+{
+ int retval;
+ mutex_lock(&io_op->backend->mutex);
+ retval = __backend_hotkeys_set(io_op, io_op->backend->hotkeys_state);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Disable hotkeys upon suspend (FIXME is the disabling required ?)
+ */
+static int omnibook_hotkeys_suspend(struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ retval = backend_hotkeys_set(io_op, HKEY_OFF);
+ return retval;
+}
+
+static const char pretty_name[][27] = {
+ "Onetouch buttons are",
+ "Multimedia hotkeys are",
+ "Fn hotkeys are",
+ "Stick key is",
+ "Press Fn twice to lock is",
+ "Dock events are",
+ "Fn + F5 hotkey is",
+};
+
+static int omnibook_hotkeys_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int retval;
+ unsigned int read_state = 0; /* buggy gcc 4.1 warning fix */
+ unsigned int shift, mask;
+
+ retval = hotkeys_get_save(io_op, &read_state);
+
+ if (retval < 0)
+ return retval;
+
+ for (shift = 0; shift <= HKEY_LAST_SHIFT ; shift++) {
+ mask = 1 << shift;
+ /* we assume write capability or read capability imply support */
+ if ((io_op->backend->hotkeys_read_cap | io_op->backend->hotkeys_write_cap) & mask)
+ len +=
+ sprintf(buffer + len, "%s %s.\n", pretty_name[shift],
+ (read_state & mask) ? "enabled" : "disabled");
+ }
+
+ return len;
+}
+
+static int omnibook_hotkeys_write(char *buffer, struct omnibook_operation *io_op)
+{
+ unsigned int state;
+ char *endp;
+
+ if (strncmp(buffer, "off", 3) == 0)
+ hotkeys_set_save(io_op, HKEY_OFF);
+ else if (strncmp(buffer, "on", 2) == 0)
+ hotkeys_set_save(io_op, HKEY_ON);
+ else {
+ state = simple_strtoul(buffer, &endp, 16);
+ if (endp == buffer)
+ return -EINVAL;
+ else
+ hotkeys_set_save(io_op, state);
+ }
+ return 0;
+}
+
+static int __init omnibook_hotkeys_init(struct omnibook_operation *io_op)
+{
+ int retval;
+
+ printk(O_INFO "Enabling all hotkeys.\n");
+ retval = hotkeys_set_save(io_op, HKEY_ON);
+ return retval < 0 ? retval : 0;
+}
+
+static void __exit omnibook_hotkeys_cleanup(struct omnibook_operation *io_op)
+{
+ printk(O_INFO "Disabling all hotkeys.\n");
+ hotkeys_set_save(io_op, HKEY_OFF);
+}
+
+static struct omnibook_tbl hotkeys_table[] __initdata = {
+ {XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM30X,
+ COMMAND(KBC,OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE,OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)},
+ {TSM70, {CDI,}},
+ {TSM40, {SMI,}},
+ {TSX205, {ACPI,}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature hotkeys_driver = {
+ .name = "hotkeys",
+ .enabled = 1,
+ .read = omnibook_hotkeys_read,
+ .write = omnibook_hotkeys_write,
+ .init = omnibook_hotkeys_init,
+ .exit = omnibook_hotkeys_cleanup,
+ .suspend = omnibook_hotkeys_suspend,
+ .resume = omnibook_hotkeys_resume,
+ .ectypes =
+ XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | AMILOD | TSP10 | TSM70 | TSM30X |
+ TSM40 | TSX205,
+ .tbl = hotkeys_table,
+};
+
+module_param_named(hotkeys, hotkeys_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(hotkeys, "Use 0 to disable, 1 to enable hotkeys handling");
+/* End of file */
diff --git a/ubuntu/omnibook/info.c b/ubuntu/omnibook/info.c
new file mode 100644
index 00000000000..8e25e7a1a9d
--- /dev/null
+++ b/ubuntu/omnibook/info.c
@@ -0,0 +1,68 @@
+/*
+ * info.c -- trivial informational features
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/dmi.h>
+#include <linux/version.h>
+
+static int omnibook_version_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ len += sprintf(buffer + len, "%s\n", OMNIBOOK_MODULE_VERSION);
+
+ return len;
+}
+
+static int omnibook_dmi_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ len += sprintf(buffer + len, "BIOS Vendor: %s\n", dmi_get_system_info(DMI_BIOS_VENDOR));
+ len += sprintf(buffer + len, "BIOS Version: %s\n", dmi_get_system_info(DMI_BIOS_VERSION));
+ len += sprintf(buffer + len, "BIOS Release: %s\n", dmi_get_system_info(DMI_BIOS_DATE));
+ len += sprintf(buffer + len, "System Vendor: %s\n", dmi_get_system_info(DMI_SYS_VENDOR));
+ len += sprintf(buffer + len, "Product Name: %s\n", dmi_get_system_info(DMI_PRODUCT_NAME));
+ len +=
+ sprintf(buffer + len, "Version: %s\n", dmi_get_system_info(DMI_PRODUCT_VERSION));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+ len +=
+ sprintf(buffer + len, "Serial Number: %s\n", dmi_get_system_info(DMI_PRODUCT_SERIAL));
+#endif
+ len += sprintf(buffer + len, "Board Vendor: %s\n", dmi_get_system_info(DMI_BOARD_VENDOR));
+ len += sprintf(buffer + len, "Board Name: %s\n", dmi_get_system_info(DMI_BOARD_VERSION));
+
+ return len;
+}
+
+static struct omnibook_feature __declared_feature version_driver = {
+ .name = "version",
+ .enabled = 1,
+ .read = omnibook_version_read,
+};
+
+static struct omnibook_feature __declared_feature dmi_driver = {
+ .name = "dmi",
+ .enabled = 1,
+ .read = omnibook_dmi_read,
+};
+
+module_param_named(dmi, dmi_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(dmi, "Use 0 to disable, 1 to enable DMI informations display support");
+
+/* End of file */
diff --git a/ubuntu/omnibook/init.c b/ubuntu/omnibook/init.c
new file mode 100644
index 00000000000..c5278fea963
--- /dev/null
+++ b/ubuntu/omnibook/init.c
@@ -0,0 +1,535 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/proc_fs.h>
+#include <linux/dmi.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include "hardware.h"
+#include "laptop.h"
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+#include <linux/platform_device.h>
+#else
+#include <linux/device.h>
+#endif
+
+/*
+ * For compatibility with kernel older than 2.6.11
+ */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
+typedef u32 pm_message_t;
+#endif
+
+static int __init omnibook_probe(struct platform_device *dev);
+static int __exit omnibook_remove(struct platform_device *dev);
+static int omnibook_suspend(struct platform_device *dev, pm_message_t state);
+static int omnibook_resume(struct platform_device *dev);
+
+/*
+ * For compatibility with kernel older than 2.6.15
+ */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))
+
+#define to_platform_device(x) container_of((x), struct platform_device, dev)
+
+static int __init compat_omnibook_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ return omnibook_probe(pdev);
+}
+
+static int __exit compat_omnibook_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ return omnibook_remove(pdev);
+}
+
+static int compat_omnibook_suspend(struct device *dev, pm_message_t state, u32 level)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ return omnibook_suspend(pdev, state);
+}
+
+static int compat_omnibook_resume(struct device *dev, u32 level)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ return omnibook_resume(pdev);
+}
+
+#endif
+
+static struct proc_dir_entry *omnibook_proc_root = NULL;
+
+enum omnibook_ectype_t omnibook_ectype = NONE;
+
+static const char *laptop_model __initdata;
+
+static int omnibook_userset = 0;
+
+/*
+ * The platform_driver interface was added in linux 2.6.15
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+
+static struct platform_device *omnibook_device;
+
+static struct platform_driver omnibook_driver = {
+ .probe = omnibook_probe,
+ .remove = omnibook_remove,
+#ifdef CONFIG_PM
+ .suspend = omnibook_suspend,
+ .resume = omnibook_resume,
+#endif
+ .driver = {
+ .name = OMNIBOOK_MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+#else /* 2.6.15 */
+
+static struct device_driver omnibook_driver = {
+ .name = OMNIBOOK_MODULE_NAME,
+ .bus = &platform_bus_type,
+ .probe = compat_omnibook_probe,
+ .remove = compat_omnibook_remove,
+#ifdef CONFIG_PM
+ .suspend = compat_omnibook_suspend,
+ .resume = compat_omnibook_resume,
+#endif
+};
+
+static struct platform_device omnibook_device = {
+ .name = OMNIBOOK_MODULE_NAME,
+};
+
+#endif /* 2.6.15 */
+
+/* Linked list of all enabled features */
+static struct omnibook_feature *omnibook_available_feature;
+
+/* Delimiters of the .features section wich holds all the omnibook_feature structs */
+extern struct omnibook_feature _start_features_driver[];
+extern struct omnibook_feature _end_features_driver[];
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+static int __init dmi_matched(struct dmi_system_id *dmi)
+#else
+static int __init dmi_matched(const struct dmi_system_id *dmi)
+#endif
+{
+ omnibook_ectype = (enum omnibook_ectype_t)dmi->driver_data;
+ if (dmi->ident)
+ laptop_model = (char *)dmi->ident;
+ else
+ laptop_model = dmi_get_system_info(DMI_PRODUCT_VERSION);
+ return 1; /* return non zero means we stop the parsing selecting this entry */
+}
+
+/*
+ * Callback function for procfs file reading: the name of the file read was stored in *data
+ */
+static int procfile_read_dispatch(char *page, char **start, off_t off, int count, int *eof,
+ void *data)
+{
+ struct omnibook_feature *feature = (struct omnibook_feature *)data;
+ int len = 0;
+
+ if (!feature || !feature->read)
+ return -EINVAL;
+
+ if(off)
+ goto out;
+
+ len = feature->read(page, feature->io_op);
+ if (len < 0)
+ return len;
+
+ out:
+ *eof = 1;
+ return len;
+}
+
+/*
+ * Callback function for procfs file writing: the name of the file written was stored in *data
+ */
+static int procfile_write_dispatch(struct file *file, const char __user * userbuf,
+ unsigned long count, void *data)
+{
+ struct omnibook_feature *feature = (struct omnibook_feature *)data;
+ char *kernbuf;
+ int retval;
+
+ if (!feature || !feature->write)
+ return -EINVAL;
+
+ kernbuf = kmalloc(count + 1, GFP_KERNEL);
+ if (!kernbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(kernbuf, userbuf, count)) {
+ kfree(kernbuf);
+ return -EFAULT;
+ }
+
+ /* Make sure the string is \0 terminated */
+ kernbuf[count] = '\0';
+
+ retval = feature->write(kernbuf, feature->io_op);
+ if (retval == 0)
+ retval = count;
+
+ kfree(kernbuf);
+
+ return retval;
+}
+
+/*
+ * Match an ectype and return pointer to corresponding omnibook_operation.
+ * Also make corresponding backend initialisation if necessary, and skip
+ * to the next entry if it fails.
+ */
+static struct omnibook_operation *omnibook_backend_match(struct omnibook_tbl *tbl)
+{
+ int i;
+ struct omnibook_operation *matched = NULL;
+
+ for (i = 0; tbl[i].ectypes; i++) {
+ if (omnibook_ectype & tbl[i].ectypes) {
+ if (tbl[i].io_op.backend->init && tbl[i].io_op.backend->init(&tbl[i].io_op)) {
+ dprintk("Backend %s init failed, skipping entry.\n",
+ tbl[i].io_op.backend->name);
+ continue;
+ }
+ matched = &tbl[i].io_op;
+ dprintk("Returning table entry nr %i.\n", i);
+ break;
+ }
+ }
+ return matched;
+}
+
+/*
+ * Initialise a feature and add it to the linked list of active features
+ */
+static int __init omnibook_init(struct omnibook_feature *feature)
+{
+ int retval = 0;
+ mode_t pmode;
+ struct proc_dir_entry *proc_entry;
+ struct omnibook_operation *op;
+
+ if (!feature)
+ return -EINVAL;
+
+/*
+ * Select appropriate backend for feature operations
+ * We copy the io_op field so the tbl can be initdata
+ */
+ if (feature->tbl) {
+ dprintk("Begin table match of %s feature.\n", feature->name);
+ op = omnibook_backend_match(feature->tbl);
+ if (!op) {
+ dprintk("Match failed: disabling %s.\n", feature->name);
+ return -ENODEV;
+ }
+ feature->io_op = kmalloc(sizeof(struct omnibook_operation), GFP_KERNEL);
+ if (!feature->io_op)
+ return -ENOMEM;
+ memcpy(feature->io_op, op, sizeof(struct omnibook_operation));
+ } else
+ dprintk("%s feature has no backend table, io_op not initialized.\n", feature->name);
+
+/*
+ * Specific feature init code
+ */
+ if (feature->init && (retval = feature->init(feature->io_op))) {
+ printk(O_ERR "Init function of %s failed with error %i.\n", feature->name, retval);
+ goto err;
+ }
+/*
+ * procfs file setup
+ */
+ if (feature->name && feature->read) {
+ pmode = S_IFREG | S_IRUGO;
+ if (feature->write) {
+ pmode |= S_IWUSR;
+ if (omnibook_userset)
+ pmode |= S_IWUGO;
+ }
+
+ proc_entry = create_proc_entry(feature->name, pmode, omnibook_proc_root);
+
+ if (!proc_entry) {
+ printk(O_ERR "Unable to create proc entry %s\n", feature->name);
+ if (feature->exit)
+ feature->exit(feature->io_op);
+ retval = -ENOENT;
+ goto err;
+ }
+ proc_entry->data = feature;
+ proc_entry->read_proc = &procfile_read_dispatch;
+ if (feature->write)
+ proc_entry->write_proc = &procfile_write_dispatch;
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
+ proc_entry->owner = THIS_MODULE;
+ #endif
+ }
+ list_add_tail(&feature->list, &omnibook_available_feature->list);
+ return 0;
+ err:
+ if (feature->io_op && feature->io_op->backend->exit)
+ feature->io_op->backend->exit(feature->io_op);
+ kfree(feature->io_op);
+ return retval;
+}
+
+/*
+ * Callback function for driver registering :
+ * Initialize the linked list of enabled features and call omnibook_init to populate it
+ */
+static int __init omnibook_probe(struct platform_device *dev)
+{
+ int i;
+ struct omnibook_feature *feature;
+
+ /* temporary hack */
+ mutex_init(&kbc_backend.mutex);
+ mutex_init(&pio_backend.mutex);
+ mutex_init(&ec_backend.mutex);
+
+ omnibook_available_feature = kzalloc(sizeof(struct omnibook_feature), GFP_KERNEL);
+ if (!omnibook_available_feature)
+ return -ENOMEM;
+ INIT_LIST_HEAD(&omnibook_available_feature->list);
+
+ for (i = 0; i < _end_features_driver - _start_features_driver; i++) {
+
+ feature = &_start_features_driver[i];
+
+ if (!feature->enabled)
+ continue;
+
+ if ((omnibook_ectype & feature->ectypes) || (!feature->ectypes))
+ omnibook_init(feature);
+ }
+
+ printk(O_INFO "Enabled features:");
+ list_for_each_entry(feature, &omnibook_available_feature->list, list) {
+ if (feature->name)
+ printk(" %s", feature->name);
+ }
+ printk(".\n");
+
+ return 0;
+}
+
+/*
+ * Callback function for driver removal
+ */
+static int __exit omnibook_remove(struct platform_device *dev)
+{
+ struct omnibook_feature *feature, *temp;
+
+ list_for_each_entry_safe(feature, temp, &omnibook_available_feature->list, list) {
+ list_del(&feature->list);
+ /* Feature specific cleanup */
+ if (feature->exit)
+ feature->exit(feature->io_op);
+ /* Generic backend cleanup */
+ if (feature->io_op && feature->io_op->backend->exit)
+ feature->io_op->backend->exit(feature->io_op);
+ if (feature->name)
+ remove_proc_entry(feature->name, omnibook_proc_root);
+ kfree(feature->io_op);
+ }
+ kfree(omnibook_available_feature);
+
+ return 0;
+}
+
+/*
+ * Callback function for system suspend
+ */
+static int omnibook_suspend(struct platform_device *dev, pm_message_t state)
+{
+ int retval;
+ struct omnibook_feature *feature;
+
+ list_for_each_entry(feature, &omnibook_available_feature->list, list) {
+ if (feature->suspend) {
+ retval = feature->suspend(feature->io_op);
+ if (retval)
+ printk(O_ERR "Unable to suspend the %s feature (error %i).\n", feature->name, retval);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Callback function for system resume
+ */
+static int omnibook_resume(struct platform_device *dev)
+{
+ int retval;
+ struct omnibook_feature *feature;
+
+ list_for_each_entry(feature, &omnibook_available_feature->list, list) {
+ if (feature->resume) {
+ retval = feature->resume(feature->io_op);
+ if (retval)
+ printk(O_ERR "Unable to resume the %s feature (error %i).\n", feature->name, retval);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Find a given available feature by its name
+ */
+struct omnibook_feature *omnibook_find_feature(char *name)
+{
+ struct omnibook_feature *feature;
+
+ list_for_each_entry(feature, &omnibook_available_feature->list, list) {
+ if (!strcmp(feature->name, name))
+ return feature;
+ }
+ return NULL;
+}
+
+/*
+ * Maintain compatibility with the old ectype numbers:
+ * ex: The user set/get ectype=12 for TSM70=2^(12-1)
+ */
+static int __init set_ectype_param(const char *val, struct kernel_param *kp)
+{
+ char *endp;
+ int value;
+
+ if (!val)
+ return -EINVAL;
+
+ value = simple_strtol(val, &endp, 10);
+ if (endp == val) /* No match */
+ return -EINVAL;
+ omnibook_ectype = 1 << (value - 1);
+ return 0;
+}
+
+static int get_ectype_param(char *buffer, struct kernel_param *kp)
+{
+ return sprintf(buffer, "%i", ffs(omnibook_ectype));
+}
+
+static int __init omnibook_module_init(void)
+{
+ int retval;
+
+ printk(O_INFO "Driver version %s.\n", OMNIBOOK_MODULE_VERSION);
+
+ if (omnibook_ectype != NONE)
+ printk(O_WARN "Forced load with EC type %i.\n", ffs(omnibook_ectype));
+ else if (dmi_check_system(omnibook_ids))
+ printk(O_INFO "%s detected.\n", laptop_model);
+ else
+ printk(O_INFO "Unknown model.\n");
+
+ omnibook_proc_root = proc_mkdir(OMNIBOOK_MODULE_NAME, NULL);
+ if (!omnibook_proc_root) {
+ printk(O_ERR "Unable to create /proc/%s.\n", OMNIBOOK_MODULE_NAME);
+ return -ENOENT;
+ }
+
+/*
+ * The platform_driver interface was added in linux 2.6.15
+ */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+
+ retval = platform_driver_register(&omnibook_driver);
+ if (retval < 0)
+ return retval;
+
+ omnibook_device = platform_device_alloc(OMNIBOOK_MODULE_NAME, -1);
+ if (!omnibook_device) {
+ platform_driver_unregister(&omnibook_driver);
+ return -ENOMEM;
+ }
+
+ retval = platform_device_add(omnibook_device);
+ if (retval) {
+ platform_device_put(omnibook_device);
+ platform_driver_unregister(&omnibook_driver);
+ return retval;
+ }
+#else /* 2.6.15 */
+
+ retval = driver_register(&omnibook_driver);
+ if (retval < 0)
+ return retval;
+
+ retval = platform_device_register(&omnibook_device);
+
+ if (retval) {
+ driver_unregister(&omnibook_driver);
+ return retval;
+ }
+#endif
+ return 0;
+}
+
+static void __exit omnibook_module_cleanup(void)
+{
+
+/*
+ * The platform_driver interface was added in linux 2.6.15
+ */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+ platform_device_unregister(omnibook_device);
+ platform_driver_unregister(&omnibook_driver);
+#else
+ platform_device_unregister(&omnibook_device);
+ driver_unregister(&omnibook_driver);
+#endif
+
+ if (omnibook_proc_root)
+ remove_proc_entry("omnibook", NULL);
+ printk(O_INFO "Module is unloaded.\n");
+}
+
+module_init(omnibook_module_init);
+module_exit(omnibook_module_cleanup);
+
+MODULE_AUTHOR("Soós Péter, Mathieu Bérard");
+MODULE_VERSION(OMNIBOOK_MODULE_VERSION);
+MODULE_DESCRIPTION
+ ("Kernel interface for HP OmniBook, HP Pavilion, Toshiba Satellite and Compal ACL00 laptops");
+MODULE_LICENSE("GPL");
+module_param_call(ectype, set_ectype_param, get_ectype_param, NULL, S_IRUGO);
+module_param_named(userset, omnibook_userset, int, S_IRUGO);
+MODULE_PARM_DESC(ectype, "Type of embedded controller firmware");
+MODULE_PARM_DESC(userset, "Use 0 to disable, 1 to enable users to set parameters");
+
+/* End of file */
diff --git a/ubuntu/omnibook/kbc.c b/ubuntu/omnibook/kbc.c
new file mode 100644
index 00000000000..5634b40565c
--- /dev/null
+++ b/ubuntu/omnibook/kbc.c
@@ -0,0 +1,152 @@
+/*
+ * kbc.c -- low level functions to access Keyboard Controller
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include "hardware.h"
+
+extern int omnibook_key_polling_enable(void);
+extern int omnibook_key_polling_disable(void);
+
+/*
+ * 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 */
+
+
+/*
+ * Interrupt control
+ */
+
+static DEFINE_SPINLOCK(omnibook_kbc_lock);
+
+/*
+ * 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)
+{
+ int retval;
+
+ spin_lock_irq(&omnibook_kbc_lock);
+ 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:
+ spin_unlock_irq(&omnibook_kbc_lock);
+ return retval;
+}
+
+/*
+ * Write to the keyboard data register
+ */
+
+static int omnibook_kbc_write_data(u8 data)
+{
+ int retval;
+
+ spin_lock_irq(&omnibook_kbc_lock);
+ 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:
+ spin_unlock_irq(&omnibook_kbc_lock);
+ return retval;
+}
+
+/*
+ * Send a command to keyboard controller
+ */
+
+static int omnibook_kbc_command(const struct omnibook_operation *io_op, u8 data)
+{
+ int retval;
+
+ if ((retval = omnibook_kbc_write_command(OMNIBOOK_KBC_CONTROL_CMD)))
+ return retval;
+
+ retval = omnibook_kbc_write_data(data);
+ return retval;
+}
+
+/*
+ * Onetouch button hotkey handler
+ */
+static int omnibook_kbc_hotkeys(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval;
+
+ retval = __omnibook_toggle(io_op, !!(state & HKEY_ONETOUCH));
+ return retval;
+}
+
+/*
+ * Backend interface declarations
+ */
+struct omnibook_backend kbc_backend = {
+ .name = "i8042",
+ .hotkeys_write_cap = HKEY_ONETOUCH,
+ .byte_write = omnibook_kbc_command,
+ .hotkeys_set = omnibook_kbc_hotkeys,
+};
+
+/* End of file */
diff --git a/ubuntu/omnibook/laptop.h b/ubuntu/omnibook/laptop.h
new file mode 100644
index 00000000000..dd0a198039a
--- /dev/null
+++ b/ubuntu/omnibook/laptop.h
@@ -0,0 +1,1077 @@
+/*
+ * laptop.h -- Various structures about supported hardware
+ *
+ * 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-2004
+ * Written by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+
+#define HP_SIGNATURE "Hewlett-Packard"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+static int __init dmi_matched(struct dmi_system_id *dmi);
+#else
+static int __init dmi_matched(const struct dmi_system_id *dmi);
+#endif
+
+static struct dmi_system_id omnibook_ids[] __initdata = {
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XE3 GF",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XE3 GF"),
+ },
+ .driver_data = (void *) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XT1000",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XT1000"),
+ },
+ .driver_data = (void *) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XE2 DC",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XE2 DC"),
+ },
+ .driver_data = (void *) XE2
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XE3 GC",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XE3 GC"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XE3 GD / Pavilion N5430",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XE3 GD"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XE3 GE / Pavilion N5415",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook XE3 GE"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 500 FA",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 500 FA"),
+ },
+ .driver_data = (void*) OB500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 510 FB",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 510 FB"),
+ },
+ .driver_data = (void*) OB510
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 4150",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 4150"),
+ },
+ .driver_data = (void*) OB4150
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 900 B",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 900 B"),
+ },
+ .driver_data = (void*) OB4150
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 6000 EA",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 6000 EA"),
+ },
+ .driver_data = (void*) OB6000
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 6100 EB",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 6100 EB"),
+ },
+ .driver_data = (void*) OB6100
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook xe4000/xe4100",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook xe4000"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook xe4400",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook xe4400"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook xe4500",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook xe4500"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook 6200 EG / vt6200 / xt 6200",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook 6200 EG"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ /* There are no model specific strings of some HP OmniBook XT1500 */
+ {
+ .callback = dmi_matched,
+ .ident = "HP OmniBook XT1500",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP OmniBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP OmniBook"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ze4000 / ze4125",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP NoteBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP NoteBook ze4000"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ /* There are no model specific strings of some HP Pavilion xt155 and some HP Pavilion ze4100
+ * There are no model specific strings of some HP nx9000 */
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion xt155 / ze4100 / nx9000",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP NoteBook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP NoteBook PC"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ZU1000 FA / ZU1000 FA / ZU1175",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion ZU1000 FA"),
+ },
+ .driver_data = (void*) OB500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion Notebook XE3 GC / N5290",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook XE3 GC"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion Notebook GD / N5441",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GD"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion Notebook GE / XH545",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion Notebook ZT1000 / ZT1141",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ /* There are no model specific strings of some HP Pavilion ZT1175 and ZT1195 notebooks */
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ZT1175 / ZT1195",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ze4200 series",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ze4200"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ze4300 series",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ze4300"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ze4500 series",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ze4500"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Pavilion ze8500 series",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ze8500"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ /* Compaq nx9000 */
+ {
+ .callback = dmi_matched,
+ .ident = "HP Compaq nx9000",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP nx9000"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Compaq nx9005",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP nx9005"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP Compaq nx9010",
+ .matches = {
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP nx9010"),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1000"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1005",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1005"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1110"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1115",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1115"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1130",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1130"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1700-100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1700-100"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1700-200",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1700-200"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1700-300",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1700-300"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1700-400",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1700-400"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1700-500",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1700-500"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1900",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1900"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1905",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1905"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1950",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1950"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1955",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1955"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 2430",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S2430"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 2435",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S2435"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 3000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S3000"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 3005",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S3005"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1000"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1005",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1005"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1110"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1115",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1115"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1115",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Toshiba 1115"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1900",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1900"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1905",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1905"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1950",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1950"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 1955",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 1955"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 2430",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 2430"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 2435",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 2435"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 3000",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 3000"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite 3005",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite 3005"),
+ },
+ .driver_data = (void*) XE3GF,
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite A70",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A70"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite A75",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A75"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite A80",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A80"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite A105",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A105"),
+ },
+ .driver_data = (void*) TSA105
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite A100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"),
+ },
+ .driver_data = (void*) TSA105
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite P100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"),
+ },
+ .driver_data = (void*) TSA105
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite P10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"),
+ },
+ .driver_data = (void*) TSP10
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite P15",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P15"),
+ },
+ .driver_data = (void*) TSP10
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite P20",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P20"),
+ },
+ .driver_data = (void*) TSP10
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite P25",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P25"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M30X",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M30X"),
+ },
+ .driver_data = (void*) TSM30X
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M35X",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M35X"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M50",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M50"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M60",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M60"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M70",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M70"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE M100"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M100",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M100"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M115",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M115"),
+ },
+ .driver_data = (void*) TSA105
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M40X",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M40X"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M40",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M40"),
+ },
+ .driver_data = (void*) TSM40
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite M45",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite M45"),
+ },
+ .driver_data = (void*) TSM40
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Satellite X205-S9800",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Satellite X205"),
+ },
+ .driver_data = (void*) TSX205
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Tecra S1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TECRA S1"),
+ },
+ .driver_data = (void*) TSM40
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Tecra S1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Tecra S1"),
+ },
+ .driver_data = (void*) TSM40
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Tecra S2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Tecra S2"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Tecra A4",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Tecra A4"),
+ },
+ .driver_data = (void*) TSM40
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Tecra A6",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A6"),
+ },
+ .driver_data = (void*) TSM70
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Toshiba Equium A110",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"),
+ },
+ .driver_data = (void*) TSM30X /* FIXME: provisional */
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Compal ACL00",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_BOARD_NAME, "ACL00"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Compal ACL10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+ DMI_MATCH(DMI_BOARD_NAME, "ACL10"),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "Fujitsu-Siemens Amilo D series",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D-Series"),
+ },
+ .driver_data = (void*) AMILOD
+ },
+/* HP Technology code Matching:
+ * 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.
+ * New HP/Compaq models use more characters (eg. KF_KH.).
+ */
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code CI",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "CI."),
+ },
+ .driver_data = (void*) OB4150
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code CL",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "CL."),
+ },
+ .driver_data = (void*) OB4150
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code DC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "DC."),
+ },
+ .driver_data = (void*) XE2
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code EA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "EA."),
+ },
+ .driver_data = (void*) OB6000
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code EB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "EB."),
+ },
+ .driver_data = (void*) OB6100
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code EG",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "EG."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code FA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "FA."),
+ },
+ .driver_data = (void*) OB500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code FB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "FB."),
+ },
+ .driver_data = (void*) OB510
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code GC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "GC."),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code GD",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "GD."),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code GE",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "GE."),
+ },
+ .driver_data = (void*) XE3GC
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code GF",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "GF."),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code IB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "IB."),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code IC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "IC."),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code ID",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "ID."),
+ },
+ .driver_data = (void*) XE3GF
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KA",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KA."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KB."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KC",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KC."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KD",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KD."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KE",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KE."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KE_KG",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KE_KG."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ {
+ .callback = dmi_matched,
+ .ident = "HP model with technology code KF_KH",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, HP_SIGNATURE),
+ DMI_MATCH(DMI_BIOS_VERSION, "KF_KH."),
+ },
+ .driver_data = (void*) XE4500
+ },
+ { NULL, }
+};
diff --git a/ubuntu/omnibook/lcd.c b/ubuntu/omnibook/lcd.c
new file mode 100644
index 00000000000..7702ea67c0b
--- /dev/null
+++ b/ubuntu/omnibook/lcd.c
@@ -0,0 +1,207 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include <linux/err.h>
+
+#ifdef CONFIG_OMNIBOOK_BACKLIGHT
+#include <linux/backlight.h>
+#endif
+
+#include "hardware.h"
+
+unsigned int omnibook_max_brightness;
+
+#ifdef CONFIG_OMNIBOOK_BACKLIGHT
+static struct backlight_device *omnibook_backlight_device;
+
+static int omnibook_get_backlight(struct backlight_device *bd);
+static int omnibook_set_backlight(struct backlight_device *bd);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+static struct backlight_ops omnibookbl_ops = {
+#else /* 2.6.21 */
+static struct backlight_properties omnibookbl_data = {
+ .owner = THIS_MODULE,
+#endif /* 2.6.21 */
+ .get_brightness = omnibook_get_backlight,
+ .update_status = omnibook_set_backlight,
+};
+
+static int omnibook_get_backlight(struct backlight_device *bd)
+{
+ int retval = 0;
+ struct omnibook_operation *io_op;
+ u8 brgt;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ io_op = bl_get_data(bd);
+#else /* 2.6.23 */
+ io_op = class_get_devdata(&bd->class_dev);
+#endif /* 2.6.23 */
+ retval = backend_byte_read(io_op, &brgt);
+ if (!retval)
+ retval = brgt;
+
+ return retval;
+}
+
+static int omnibook_set_backlight(struct backlight_device *bd)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ u8 intensity = bd->props.brightness;
+#else /* 2.6.21 */
+ u8 intensity = bd->props->brightness;
+#endif /* 2.6.21 */
+ struct omnibook_operation *io_op;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
+ io_op = bl_get_data(bd);
+#else /* 2.6.23 */
+ io_op = class_get_devdata(&bd->class_dev);
+#endif /* 2.6.23 */
+ return backend_byte_write(io_op, intensity);
+}
+#endif /* CONFIG_OMNIBOOK_BACKLIGHT */
+
+static int omnibook_brightness_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ u8 brgt;
+
+ backend_byte_read(io_op, &brgt);
+
+ len +=
+ sprintf(buffer + len, "LCD brightness: %2d (max value: %d)\n", brgt,
+ omnibook_max_brightness);
+
+ return len;
+}
+
+static int omnibook_brightness_write(char *buffer, struct omnibook_operation *io_op)
+{
+ unsigned int brgt = 0;
+ char *endp;
+
+ if (strncmp(buffer, "off", 3) == 0)
+ omnibook_lcd_blank(1);
+ else if (strncmp(buffer, "on", 2) == 0)
+ omnibook_lcd_blank(0);
+ else {
+ brgt = simple_strtoul(buffer, &endp, 10);
+ if ((endp == buffer) || (brgt > omnibook_max_brightness))
+ return -EINVAL;
+ else {
+ backend_byte_write(io_op, brgt);
+#ifdef CONFIG_OMNIBOOK_BACKLIGHT
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ omnibook_backlight_device->props.brightness = brgt;
+#else /* 2.6.21 */
+ omnibookbl_data.brightness = brgt;
+#endif
+#endif
+ }
+ }
+ return 0;
+}
+
+static int __init omnibook_brightness_init(struct omnibook_operation *io_op)
+{
+ /*
+ * FIXME: What is exactly the max value for each model ?
+ * I know that it's 7 for the TSM30X, TSM70, TSM40 and TSA105
+ * and previous versions of this driver (wrongly) assumed it was 10 for
+ * all models.
+ *
+ * XE3GF
+ * TSM30X
+ * TSM70
+ * TSM40
+ * TSA105
+ * TSX205
+ */
+ if (omnibook_ectype & (XE3GF | TSM70 | TSM30X | TSM40 | TSA105 | TSX205))
+ omnibook_max_brightness = 7;
+ else {
+ omnibook_max_brightness = 10;
+ printk(O_WARN "Assuming that LCD brightness is between 0 and %i,\n",
+ omnibook_max_brightness);
+ printk(O_WARN
+ "please contact http://sourceforge.net/projects/omnibook to confirm.\n");
+ }
+
+#ifdef CONFIG_OMNIBOOK_BACKLIGHT
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ omnibook_backlight_device =
+ backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, (void *)io_op, &omnibookbl_ops);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+ omnibook_backlight_device =
+ backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, (void *)io_op, &omnibookbl_data);
+#else /* < 2.6.20 */
+ omnibook_backlight_device =
+ backlight_device_register(OMNIBOOK_MODULE_NAME, (void *)io_op, &omnibookbl_data);
+#endif
+ if (IS_ERR(omnibook_backlight_device)) {
+ printk(O_ERR "Unable to register as backlight device.\n");
+ return -ENODEV;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ omnibook_backlight_device->props.max_brightness = omnibook_max_brightness;
+ backend_byte_read(io_op, (u8*) &omnibook_backlight_device->props.brightness);
+#else /* < 2.6.21 */
+ omnibookbl_data.max_brightness = omnibook_max_brightness;
+ backend_byte_read(io_op, (u8*) &omnibookbl_data.brightness);
+#endif
+
+#endif /* CONFIG_OMNIBOOK_BACKLIGHT */
+ return 0;
+}
+static void __exit omnibook_brightness_cleanup(struct omnibook_operation *io_op)
+{
+#ifdef CONFIG_OMNIBOOK_BACKLIGHT
+ backlight_device_unregister(omnibook_backlight_device);
+#endif
+}
+
+static struct omnibook_tbl lcd_table[] __initdata = {
+ {TSM70 | TSX205, {CDI, TSM70_LCD_READ, TSM70_LCD_WRITE, 0, 0, 0}},
+ {TSM40, {SMI, SMI_GET_LCD_BRIGHTNESS, SMI_SET_LCD_BRIGHTNESS, 0, 0, 0}},
+ {XE3GF | TSP10 | TSM70 | TSM30X, SIMPLE_BYTE(EC, XE3GF_BRTS, XE3GF_BRTS_MASK)},
+ {XE3GC, SIMPLE_BYTE(EC, XE3GC_BTVL, XE3GC_BTVL_MASK)},
+ {AMILOD, SIMPLE_BYTE(EC, AMILOD_CBRG, XE3GC_BTVL_MASK)},
+ {TSA105, SIMPLE_BYTE(EC, A105_BNDT, A105_BNDT_MASK)},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature lcd_driver = {
+ .name = "lcd",
+ .enabled = 1,
+ .read = omnibook_brightness_read,
+ .write = omnibook_brightness_write,
+ .init = omnibook_brightness_init,
+ .exit = omnibook_brightness_cleanup,
+ .ectypes = XE3GF | XE3GC | AMILOD | TSP10 | TSM70 | TSM30X | TSM40 | TSA105 | TSX205,
+ .tbl = lcd_table,
+};
+
+module_param_named(lcd, lcd_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(lcd, "Use 0 to disable, 1 to enable to LCD brightness support");
+
+/* End of file */
diff --git a/ubuntu/omnibook/lib.c b/ubuntu/omnibook/lib.c
new file mode 100644
index 00000000000..728e70f3668
--- /dev/null
+++ b/ubuntu/omnibook/lib.c
@@ -0,0 +1,81 @@
+/*
+ * lib.c -- Generic helpers 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include "hardware.h"
+#include "compat.h"
+#include <linux/input.h>
+
+/*
+ * Generic funtion for applying a mask on a value
+ * Hack: degenerate to omnibook_toggle if there is no read method
+ * of if the read address is 0, this is used in blank.c
+ */
+int __omnibook_apply_write_mask(const struct omnibook_operation *io_op, int toggle)
+{
+ int retval = 0;
+ int mask;
+ u8 data;
+
+ if(!(io_op->backend->byte_read && io_op->read_addr))
+ return __omnibook_toggle(io_op,toggle);
+
+ if ((retval = __backend_byte_read(io_op, &data)))
+ return retval;
+
+ if (toggle == 1)
+ mask = io_op->on_mask;
+ else if (toggle == 0)
+ mask = io_op->off_mask;
+ else
+ return -EINVAL;
+
+ if (mask > 0)
+ data |= (u8) mask;
+ else if (mask < 0)
+ data &= ~((u8) (-mask));
+ else
+ return -EINVAL;
+
+ retval = __backend_byte_write(io_op, data);
+
+ return retval;
+}
+
+/*
+ * Helper for toggle like operations
+ */
+int __omnibook_toggle(const struct omnibook_operation *io_op, int toggle)
+{
+ int retval;
+ u8 data;
+
+ data = toggle ? io_op->on_mask : io_op->off_mask;
+ retval = __backend_byte_write(io_op, data);
+ return retval;
+}
+
+void omnibook_report_key( struct input_dev *dev, unsigned int keycode)
+{
+ input_report_key(dev, keycode, 1);
+ input_sync(dev);
+ input_report_key(dev, keycode, 0);
+ input_sync(dev);
+}
+
+/* End of file */
diff --git a/ubuntu/omnibook/misc/README.mmkeys b/ubuntu/omnibook/misc/README.mmkeys
new file mode 100644
index 00000000000..9a9fc04aa0a
--- /dev/null
+++ b/ubuntu/omnibook/misc/README.mmkeys
@@ -0,0 +1,9 @@
+This patch maps some extra Fn+key combinations to keycodes for multimedia
+keyboards and only works for the nbsmi-backend. It might be useful if you
+want to control some mediaplayer while working with other applications.
+
+Following combinations are mapped:
+Fn+Y => Previous song
+Fn+X => Play/pause
+Fn+V => Stop CD
+Fn+B => Next song \ No newline at end of file
diff --git a/ubuntu/omnibook/misc/dmi_strings.txt b/ubuntu/omnibook/misc/dmi_strings.txt
new file mode 100644
index 00000000000..4eef0c09ae7
--- /dev/null
+++ b/ubuntu/omnibook/misc/dmi_strings.txt
@@ -0,0 +1,857 @@
+HP OmniBook XT1000 -------------------------
+
+BIOS Vendor: Insyde Software
+BIOS Version: IB.M1.05
+BIOS Release: 02/28/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XT1000
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: HP OmniBook XT1000
+
+---------------------------------------------
+HP OmniBook XT1500 --------------------------
+
+BIOS Vendor: Insyde Software
+BIOS Version: IC.M1.05
+BIOS Release: 08/13/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: HP OmniBook
+
+---------------------------------------------
+HP OmniBook XT1500 -------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: ID.M1.04
+BIOS Release: 08/14/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XE3 GF
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook Zinfandel 4.5
+
+---------------------------------------------
+HP OmniBook XE3 GC --------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GC.M1.63
+BIOS Release: 01/01/1992
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XE3 GC
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-733
+
+---------------------------------------------
+HP OmniBook XE3 GF --------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GF.M1.07
+BIOS Release: 03/05/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XE3 GF
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-101
+
+---------------------------------------------
+HP OmniBook 500 FA --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd
+BIOS Version: FA.M2.62
+BIOS Release: 11/30/1999
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 500 FA
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 500 FA
+
+---------------------------------------------
+HP OmniBook 510 FB --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: FB.M1.20
+BIOS Release: 04/12/02
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 510 FB
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 510FB
+
+---------------------------------------------
+Toshiba Satellite 3000-100 ------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.20
+BIOS Release: 10/12/01
+System Vendor: TOSHIBA
+Product Name: S3000-100
+Version: PS300E-03EKL-FR
+Board Vendor: Null
+Board Name: 888M1
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite 1115-s103------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.20
+BIOS Release: 09/11/2002
+System Vendor: TOSHIBA
+Product Name: Satellite 1115
+Version: PS111U-001FUV
+Board Vendor: TOSHIBA
+Board Name: BTK20
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite 1110 ----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.20
+BIOS Release: 09/11/2002
+System Vendor: TOSHIBA
+Product Name: S1110
+Version: PS111E-003DN-GR
+Board Vendor: TOSHIBA
+Board Name: BTK20
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite 1130 ----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.70A
+BIOS Release: 09/02/2003
+System Vendor: TOSHIBA
+Product Name: Satellite 1130
+Version: PS113E-05ZYF-GR
+Board Vendor: TOSHIBA
+Board Name: BTW30
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite 1900-704 ------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.50
+BIOS Release: 11/25/2002
+System Vendor: TOSHIBA
+Product Name: Satellite 1950
+Version: PS195E-008QY-DU
+Board Vendor: TOSHIBA
+Board Name: ATR60
+
+---------------------------------------------
+Toshiba Satellite 1955-s805 -----------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.00
+BIOS Release: 01/17/2003
+System Vendor: TOSHIBA
+Product Name: Satellite 1955
+Version: PS197U-000LEV
+Board Vendor: TOSHIBA
+Board Name: BTR80
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite A70 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.50
+BIOS Release: 11/16/2004
+System Vendor: TOSHIBA
+Product Name: Satellite A70
+Version: PSA70C-KL100E
+Serial Number: X4451615K
+Board Vendor: TOSHIBA
+Board Name: EDW10
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite A80 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.50
+BIOS Release: 01/11/2006
+System Vendor: TOSHIBA
+Product Name: Satellite A80
+Version: PSA80E-03T00JSP
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Satellite A105 ----------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: 1.30
+BIOS Release: 02/09/2006
+System Vendor: TOSHIBA
+Product Name: Satellite A105
+Version: PSAA8U-02000U
+Board Vendor: Intel Corporation
+Board Name: Not Applicable
+
+---------------------------------------------
+Toshiba Satellite P10 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.20
+BIOS Release: 09/12/2003
+System Vendor: TOSHIBA
+Product Name: Satellite P10
+Version: PSP10E-34FJR
+Board Vendor: TOSHIBA
+Board Name: DAL00
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite P15 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.20
+BIOS Release: 09/12/2003
+System Vendor: TOSHIBA
+Product Name: Satellite P15
+Version: PSP10U-0DUJPV
+Board Vendor: TOSHIBA
+Board Name: DAL00
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite P25 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.10
+BIOS Release: 12/27/2004
+System Vendor: TOSHIBA
+Product Name: Satellite P25
+Version: PSP20U-19PS8R
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Satellite P100 ----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V3.30
+BIOS Release: 12/22/2006
+System Vendor: TOSHIBA
+Product Name: Satellite P100
+Version: PSPA3E-02E013G3
+Board Vendor: TOSHIBA
+Board Name: Not Applicable
+
+---------------------------------------------
+Toshiba Satellite M40 -----------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: 1.10
+BIOS Release: 08/24/05
+System Vendor: TOSHIBA
+Product Name: Satellite M40
+Version: PSM44E-00U00EFR
+Board Vendor: ATI
+Board Name: SB400
+Board Version: Rev0.4b
+
+---------------------------------------------
+Toshiba Satellite M45 (S355) ----------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: Version 2.00
+BIOS Release: 02/07/2006
+System Vendor: TOSHIBA
+Product Name: Satellite M45
+Version: PSM40U-073001
+Board Vendor: TOSHIBA
+Board Name: Version A0
+
+---------------------------------------------
+Toshiba Satellite M40X (-131)----------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.60
+BIOS Release: 06/09/2005
+System Vendor: TOSHIBA
+Product Name: Satellite M40X
+Version: PSM4XE-01400GFR
+Board Vendor: TOSHIBA
+Board Name: EAL30
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite M50------------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.10
+BIOS Release: 05/08/2006
+System Vendor: TOSHIBA
+Product Name: Satellite M50
+Version: PSM51E-01C011IT
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Satellite M60 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.60
+BIOS Release: 03/16/2006
+System Vendor: TOSHIBA
+Product Name: Satellite M60
+Version: PSM60E-0CD01FIT
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Satellite M70 -----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.10
+BIOS Release: 09/15/2005
+System Vendor: TOSHIBA
+Product Name: Satellite M70
+Version: PSM71E-01100KFR
+Board Vendor: TOSHIBA
+Board Name: HTW00
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite A75 -----------------------
+
+IOS Vendor: TOSHIBA
+BIOS Version: V1.50
+BIOS Release: 11/16/2004
+System Vendor: TOSHIBA
+Product Name: Satellite A75
+Version: PSA70U-004004B
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Satellite M100 ----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.90
+BIOS Release: 07/20/2006
+System Vendor: TOSHIBA
+Product Name: SATELLITE M100
+Version: PSMA0E-030019TE
+Board Vendor: TOSHIBA
+Board Name: HAQAA
+Board Version: Null
+
+---------------------------------------------
+Toshiba Satellite M100 ----------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.00
+BIOS Release: 03/30/2006
+System Vendor: TOSHIBA
+Product Name: Satellite M100
+Version: PSMA2U-00T00G
+Board Vendor: TOSHIBA
+Board Name: HAWAA
+Board Version: None
+
+---------------------------------------------
+Toshiba Satellite M115 ----------------------
+
+Bios vender: Phoenix Tech. LTD
+Bios version: 1.00
+Bios release: 08/31/2006
+System Vendor: Toshiba
+Product Name: Satellite M115
+Version: PSMBOU-015007
+Board vendor Intel
+Board name: N/a
+
+---------------------------------------------
+Toshiba Equium A110 -------------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.30
+BIOS Release: 07/20/2006
+System Vendor: TOSHIBA
+Product Name: EQUIUM A110
+Version: PSAB2E-002006AV
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Tecra A4 ----------------------------
+
+
+BIOS Vendor: TOSHIBA
+BIOS Version: Version 1.70
+BIOS Release: 10/14/2005
+System Vendor: TOSHIBA
+Product Name: Tecra A4
+Version: PTA40E-0UN00FSP
+Board Vendor: TOSHIBA
+Board Name: Version A0
+
+---------------------------------------------
+Toshiba Tecra A6 ----------------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.70
+BIOS Release: 04/26/2007
+System Vendor: TOSHIBA
+Product Name: TECRA A6
+Version: PTA60U-0FK00D
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Toshiba Tecra S2 ----------------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V2.50
+BIOS Release: 01/11/2006
+System Vendor: TOSHIBA
+Product Name: Tecra S2
+Version: PTS20E-1FE04Q8M
+Board Vendor: TOSHIBA
+Board Name: Null
+
+---------------------------------------------
+Compal ACL00 --------------------------------
+
+BIOS Vendor: COMPAL
+BIOS Version: V2.10C
+BIOS Release: 03/25/02
+System Vendor: COMPAL
+Product Name: *
+Version: *
+Board Vendor: Null
+Board Name: ACL00
+Board Version: Null
+
+---------------------------------------------
+Compal ACL10 --------------------------------
+
+BIOS Vendor: COMPAL
+BIOS Version: V1.10
+BIOS Release: 04/12/2001
+System Vendor: *
+Product Name: *
+Version: *
+Board Vendor: COMPAL
+Board Name: ACL10
+Board Version: Null
+
+---------------------------------------------
+HP Pavilion ZT1195 --------------------------
+
+BIOS Vendor: Insyde Software
+BIOS Version: IC.M1.00
+BIOS Release: 03/20/2002
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion Notebook
+Board Vendor: Hewlett-Packard
+Board Name: HP Pavilion Notebook PC
+Board Version: HP Pavilion Notebook
+
+---------------------------------------------
+HP Pavilion ZT1141 --------------------------
+
+BIOS Vendor: Insyde Software
+BIOS Version: IB.M1.05
+BIOS Release: 02/28/2002
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion Notebook ZT1000
+Board Vendor: Hewlett-Packard
+Board Name: HP Pavilion Notebook PC
+Board Version: HP Pavilion Notebook ZT1000
+
+---------------------------------------------
+HP OmniBook 6100 EB -------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: EB.M2.20
+BIOS Release: 02/27/02
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 6100 EB
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 6100EB
+
+---------------------------------------------
+HP OmniBook 6000 EA -------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: EA.M1.81
+BIOS Release: 02/22/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 6000 EA
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 6000EA
+
+---------------------------------------------
+HP OmniBook xe4500 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KB.M1.30
+BIOS Release: 08/05/20022
+System Vendor: Hewlett-Packard.
+Product Name: HP OmniBook PC
+Version: HP OmniBook xe4500
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: xe4500
+
+---------------------------------------------
+HP Pavilion N5441 ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GD.M1.08
+BIOS Release: 09/27/2001
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion Notebook Model GD
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-736
+
+---------------------------------------------
+HP Pavilion N5430 ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GD.M1.08
+BIOS Release: 09/27/2001
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XE3 GD
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-736
+
+---------------------------------------------
+HP Pavilion N5415 ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GE.M1.04
+BIOS Release: 07/30/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook XE3 GE
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-736
+
+---------------------------------------------
+HP Pavilion N5290 ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GC.M1.63
+BIOS Release: 01/01/1992
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion Notebook XE3 GC
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-733
+
+---------------------------------------------
+HP OmniBook vt6200 -------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: EG.M2.10
+BIOS Release: 09/19/02
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 6200 EG
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 6200EG
+
+---------------------------------------------
+HP OmniBook 4150 ----------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: CI.M2.250
+BIOS Release: 06/10/99
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 4150
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook TS32T2
+
+---------------------------------------------
+HP OmniBook xt6200 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd
+BIOS Version: EG.M2.10
+BIOS Release: 09/19/02
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 6200 EG
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 6200EG
+
+---------------------------------------------
+HP Pavilion ze4125 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd
+BIOS Version: KA.M1.20
+BIOS Release: 09/13/2002
+System Vendor: Hewlett-Packard
+Product Name: HP NoteBook PC
+Version: HP NoteBook ze4000
+Board Vendor: Hewlett-Packard
+Board Name: HP NoteBook PC
+Board Version: HP NoteBook ze4000
+
+---------------------------------------------
+HP OmniBook xt155 ---------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KE.M1.40
+BIOS Release: 10/11/20022
+System Vendor: Hewlett-Packard
+Product Name: HP NoteBook PC
+Version: HP Notebook PC
+Board Vendor: Hewlett-Packard
+Board Name: HP NoteBook PC
+Board Version: HP Notebook PC
+
+---------------------------------------------
+HP OmniBook xe4100 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KC.M1.10
+BIOS Release: 07/11/2002
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook xe4000
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: 4000KC
+
+---------------------------------------------
+HP Omnibook xe4400 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KD.M1.60
+BIOS Release: 09/19/20022
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP Omnibook xe4400
+Board Vendor: Hewlett-Packard
+Board Name: HP OmniBook PC
+Board Version: xe4400
+
+---------------------------------------------
+HP Pavilion ze4100 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KE.M1.40
+BIOS Release: 10/11/20022
+System Vendor: Hewlett-Packard
+Product Name: HP NoteBook PC
+Version: HP Notebook PC
+Board Vendor: Hewlett-Packard
+Board Name: HP NoteBook PC
+Board Version: HP Notebook PC
+
+---------------------------------------------
+Acer Aspire 1350 ----------------------------
+BIOS Vendor: Acer
+BIOS Version: 3A24
+BIOS Release: 12/01/2003
+System Vendor: Acer,Inc.
+Product Name: Aspire 1350
+Version: 3A24
+Board Vendor: Acer,Inc.
+Board Name: Aspire 1350
+Board Version: Rev.A
+
+---------------------------------------------
+Acer Aspire 1406 LC -------------------------
+
+BIOS Vendor: Acer
+BIOS Version: V2.30
+BIOS Release: 10/04/02
+System Vendor: Acer
+Product Name: Aspire 1400 series
+Version: *
+Board Vendor: Null
+Board Name: BR20
+Board Version: Null
+
+---------------------------------------------
+HP Pavilion ze4200 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KE.M1.53
+BIOS Release: 12/10/20022
+System Vendor: Hewlett-Packard
+Product Name: Pavilion ze4200
+Version: KE.M1.53
+Board Vendor: Hewlett-Packard
+Board Name: 002A
+Board Version: NS570 Version PQ1A74
+
+---------------------------------------------
+HP Pavilion ze4500 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KAM1.57
+BIOS Release: 02/19/2004
+System Vendor: Hewlett-Packard
+Product Name: Pavilion ze4500 (DP793E)
+Version: KAM1.57
+Board Vendor: Hewlett-Packard
+Board Name: PQ1A83
+
+---------------------------------------------
+HP Pavilion ZU1175 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: FA.M2.60
+BIOS Release: 11/30/1999
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion ZU1000 FA
+Board Vendor: Hewlett-Packard
+Board Name: HP Pavilion Notebook PC
+Board Version: 1000FA
+
+---------------------------------------------
+HP Pavilion XH545 ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: GE.M1.03
+BIOS Release: 11/08/2001
+System Vendor: Hewlett-Packard
+Product Name: HP Pavilion Notebook PC
+Version: HP Pavilion Notebook Model GE
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook N32N-736
+
+---------------------------------------------
+Toshiba Satellite 2430-402 ------------------
+
+BIOS Vendor: TOSHIBA
+BIOS Version: V1.30
+BIOS Release: 01/16/2003
+System Vendor: TOSHIBA
+Product Name: Satellite 2430
+Version: PS243E-06P4S-4V
+Board Vendor: TOSHIBA
+Board Name: BTS88
+Board Version: Null
+
+---------------------------------------------
+HP OmniBook 900 B ---------------------------
+
+BIOS Vendor: Phoenix Technologies LTD
+BIOS Version: CL.M3.13
+BIOS Release: 11/11/99
+System Vendor: Hewlett-Packard
+Product Name: HP OmniBook PC
+Version: HP OmniBook 900 B
+Board Vendor: Hewlett-Packard
+Board Name: N/A
+Board Version: OmniBook TS32U2
+
+---------------------------------------------
+HP Compaq nx9000 ----------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KE_KG.M1.06
+BIOS Release: 05/16/2003
+System Vendor: Hewlett-Packard
+Product Name: HP nx9000 (DG223T)
+Version: KG.M1.06
+Board Vendor: Hewlett-Packard
+Board Name: 002A
+Board Version: NS570 Version PQ1A78
+
+---------------------------------------------
+HP Compaq nx9000 ----------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KE_KG.M1.15
+BIOS Release: 12/19/2003
+System Vendor: Hewlett-Packard
+Product Name: HP Notebook PC
+Version: HP Notebook PC
+Board Vendor: <NULL>
+Board Name: <NULL>
+Board Version: <NULL>
+
+---------------------------------------------
+HP Compaq nx9005 ----------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KAM1.46
+BIOS Release: 07/21/200392
+System Vendor: Hewlett-Packard
+Product Name: HP nx9005 (DJ163A)
+Version: KAM1.46
+Board Vendor: Hewlett-Packard
+Board Name: 0024
+Board Version: PQ1A78
+
+----------------------------------------------
+HP Compaq nx9010 -----------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KF_KH.F.08
+BIOS Release: 06/06/2003
+System Vendor: Hewlett-Packard
+Product Name: HP nx9010 (DJ123A)
+Version: KH.F.08
+Board Vendor: Hewlett-Packard
+Board Name: 0850
+Board Version: NS570 Version PQ1B56
+
+----------------------------------------------
+HP Pavilion ze8500 --------------------------
+
+BIOS Vendor: Phoenix Technologies Ltd.
+BIOS Version: KF_KH.F.18
+BIOS Release: 11/13/2003
+System Vendor: Hewlett-Packard
+Product Name: Pavilion ze8500 (DJ317A)
+Version: KH.F.18
+Board Vendor: Hewlett-Packard
+Board Name: 0850
+Board Version: NS570 Version PQ1B60
+
+---------------------------------------------
+Fujitsu-Siemens Amilo D ---------------------
+
+BIOS Vendor: Phoenix
+BIOS Version: V1.20
+BIOS Release: 11/14/2001
+System Vendor: FUJITSU SIEMENS
+Product Name: Amilo D-Series
+Version: DESKTOP CPU ONLY
+Board Vendor: CY23
+Board Name: 8606-686B
+Board Version: None
+
+---------------------------------------------
diff --git a/ubuntu/omnibook/misc/hotkeys/README.hotkeys b/ubuntu/omnibook/misc/hotkeys/README.hotkeys
new file mode 100644
index 00000000000..3522bdfcc42
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/README.hotkeys
@@ -0,0 +1,22 @@
+HotKeys is a program to use the special keys on internet/multimedia
+keyboards.
+
+The HotKeys daemon listens for the "special" hotkeys that you won't
+normally use on your Internet/Multimedia keyboards. The buttons
+perform their intended behaviors, such as volume up and down, mute the
+speaker, or launch applications. It has On-screen display (OSD) to
+show the volume, program that's being started, etc. It features an
+XML-based keycode configuration file format, which makes it possible
+to define the hotkeys to launch any programs you want.
+
+You may reach it at http://ypwong.org/hotkeys/
+
+Files in this directory provide examles for hotkeys definition files
+for certain laptop models supported by omnibook module:
+
+ob5xx.def: HP OmniBook 5xx
+xe3gc.def: HP OmniBook XE3 GC, GD, GE and HP Pavilion N5xxx
+xe3gf.def: HP OmniBook XE3 GF
+xe4xxx.def: HP OmniBook xe4xxx and ze4xxx
+xt155.def: HP OmniBook xt155
+nx9xxx.def: HP/Compaq nx9xxx
diff --git a/ubuntu/omnibook/misc/hotkeys/nx9xxx.def b/ubuntu/omnibook/misc/hotkeys/nx9xxx.def
new file mode 100644
index 00000000000..9d3f531fe8d
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/nx9xxx.def
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP/Compaq nx9xxx laptops">
+
+ <!--
+ Multimedia keys are disabled by default on HP laptops.
+ For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <Email keycode="236"/>
+ <WebBrowser keycode="178"/>
+ <Shell keycode="243"/>
+ <ScreenSaver keycode="241"/>
+ <Help keycode="240"/>
+
+ <VolUp keycode="176" adj="1"/>
+ <VolDown keycode="174" adj="1"/>
+
+ <userdef keycode="160" command="aumix -vM">Sound muted</userdef>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/misc/hotkeys/ob5xx.def b/ubuntu/omnibook/misc/hotkeys/ob5xx.def
new file mode 100644
index 00000000000..807b8d1748f
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/ob5xx.def
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP OmniBook 5xx">
+
+ <!--
+ Multimedia keys are disabled by default on HP OmniBook
+ laptops. For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <Shell keycode="244"/>
+ <Help keycode="243"/>
+
+ <!-- Keys below available on the docking station only -->
+
+ <PrevTrack keycode="144"/>
+ <Play keycode="162"/>
+ <Stop keycode="164"/>
+ <NextTrack keycode="153"/>
+
+ <VolUp keycode="176" adj="1"/>
+ <VolDown keycode="174" adj="1"/>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/misc/hotkeys/xe3gc.def b/ubuntu/omnibook/misc/hotkeys/xe3gc.def
new file mode 100644
index 00000000000..5e418f21ffa
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/xe3gc.def
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP OmniBook XE3 GC, GD, GE and HP Pavilion N5xxx">
+
+ <!--
+ Multimedia keys are disabled by default on HP OmniBook
+ laptops. For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <PrevTrack keycode="144"/>
+ <Play keycode="162"/>
+ <Stop keycode="164"/>
+ <NextTrack keycode="153"/>
+
+ <VolUp keycode="176" adj="1"/>
+ <VolDown keycode="174" adj="1"/>
+
+ <WebBrowser keycode="243"/>
+ <Email keycode="244"/>
+ <Shell keycode="242"/>
+ <Help keycode="241"/>
+
+ <userdef keycode="160" command="aumix -vM">Sound muted</userdef>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/misc/hotkeys/xe3gf.def b/ubuntu/omnibook/misc/hotkeys/xe3gf.def
new file mode 100644
index 00000000000..8f8b40e56f1
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/xe3gf.def
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP OmniBook XE3 GF">
+
+ <!--
+ Multimedia keys are disabled by default on HP OmniBook
+ laptops. For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <PrevTrack keycode="144"/>
+ <Play keycode="162"/>
+ <Stop keycode="164"/>
+ <NextTrack keycode="153"/>
+
+ <VolUp keycode="176" adj="1"/>
+ <VolDown keycode="174" adj="1"/>
+
+ <Email keycode="236"/>
+ <WebBrowser keycode="178"/>
+ <Shell keycode="244"/>
+ <Help keycode="243"/>
+
+ <userdef keycode="160" command="aumix -vM">Sound muted</userdef>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/misc/hotkeys/xe4xxx.def b/ubuntu/omnibook/misc/hotkeys/xe4xxx.def
new file mode 100644
index 00000000000..6b14cde47a9
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/xe4xxx.def
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP OmniBook xe4xxx and ze4xxx">
+
+ <!--
+ Multimedia keys are disabled by default on HP OmniBook
+ laptops. For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <Email keycode="236"/>
+ <WebBrowser keycode="178"/>
+ <Shell keycode="243"/>
+ <ScreenSaver keycode="241"/>
+ <Help keycode="240"/>
+
+ <VolUp keycode="176" adj="1"/>
+ <VolDown keycode="174" adj="1"/>
+
+ <userdef keycode="160" command="aumix -vM">Sound muted</userdef>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/misc/hotkeys/xt155.def b/ubuntu/omnibook/misc/hotkeys/xt155.def
new file mode 100644
index 00000000000..d200bf09eac
--- /dev/null
+++ b/ubuntu/omnibook/misc/hotkeys/xt155.def
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<definition>
+ <config model="HP OmniBook xt155">
+
+ <!--
+ Multimedia keys are disabled by default on HP OmniBook
+ laptops. For enabling them see the project at URL
+ http://sourceforge.net/projects/omke
+ -->
+
+ <Email keycode="236"/>
+ <WebBrowser keycode="178"/>
+ <Shell keycode="243"/>
+ <ScreenSaver keycode="241"/>
+ <Help keycode="240"/>
+
+ </config>
+
+ <contributor>
+ <name>Soos, Peter</name>
+ <email>sp@osb.hu</email>
+ </contributor>
+</definition>
diff --git a/ubuntu/omnibook/muteled.c b/ubuntu/omnibook/muteled.c
new file mode 100644
index 00000000000..a21793a50bf
--- /dev/null
+++ b/ubuntu/omnibook/muteled.c
@@ -0,0 +1,109 @@
+/*
+ * mutled.c -- MUTE LED 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 Thomas Perl <thp@perli.net>, 2006
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_muteled_set(struct omnibook_operation *io_op, int status)
+{
+ int retval = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if((retval = __omnibook_toggle(io_op, !!status))) {
+ printk(O_ERR "Failed muteled %s command.\n", status ? "on" : "off");
+ goto out;
+ }
+
+ io_op->backend->muteled_state = !!status;
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Hardware query is unsupported, reading is unreliable.
+ */
+static int omnibook_muteled_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+ len +=
+ sprintf(buffer + len, "Last mute LED action was an %s command.\n",
+ io_op->backend->touchpad_state ? "on" : "off");
+
+ mutex_unlock(&io_op->backend->mutex);
+ return len;
+}
+
+static int omnibook_muteled_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int cmd;
+
+ if (*buffer == '0' || *buffer == '1') {
+ cmd = *buffer - '0';
+ if (!omnibook_muteled_set(io_op, cmd)) {
+ dprintk("Switching mute LED to %s state.\n", cmd ? "on" : "off");
+ }
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * May re-enable muteled upon resume
+ */
+static int omnibook_muteled_resume(struct omnibook_operation *io_op)
+{
+ int retval;
+ mutex_lock(&io_op->backend->mutex);
+ retval = __omnibook_toggle(io_op, !!io_op->backend->touchpad_state);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Switch muteled off upon exit
+ */
+static void __exit omnibook_muteled_cleanup(struct omnibook_operation *io_op)
+{
+ omnibook_muteled_set(io_op, 0);
+}
+
+static struct omnibook_tbl muteled_table[] __initdata = {
+ {XE4500, COMMAND(KBC, OMNIBOOK_KBC_CMD_MUTELED_ON, OMNIBOOK_KBC_CMD_MUTELED_OFF)},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature muteled_driver = {
+ .name = "muteled",
+ .enabled = 1,
+ .read = omnibook_muteled_read,
+ .write = omnibook_muteled_write,
+ .exit = omnibook_muteled_cleanup,
+ .resume = omnibook_muteled_resume,
+ .ectypes = XE4500,
+ .tbl = muteled_table,
+};
+
+module_param_named(muteled, muteled_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(muteled, "Use 0 to disable, 1 to enable 'Audo Mute' LED control");
diff --git a/ubuntu/omnibook/nbsmi.c b/ubuntu/omnibook/nbsmi.c
new file mode 100644
index 00000000000..8ce10b98015
--- /dev/null
+++ b/ubuntu/omnibook/nbsmi.c
@@ -0,0 +1,968 @@
+/*
+ * nbsmi.c -- Toshiba SMI low-level acces 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ *
+ * Sources of inspirations for this code were:
+ * -Toshiba via provided hardware specification
+ * -Thorsten Zachmann with the 's1bl' project
+ * -Frederico Munoz with the 'tecra_acpi' project
+ * Thanks to them
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+#include <linux/preempt.h>
+#include <linux/pci.h>
+#include <linux/kref.h>
+#include <asm/io.h>
+#include <asm/mc146818rtc.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+
+/* copied from drivers/input/serio/i8042-io.h */
+#define I8042_KBD_PHYS_DESC "isa0060/serio0"
+
+/*
+ * ATI's IXP PCI-LPC bridge
+ */
+#define INTEL_PMBASE 0x40
+#define INTEL_GPE0_EN 0x2c
+
+#define BUFFER_SIZE 0x20
+#define INTEL_OFFSET 0x60
+#define INTEL_SMI_PORT 0xb2 /* APM_CNT port in INTEL ICH specs */
+
+/*
+ * Toshiba Specs state 0xef here but:
+ * -this would overflow (ef + 19 > ff)
+ * -code from Toshiba use e0, which make much more sense
+ */
+
+#define ATI_OFFSET 0xe0
+#define ATI_SMI_PORT 0xb0
+
+#define EC_INDEX_PORT 0x300
+#define EC_DATA_PORT 0x301
+
+/* Masks decode for GetAeral */
+#define WLEX_MASK 0x4
+#define WLAT_MASK 0x8
+#define BTEX_MASK 0x1
+#define BTAT_MASK 0x2
+
+/*
+ * Private data of this backend
+ */
+struct nbsmi_backend_data {
+ struct pci_dev *lpc_bridge; /* Southbridge chip ISA bridge/LPC interface PCI device */
+ u8 start_offset; /* Start offset in CMOS memory */
+ struct input_dev *nbsmi_input_dev;
+ struct work_struct fnkey_work;
+};
+
+/*
+ * Possible list of supported southbridges
+ * Here mostly to implement a more or less clean PCI probing
+ * Works only because of previous DMI probing.
+ * It's in compal.c
+ */
+extern const struct pci_device_id lpc_bridge_table[];
+
+/*
+ * Since we are going to trigger an SMI, all registers (I assume this does not
+ * include esp and maybe ebp) and eflags may be mangled in the
+ * process.
+ * We also disable preemtion and IRQs upon SMI call.
+ */
+static inline u32 ati_do_smi_call(u16 function)
+{
+ unsigned long flags;
+ u32 retval = 0;
+
+ local_irq_save(flags);
+ preempt_disable();
+
+/*
+ * eflags, eax, ebx, ecx, edx, esi and edi are clobbered upon writing to SMI_PORT
+ * thus the clobber list.
+ *
+ * Equivalent pseudocode:
+ *
+ * eax = function; [non null]
+ * outw(eax, ATI_SMI_PORT); <- This Trigger an SMI
+ * if( eax == 0 ) [success if eax has been cleared]
+ * goto out;
+ * if( inb(ATI_SMI_PORT + 1) == 0) [if not in eax, success maybe be stored here]
+ * goto out;
+ * retval = -EIO; [too bad]
+ * out:
+ */
+ __asm__ __volatile__("outw %%ax, %2; \
+ orw %%ax, %%ax; \
+ jz 1f; \
+ inw %3, %%ax; \
+ orw %%ax, %%ax; \
+ jz 1f; \
+ movl %4, %0; \
+ 1:;"
+ : "=m" (retval)
+ : "a"(function), "N"(ATI_SMI_PORT), "N"(ATI_SMI_PORT+1), "i"(-EIO)
+ : "memory", "ebx", "ecx", "edx", "esi", "edi", "cc");
+
+ local_irq_restore(flags);
+ preempt_enable_no_resched();
+ return retval;
+}
+
+static inline u32 intel_do_smi_call(u16 function, struct pci_dev *lpc_bridge)
+{
+ u32 state;
+ unsigned long flags;
+ u32 retval = 0;
+ u32 sci_en = 0;
+
+ local_irq_save(flags);
+ preempt_disable();
+
+/*
+ * We get the PMBASE offset ( bits 15:7 at 0x40 offset of PCI config space )
+ * And we access offset 2c (GPE0_EN), save the state, disable all SCI
+ * and restore the state after the SMI call
+ */
+ pci_read_config_dword(lpc_bridge, INTEL_PMBASE, &sci_en);
+ sci_en = sci_en & 0xff80; /* Keep bits 15:7 */
+ sci_en += INTEL_GPE0_EN; /* GPEO_EN offset */
+ state = inl(sci_en);
+ outl(0, sci_en);
+
+/*
+ * eflags, eax, ebx, ecx, edx, esi and edi are clobbered upon writing to SMI_PORT
+ * thus the clobber list.
+ *
+ * Equivalent pseudocode:
+ *
+ * eax = function; [non null]
+ * outw(eax, INTEL_SMI_PORT); <- This Trigger an SMI
+ * if( eax == 0 ) [success if eax has been cleared]
+ * goto out;
+ * retval = -EIO; [too bad]
+ * out:
+ */
+ __asm__ __volatile__("outw %%ax, %2; \
+ orw %%ax, %%ax; \
+ jz 1f; \
+ movl %3, %0; \
+ 1:;"
+ : "=m" (retval)
+ : "a"(function), "N"(INTEL_SMI_PORT), "i"(-EIO)
+ : "memory", "ebx", "ecx", "edx", "esi", "edi", "cc");
+
+ outl(state, sci_en);
+ local_irq_restore(flags);
+ preempt_enable_no_resched();
+ return retval;
+}
+
+static int nbsmi_smi_command(u16 function,
+ const u8 * inputbuffer,
+ u8 * outputbuffer,
+ const struct nbsmi_backend_data *priv_data)
+{
+ int count;
+ u32 retval = 0;
+
+
+ for (count = 0; count < BUFFER_SIZE; count++) {
+ outb(count + priv_data->start_offset, RTC_PORT(2));
+ outb(*(inputbuffer + count), RTC_PORT(3));
+ }
+
+/*
+ * We have to write 0xe4XX to smi_port
+ * where XX is the SMI function code
+ */
+ function = (function & 0xff) << 8;
+ function |= 0xe4;
+
+ switch (priv_data->lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ retval = intel_do_smi_call(function, priv_data->lpc_bridge);
+ break;
+ case PCI_VENDOR_ID_ATI:
+ retval = ati_do_smi_call(function);
+ break;
+ default:
+ BUG();
+ }
+
+ if (retval)
+ printk(O_ERR "smi_command failed with error %u.\n", retval);
+
+ for (count = 0; count < BUFFER_SIZE; count++) {
+ outb(count + priv_data->start_offset, RTC_PORT(2));
+ *(outputbuffer + count) = inb(RTC_PORT(3));
+ }
+
+ return retval;
+}
+
+static int nbsmi_smi_read_command(const struct omnibook_operation *io_op, u8 * data)
+{
+ int retval;
+ u8 *inputbuffer;
+ u8 *outputbuffer;
+ struct nbsmi_backend_data *priv_data = io_op->backend->data;
+
+ if (!priv_data)
+ return -ENODEV;
+
+ inputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
+ if (!inputbuffer) {
+ retval = -ENOMEM;
+ goto error1;
+ }
+
+ outputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
+ if (!outputbuffer) {
+ retval = -ENOMEM;
+ goto error2;
+ }
+
+ retval = nbsmi_smi_command((u16) io_op->read_addr, inputbuffer, outputbuffer, priv_data);
+ if (retval)
+ goto out;
+
+ *data = outputbuffer[0];
+
+ if (io_op->read_mask)
+ *data &= io_op->read_mask;
+
+ out:
+ kfree(outputbuffer);
+ error2:
+ kfree(inputbuffer);
+ error1:
+ return retval;
+}
+
+static int nbsmi_smi_write_command(const struct omnibook_operation *io_op, u8 data)
+{
+ int retval;
+ u8 *inputbuffer;
+ u8 *outputbuffer;
+ struct nbsmi_backend_data *priv_data = io_op->backend->data;
+
+ if (!priv_data)
+ return -ENODEV;
+
+ inputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
+ if (!inputbuffer) {
+ retval = -ENOMEM;
+ goto error1;
+ }
+
+ outputbuffer = kcalloc(BUFFER_SIZE, sizeof(u8), GFP_KERNEL);
+ if (!outputbuffer) {
+ retval = -ENOMEM;
+ goto error2;
+ }
+
+ inputbuffer[0] = data;
+
+ retval = nbsmi_smi_command((u16) io_op->write_addr, inputbuffer, outputbuffer, priv_data);
+
+ kfree(outputbuffer);
+ error2:
+ kfree(inputbuffer);
+ error1:
+ return retval;
+}
+
+/*
+ * Read/Write to INDEX/DATA interface at port 0x300 (SMSC Mailbox registers)
+ */
+static inline void nbsmi_ec_read_command(u8 index, u8 * data)
+{
+ outb(index, EC_INDEX_PORT);
+ *data = inb(EC_DATA_PORT);
+}
+
+#if 0
+static inline void nbsmi_ec_write_command(u8 index, u8 data)
+{
+ outb(index, EC_INDEX_PORT);
+ outb(data, EC_DATA_PORT);
+}
+#endif
+
+
+/*
+ * Hotkeys workflow:
+ * 1. Fn+Foo pressed
+ * 2. Scancode 0x6d generated by kbd controller
+ * 3. Scancode 0x6d caught by omnibook input handler
+ * 4. SMI Call issued -> Got keycode of last actually pressed Fn key
+ * 5. nbsmi_scan_table used to associate a detected keycode with a generated one
+ * 6. Generated keycode issued using the omnibook input device
+ */
+
+/*
+ * The input handler should only bind with the standard AT keyboard.
+ * XXX: Scancode 0x6d won't be detected if the keyboard has already been
+ * grabbed (the Xorg event input driver do that)
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+static int hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ const struct input_device_id *id)
+#else
+static struct input_handle *hook_connect(struct input_handler *handler,
+ struct input_dev *dev,
+ struct input_device_id *id)
+#endif
+{
+ struct input_handle *handle;
+ int error;
+
+ /* the 0x0001 vendor magic number is found in atkbd.c */
+ if(!(dev->id.bustype == BUS_I8042 && dev->id.vendor == 0x0001))
+ goto out_nobind;
+
+ if(!strstr(dev->phys, I8042_KBD_PHYS_DESC))
+ goto out_nobind;
+
+ dprintk("hook_connect for device %s.\n", dev->name);
+
+ if(dev->grab)
+ printk(O_WARN "Input device is grabbed by %s, Fn hotkeys won't work.\n",
+ dev->grab->name);
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return -ENOMEM;
+#else
+ return NULL;
+#endif
+
+ handle->dev = dev;
+ handle->handler = handler;
+ handle->name = "omnibook_scancode_hook";
+ handle->private = handler->private;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ error = input_register_handle(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ goto out_nobind_free;
+ }
+ error = input_open_device(handle);
+ if (error) {
+ dprintk("register_handle failed\n");
+ input_unregister_handle(handle);
+ goto out_nobind_free;
+ }
+
+#else
+ error = input_open_device(handle);
+ if (error==0) dprintk("Input device opened\n");
+ else {
+ dprintk("opening input device failed\n");
+ goto out_nobind_free;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ return 0;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return -ENODEV;
+#else
+ return handle;
+out_nobind_free:
+ kfree(handle);
+out_nobind:
+ return NULL;
+#endif
+}
+
+static void hook_disconnect(struct input_handle *handle)
+{
+ dprintk("hook_disconnect.\n");
+ input_close_device(handle);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21))
+ input_unregister_handle(handle);
+#endif
+ kfree(handle);
+}
+
+/*
+ * Hook for scancode 0x6d. Actual handling is done in a workqueue as
+ * the nbsmi backend might sleep.
+ */
+
+static void hook_event(struct input_handle *handle, unsigned int event_type,
+ unsigned int event_code, int value)
+{
+ if (event_type == EV_MSC && event_code == MSC_SCAN && value == SMI_FN_SCAN)
+ schedule_work(&((struct nbsmi_backend_data *)handle->private)->fnkey_work);
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+static const struct input_device_id hook_ids[] = {
+#else
+static struct input_device_id hook_ids[] = {
+#endif
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
+ .evbit = { BIT(EV_KEY) },
+ },
+ { }, /* Terminating entry */
+};
+
+static struct input_handler hook_handler = {
+ .event = hook_event,
+ .connect = hook_connect,
+ .disconnect = hook_disconnect,
+ .name = OMNIBOOK_MODULE_NAME,
+ .id_table = hook_ids,
+};
+
+/*
+ * Define some KEY_ that may be missing in input.h for some kernel versions
+ */
+#ifndef KEY_WLAN
+#define KEY_WLAN 238
+#endif
+
+/*
+ * Detected scancode to keycode table
+ */
+static const struct {
+ unsigned int scancode;
+ unsigned int keycode;
+} nbsmi_scan_table[] = {
+ { KEY_ESC, KEY_MUTE},
+ { KEY_F1, KEY_FN_F1},
+ { KEY_F2, KEY_PROG1},
+ { KEY_F3, KEY_SLEEP},
+ { KEY_F4, KEY_SUSPEND},
+ { KEY_F5, KEY_SWITCHVIDEOMODE},
+ { KEY_F6, KEY_BRIGHTNESSDOWN},
+ { KEY_F7, KEY_BRIGHTNESSUP},
+ { KEY_F8, KEY_WLAN},
+ { KEY_F9, KEY_FN_F9},
+ { KEY_SPACE, KEY_ZOOM},
+ { 0,0},
+};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work);
+#else
+static void omnibook_handle_fnkey(void* data);
+#endif
+
+/*
+ * Register the input handler and the input device in the input subsystem
+ */
+static int register_input_subsystem(struct nbsmi_backend_data *priv_data)
+{
+ int i, retval = 0;
+ struct input_dev *nbsmi_input_dev;
+
+ nbsmi_input_dev = input_allocate_device();
+ if (!nbsmi_input_dev) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ nbsmi_input_dev->name = "Omnibook NbSMI scancode generator";
+ nbsmi_input_dev->phys = "omnibook/input0";
+ nbsmi_input_dev->id.bustype = BUS_HOST;
+
+ set_bit(EV_KEY, nbsmi_input_dev->evbit);
+
+ for(i=0 ; i < ARRAY_SIZE(nbsmi_scan_table); i++)
+ set_bit(nbsmi_scan_table[i].keycode, nbsmi_input_dev->keybit);
+
+ retval = input_register_device(nbsmi_input_dev);
+ if(retval) {
+ input_free_device(nbsmi_input_dev);
+ goto out;
+ }
+
+ priv_data->nbsmi_input_dev = nbsmi_input_dev;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey);
+#else
+ INIT_WORK(&priv_data->fnkey_work, *omnibook_handle_fnkey, priv_data);
+#endif
+
+
+ hook_handler.private = priv_data;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
+ retval = input_register_handler(&hook_handler);
+#else
+ input_register_handler(&hook_handler);
+#endif
+
+ out:
+ return retval;
+}
+
+/*
+ * Try to init the backend
+ * This function can be called blindly as it use a kref
+ * to check if the init sequence was already done.
+ */
+static int omnibook_nbsmi_init(const struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ int i;
+ u8 ec_data;
+ u32 smi_port = 0;
+ struct nbsmi_backend_data *priv_data;
+
+ /* ectypes other than TSM40 have no business with this backend */
+ if (!(omnibook_ectype & TSM40))
+ return -ENODEV;
+
+ if (io_op->backend->already_failed) {
+ dprintk("NbSmi backend init already failed, skipping.\n");
+ return -ENODEV;
+ }
+
+ if (!io_op->backend->data) {
+ /* Fist use of the backend */
+ dprintk("Try to init NbSmi\n");
+ mutex_init(&io_op->backend->mutex);
+ mutex_lock(&io_op->backend->mutex);
+ kref_init(&io_op->backend->kref);
+
+ priv_data = kzalloc(sizeof(struct nbsmi_backend_data), GFP_KERNEL);
+ if (!priv_data) {
+ retval = -ENOMEM;
+ goto error0;
+ }
+
+ /* PCI probing: find the LPC Super I/O bridge PCI device */
+ for (i = 0; !priv_data->lpc_bridge && lpc_bridge_table[i].vendor; ++i)
+ priv_data->lpc_bridge =
+ pci_get_device(lpc_bridge_table[i].vendor, lpc_bridge_table[i].device,
+ NULL);
+
+ if (!priv_data->lpc_bridge) {
+ printk(O_ERR "Fail to find a supported LPC I/O bridge, please report\n");
+ retval = -ENODEV;
+ goto error1;
+ }
+
+ if ((retval = pci_enable_device(priv_data->lpc_bridge))) {
+ printk(O_ERR "Unable to enable PCI device.\n");
+ goto error2;
+ }
+
+ switch (priv_data->lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ priv_data->start_offset = INTEL_OFFSET;
+ smi_port = INTEL_SMI_PORT;
+ break;
+ case PCI_VENDOR_ID_ATI:
+ priv_data->start_offset = ATI_OFFSET;
+ smi_port = ATI_SMI_PORT;
+ break;
+ default:
+ BUG();
+ }
+
+ if (!request_region(smi_port, 2, OMNIBOOK_MODULE_NAME)) {
+ printk(O_ERR "Request SMI I/O region error\n");
+ retval = -ENODEV;
+ goto error2;
+ }
+
+ if (!request_region(EC_INDEX_PORT, 2, OMNIBOOK_MODULE_NAME)) {
+ printk(O_ERR "Request EC I/O region error\n");
+ retval = -ENODEV;
+ goto error3;
+ }
+
+ /*
+ * Try some heuristic tests to avoid enabling this interface on unsuported laptops:
+ * See what a port 300h read index 8f gives. Guess there is nothing if read 0xff
+ */
+
+ nbsmi_ec_read_command(SMI_FN_PRESSED, &ec_data);
+ dprintk("NbSmi test probe read: %x\n", ec_data);
+ if (ec_data == 0xff) {
+ printk(O_ERR "Probing at SMSC Mailbox registers failed, disabling NbSmi\n");
+ retval = -ENODEV;
+ goto error4;
+ }
+
+ retval = register_input_subsystem(priv_data);
+ if(retval)
+ goto error4;
+
+ io_op->backend->data = priv_data;
+
+ dprintk("NbSmi init ok\n");
+ mutex_unlock(&io_op->backend->mutex);
+ return 0;
+ } else {
+ dprintk("NbSmi has already been initialized\n");
+ kref_get(&io_op->backend->kref);
+ return 0;
+ }
+ error4:
+ release_region(EC_INDEX_PORT, 2);
+ error3:
+ release_region(smi_port, 2);
+ error2:
+ pci_dev_put(priv_data->lpc_bridge);
+ error1:
+ kfree(priv_data);
+ io_op->backend->data = NULL;
+ error0:
+ io_op->backend->already_failed = 1;
+ mutex_unlock(&io_op->backend->mutex);
+ mutex_destroy(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Free all allocated stuff and unregister from the input subsystem
+ */
+static void nbsmi_free(struct kref *ref)
+{
+ u32 smi_port = 0;
+ struct omnibook_backend *backend;
+ struct nbsmi_backend_data *priv_data;
+
+ dprintk("NbSmi not used anymore: disposing\n");
+
+ backend = container_of(ref, struct omnibook_backend, kref);
+ priv_data = backend->data;
+
+ flush_scheduled_work();
+ input_unregister_handler(&hook_handler);
+ input_unregister_device(priv_data->nbsmi_input_dev);
+
+ mutex_lock(&backend->mutex);
+
+ switch (priv_data->lpc_bridge->vendor) {
+ case PCI_VENDOR_ID_INTEL:
+ smi_port = INTEL_SMI_PORT;
+ break;
+ case PCI_VENDOR_ID_ATI:
+ smi_port = ATI_SMI_PORT;
+ break;
+ default:
+ BUG();
+ }
+
+ pci_dev_put(priv_data->lpc_bridge);
+ release_region(smi_port, 2);
+ release_region(EC_INDEX_PORT, 2);
+ kfree(priv_data);
+ backend->data = NULL;
+ mutex_unlock(&backend->mutex);
+ mutex_destroy(&backend->mutex);
+}
+
+static void omnibook_nbsmi_exit(const struct omnibook_operation *io_op)
+{
+ /* ectypes other than TSM40 have no business with this backend */
+ BUG_ON(!(omnibook_ectype & TSM40));
+ dprintk("Trying to dispose NbSmi\n");
+ kref_put(&io_op->backend->kref, nbsmi_free);
+}
+
+/*
+ * Adjust the lcd backlight level by delta.
+ * Used for Fn+F6/F7 keypress
+ */
+static int adjust_brighness(int delta)
+{
+ struct omnibook_feature *lcd_feature = omnibook_find_feature("lcd");
+ struct omnibook_operation *io_op;
+ int retval = 0;
+ u8 brgt;
+
+ if(!lcd_feature)
+ return -ENODEV;
+
+ io_op = lcd_feature->io_op;
+
+ mutex_lock(&io_op->backend->mutex);
+
+ if(( retval = __backend_byte_read(io_op, &brgt)))
+ goto out;
+
+ dprintk("FnF6/F7 pressed: adjusting britghtnes.\n");
+
+ if (((int) brgt + delta) < 0)
+ brgt = 0;
+ else if ((brgt + delta) > omnibook_max_brightness)
+ brgt = omnibook_max_brightness;
+ else
+ brgt += delta;
+
+ retval = __backend_byte_write(io_op, brgt);
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static const struct omnibook_operation last_scan_op = SIMPLE_BYTE(SMI,SMI_GET_FN_LAST_SCAN,0);
+
+/*
+ * Workqueue handler for Fn hotkeys
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_handle_fnkey(struct work_struct *work)
+#else
+static void omnibook_handle_fnkey(void* data)
+#endif
+{
+ int i;
+ u8 gen_scan;
+ struct input_dev *input_dev;
+
+ if(backend_byte_read(&last_scan_op, &gen_scan))
+ return;
+
+ dprintk("detected scancode %x.\n", gen_scan);
+ switch(gen_scan) {
+ case KEY_F6:
+ adjust_brighness(-1);
+ break;
+ case KEY_F7:
+ adjust_brighness(+1);
+ break;
+ }
+
+ for(i = 0 ; i < ARRAY_SIZE(nbsmi_scan_table); i++) {
+ if( gen_scan == nbsmi_scan_table[i].scancode) {
+ dprintk("generating keycode %i.\n", nbsmi_scan_table[i].keycode);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ input_dev = container_of(work, struct nbsmi_backend_data, fnkey_work)->nbsmi_input_dev;
+#else
+ input_dev = ((struct nbsmi_backend_data *) data)->nbsmi_input_dev;
+#endif
+ omnibook_report_key(input_dev, nbsmi_scan_table[i].keycode);
+ break;
+ }
+ }
+}
+
+static int omnibook_nbsmi_get_wireless(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval = 0;
+ struct omnibook_operation aerial_op = SIMPLE_BYTE(SMI, SMI_GET_KILL_SWITCH, 0);
+ u8 data;
+
+ if ((retval = nbsmi_smi_read_command(&aerial_op, &data)))
+ goto out;
+
+ dprintk("get_wireless (kill switch) raw_state: %x\n", data);
+
+ *state = data ? KILLSWITCH : 0;
+
+ aerial_op.read_addr = SMI_GET_AERIAL;
+
+ if ((retval = nbsmi_smi_read_command(&aerial_op, &data)))
+ goto out;
+
+ dprintk("get_wireless (aerial) raw_state: %x\n", data);
+
+ *state |= (data & WLEX_MASK) ? WIFI_EX : 0;
+ *state |= (data & WLAT_MASK) ? WIFI_STA : 0;
+ *state |= (data & BTEX_MASK) ? BT_EX : 0;
+ *state |= (data & BTAT_MASK) ? BT_STA : 0;
+
+ out:
+ return retval;
+}
+
+static int omnibook_nbsmi_set_wireless(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval = 0;
+ u8 data;
+ struct omnibook_operation aerial_op = SIMPLE_BYTE(SMI, SMI_SET_AERIAL, 0);
+
+ data = !!(state & BT_STA);
+ data |= !!(state & WIFI_STA) << 0x1;
+
+ dprintk("set_wireless raw_state: %x\n", data);
+
+ retval = nbsmi_smi_write_command(&aerial_op, data);
+
+ return retval;
+}
+
+static int omnibook_nbmsi_hotkeys_get(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval;
+ u8 data = 0;
+ struct omnibook_operation hotkeys_op = SIMPLE_BYTE(SMI, SMI_GET_FN_INTERFACE, 0);
+
+ retval = nbsmi_smi_read_command(&hotkeys_op, &data);
+ if (retval < 0)
+ return retval;
+
+ dprintk("get_hotkeys raw_state: %x\n", data);
+
+ *state = (data & SMI_FN_KEYS_MASK) ? HKEY_FN : 0;
+ *state |= (data & SMI_STICK_KEYS_MASK) ? HKEY_STICK : 0;
+ *state |= (data & SMI_FN_TWICE_LOCK_MASK) ? HKEY_TWICE_LOCK : 0;
+ *state |= (data & SMI_FN_DOCK_MASK) ? HKEY_DOCK : 0;
+
+ return 0;
+}
+
+
+static int omnibook_nbmsi_hotkeys_set(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int i, retval;
+ u8 data, rdata;
+ struct omnibook_operation hotkeys_op = SIMPLE_BYTE(SMI, SMI_SET_FN_F5_INTERFACE, 0);
+ u8* data_array;
+
+ data = !!(state & HKEY_FNF5);
+
+ dprintk("set_hotkeys (Fn F5) raw_state: %x\n", data);
+
+ retval = nbsmi_smi_write_command(&hotkeys_op, data);
+ if (retval < 0)
+ return retval;
+
+ hotkeys_op.write_addr = SMI_SET_FN_INTERFACE;
+ hotkeys_op.read_addr = SMI_GET_FN_INTERFACE;
+
+ data = (state & HKEY_FN) ? SMI_FN_KEYS_MASK : 0;
+ data |= (state & HKEY_STICK) ? SMI_STICK_KEYS_MASK : 0;
+ data |= (state & HKEY_TWICE_LOCK) ? SMI_FN_TWICE_LOCK_MASK : 0;
+ data |= (state & HKEY_DOCK) ? SMI_FN_DOCK_MASK : 0;
+
+ dprintk("set_hotkeys (Fn interface) raw_state: %x\n", data);
+
+ /*
+ * Hardware seems to be quite stubborn and multiple retries may be
+ * required. The criteria here is simple: retry until probed state match
+ * the requested one (with timeout).
+ */
+
+ data_array = kcalloc(250, sizeof(u8), GFP_KERNEL);
+ if(!data_array)
+ return -ENODEV;
+
+ for (i = 0; i < 250; i++) {
+ retval = nbsmi_smi_write_command(&hotkeys_op, data);
+ if (retval)
+ goto out;
+ mdelay(1);
+ retval = nbsmi_smi_read_command(&hotkeys_op, &rdata);
+ if(retval)
+ goto out;
+ data_array[i] = rdata;
+ if(rdata == data) {
+ dprintk("check loop ok after %i iters\n.",i);
+ retval = 0;
+ goto out;
+ }
+ }
+ dprintk("error or check loop timeout !!\n");
+ dprintk("forensics datas: ");
+ for (i = 0; i < 250; i++)
+ dprintk_simple("%x ", data_array[i]);
+ dprintk_simple("\n");
+out:
+ kfree(data_array);
+ return retval;
+}
+
+static const unsigned int nbsmi_display_mode_list[] = {
+ DISPLAY_LCD_ON,
+ DISPLAY_LCD_ON | DISPLAY_CRT_ON,
+ DISPLAY_CRT_ON,
+ DISPLAY_LCD_ON | DISPLAY_TVO_ON,
+ DISPLAY_TVO_ON,
+};
+
+static int omnibook_nbmsi_display_get(const struct omnibook_operation *io_op, unsigned int *state)
+{
+ int retval = 0;
+ u8 data;
+
+ retval = nbsmi_smi_read_command(io_op, &data);
+ if (retval < 0)
+ return retval;
+
+ if (data > (ARRAY_SIZE(nbsmi_display_mode_list) - 1))
+ return -EIO;
+
+ *state = nbsmi_display_mode_list[data];
+
+ return DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON;
+}
+
+static int omnibook_nbmsi_display_set(const struct omnibook_operation *io_op, unsigned int state)
+{
+ int retval;
+ int i;
+ u8 matched = 255;
+
+ for (i = 0; i < ARRAY_SIZE(nbsmi_display_mode_list); i++) {
+ if (nbsmi_display_mode_list[i] == state) {
+ matched = i;
+ break;
+ }
+ }
+
+ if(matched == 255) {
+ printk(O_ERR "Display mode %x is unsupported.\n", state);
+ return -EINVAL;
+ }
+
+ retval = nbsmi_smi_write_command(io_op, matched);
+ if (retval < 0)
+ return retval;
+
+ return DISPLAY_LCD_ON | DISPLAY_CRT_ON | DISPLAY_TVO_ON;
+}
+
+struct omnibook_backend nbsmi_backend = {
+ .name = "nbsmi",
+ .hotkeys_read_cap = HKEY_FN | HKEY_STICK | HKEY_TWICE_LOCK | HKEY_DOCK,
+ .hotkeys_write_cap = HKEY_FN | HKEY_STICK | HKEY_TWICE_LOCK | HKEY_DOCK | HKEY_FNF5,
+ .init = omnibook_nbsmi_init,
+ .exit = omnibook_nbsmi_exit,
+ .byte_read = nbsmi_smi_read_command,
+ .byte_write = nbsmi_smi_write_command,
+ .aerial_get = omnibook_nbsmi_get_wireless,
+ .aerial_set = omnibook_nbsmi_set_wireless,
+ .hotkeys_get = omnibook_nbmsi_hotkeys_get,
+ .hotkeys_set = omnibook_nbmsi_hotkeys_set,
+ .display_get = omnibook_nbmsi_display_get,
+ .display_set = omnibook_nbmsi_display_set,
+};
diff --git a/ubuntu/omnibook/omnibook.h b/ubuntu/omnibook/omnibook.h
new file mode 100644
index 00000000000..db811144d51
--- /dev/null
+++ b/ubuntu/omnibook/omnibook.h
@@ -0,0 +1,145 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006-2007
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/input.h>
+#include <linux/version.h>
+
+/*
+ * EC types
+ */
+
+extern enum omnibook_ectype_t {
+ NONE = 0, /* 0 Default/unknown EC type */
+ XE3GF = (1<<0), /* 1 HP OmniBook XE3 GF, most old Toshiba Satellites */
+ XE3GC = (1<<1), /* 2 HP OmniBook XE3 GC, GD, GE and compatible */
+ OB500 = (1<<2), /* 3 HP OmniBook 500 and compatible */
+ OB510 = (1<<3), /* 4 HP OmniBook 510 */
+ OB6000 = (1<<4), /* 5 HP OmniBook 6000 */
+ OB6100 = (1<<5), /* 6 HP OmniBook 6100 */
+ XE4500 = (1<<6), /* 7 HP OmniBook xe4500 and compatible */
+ OB4150 = (1<<7), /* 8 HP OmniBook 4150 */
+ XE2 = (1<<8), /* 9 HP OmniBook XE2 */
+ AMILOD = (1<<9), /* 10 Fujitsu Amilo D */
+ TSP10 = (1<<10), /* 11 Toshiba Satellite P10, P15, P20 and compatible */
+ TSM70 = (1<<11), /* 12 Toshiba Satellite M40X, M70 and compatible */
+ TSM40 = (1<<12), /* 13 Toshiba Satellite M40, M45 and Tecra S1 */
+ TSA105 = (1<<13), /* 14 Toshiba Satellite A105 and compatible (Real support is MISSING) */
+ TSM30X = (1<<14), /* 15 Toshiba Stallite M30X and compatible */
+ TSX205 = (1<<15) /* 16 Toshiba Stallite X205 and compatible */
+} omnibook_ectype;
+
+#define ALL_ECTYPES XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|XE2|AMILOD|TSP10|TSM70|TSM40|TSA105|TSM30X|TSX205
+
+/*
+ * This represent a feature provided by this module
+ */
+
+struct omnibook_operation;
+
+struct omnibook_feature {
+ char *name; /* Name */
+ int enabled; /* Set from module parameter */
+ int (*read) (char *,struct omnibook_operation *); /* Procfile read function */
+ int (*write) (char *,struct omnibook_operation *); /* Procfile write function */
+ int (*init) (struct omnibook_operation *); /* Specific Initialization function */
+ void (*exit) (struct omnibook_operation *); /* Specific Cleanup function */
+ int (*suspend) (struct omnibook_operation *); /* PM Suspend function */
+ int (*resume) (struct omnibook_operation *); /* PM Resume function */
+ int ectypes; /* Type(s) of EC we support for this feature (bitmask) */
+ struct omnibook_tbl *tbl;
+ struct omnibook_operation *io_op;
+ struct list_head list;
+};
+
+/*
+ * State of a Wifi/Bluetooth adapter
+ */
+enum {
+ WIFI_EX = (1<<0), /* 1 1=present 0=absent */
+ WIFI_STA = (1<<1), /* 2 1=enabled 0=disabled */
+ KILLSWITCH = (1<<2), /* 4 1=radio on 0=radio off */
+ BT_EX = (1<<3), /* 8 1=present 0=absent */
+ BT_STA = (1<<4), /* 16 1=enabled 0=disabled */
+};
+
+/*
+ * Hotkeys state backend neutral masks
+ */
+enum {
+ HKEY_ONETOUCH = (1<<0), /* 1 Ontetouch button scancode generation */
+ HKEY_MULTIMEDIA = (1<<1), /* 2 "Multimedia hotkeys" scancode generation */
+ HKEY_FN = (1<<2), /* 4 Fn + foo hotkeys scancode generation */
+ HKEY_STICK = (1<<3), /* 8 Stick key (Fn locked/unlocked on keypress) */
+ HKEY_TWICE_LOCK = (1<<4), /* 16 Press Fn twice to lock */
+ HKEY_DOCK = (1<<5), /* 32 (Un)Dock events scancode generation */
+ HKEY_FNF5 = (1<<6), /* 64 Fn + F5 (toggle display) is enabled */
+};
+
+#define HKEY_LAST_SHIFT 6
+
+/*
+ * Display state backend neutral masks
+ * _ON masks = port is powered up and running
+ * _DET masks = a plugged display have been detected
+ */
+
+enum {
+ DISPLAY_LCD_ON = (1<<0), /* 1 Internal LCD panel */
+ DISPLAY_CRT_ON = (1<<1), /* 2 External VGA port */
+ DISPLAY_TVO_ON = (1<<2), /* 4 External TV-OUT port */
+ DISPLAY_DVI_ON = (1<<3), /* 8 External DVI port */
+ DISPLAY_LCD_DET = (1<<4), /* 16 Internal LCD panel */
+ DISPLAY_CRT_DET = (1<<5), /* 32 External VGA port */
+ DISPLAY_TVO_DET = (1<<6), /* 64 External TV-OUT port */
+ DISPLAY_DVI_DET = (1<<7), /* 128 External DVI port */
+};
+
+extern unsigned int omnibook_max_brightness;
+int set_omnibook_param(const char *val, struct kernel_param *kp);
+int omnibook_lcd_blank(int blank);
+struct omnibook_feature *omnibook_find_feature(char *name);
+void omnibook_report_key(struct input_dev *dev, unsigned int keycode);
+
+/*
+ * __attribute_used__ is not defined anymore in 2.6.24
+ * but __used appeared only in 2.6.22
+ */
+#ifndef __used
+#define __used __attribute_used__
+#endif
+
+#define __declared_feature __attribute__ (( __section__(".features"), __aligned__(__alignof__ (struct omnibook_feature)))) __used
+
+/*
+ * yet another printk wrapper
+ */
+#define O_INFO KERN_INFO OMNIBOOK_MODULE_NAME ": "
+#define O_WARN KERN_WARNING OMNIBOOK_MODULE_NAME ": "
+#define O_ERR KERN_ERR OMNIBOOK_MODULE_NAME ": "
+
+#ifdef CONFIG_OMNIBOOK_DEBUG
+#define dprintk(fmt, args...) printk(KERN_INFO "%s: " fmt, OMNIBOOK_MODULE_NAME, ## args)
+#define dprintk_simple(fmt, args...) printk(fmt, ## args)
+#else
+#define dprintk(fmt, args...) do { } while(0)
+#define dprintk_simple(fmt, args...) do { } while(0)
+#endif
+
+/* End of file */
diff --git a/ubuntu/omnibook/pio.c b/ubuntu/omnibook/pio.c
new file mode 100644
index 00000000000..312811efdf7
--- /dev/null
+++ b/ubuntu/omnibook/pio.c
@@ -0,0 +1,173 @@
+/*
+ * pio.c -- low level functions I/O ports
+ *
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include "hardware.h"
+
+/*
+ * IO port backend. Only support single or dual ports operations
+ * private data structure: it's the linked list of requested ports
+ *
+ * Race condition issue: omnibook_pio_init/exit functions are only called from
+ * omnibook_backend_match and omnibook_remove from init.c, this should happen
+ * only at module init/exit time so there is no need for a lock.
+ */
+
+struct pio_priv_data_t {
+ unsigned long addr;
+ struct kref refcount;
+ struct list_head list;
+};
+
+static struct pio_priv_data_t pio_priv_data = {
+ .addr = 0,
+ .list = LIST_HEAD_INIT(pio_priv_data.list),
+};
+
+/*
+ * Match an entry in the linked list helper function: see if we have and entry
+ * whose addr field match maddr
+ */
+static struct pio_priv_data_t *omnibook_match_port(struct pio_priv_data_t *data,
+ unsigned long maddr)
+{
+ struct pio_priv_data_t *cursor;
+
+ list_for_each_entry(cursor, &data->list, list) {
+ if (cursor->addr == maddr) {
+ return cursor;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * See if we have to request raddr
+ */
+static int omnibook_claim_port(struct pio_priv_data_t *data, unsigned long raddr)
+{
+ struct pio_priv_data_t *match, *new;
+
+ match = omnibook_match_port(data, raddr);
+ if (match) {
+ /* Already requested by us: increment kref and quit */
+ kref_get(&match->refcount);
+ return 0;
+ }
+
+ /* there was no match: request the region and add to list */
+ if (!request_region(raddr, 1, OMNIBOOK_MODULE_NAME)) {
+ printk(O_ERR "Request I/O port error\n");
+ return -ENODEV;
+ }
+
+ new = kmalloc(sizeof(struct pio_priv_data_t), GFP_KERNEL);
+ if (!new) {
+ release_region(raddr, 1);
+ return -ENOMEM;
+ }
+
+ kref_init(&new->refcount);
+ new->addr = raddr;
+ list_add(&new->list, &data->list);
+
+ return 0;
+}
+
+/*
+ * Register read_addr and write_addr
+ */
+static int omnibook_pio_init(const struct omnibook_operation *io_op)
+{
+ int retval = 0;
+
+ if (io_op->read_addr
+ && (retval = omnibook_claim_port(io_op->backend->data, io_op->read_addr)))
+ goto out;
+
+ if (io_op->write_addr && (io_op->write_addr != io_op->read_addr))
+ retval = omnibook_claim_port(io_op->backend->data, io_op->write_addr);
+
+ out:
+ return retval;
+}
+
+/*
+ * REALLY release a port
+ */
+static void omnibook_free_port(struct kref *ref)
+{
+ struct pio_priv_data_t *data;
+
+ data = container_of(ref, struct pio_priv_data_t, refcount);
+ release_region(data->addr, 1);
+ list_del(&data->list);
+ kfree(data);
+}
+
+/*
+ * Unregister read_addr and write_addr
+ */
+static void omnibook_pio_exit(const struct omnibook_operation *io_op)
+{
+ struct pio_priv_data_t *match;
+
+ match = omnibook_match_port(io_op->backend->data, io_op->read_addr);
+ if (match)
+ kref_put(&match->refcount, omnibook_free_port);
+
+ match = omnibook_match_port(io_op->backend->data, io_op->write_addr);
+ if (match)
+ kref_put(&match->refcount, omnibook_free_port);
+
+}
+
+static int omnibook_io_read(const struct omnibook_operation *io_op, u8 * value)
+{
+ *value = inb(io_op->read_addr);
+ if (io_op->read_mask)
+ *value &= io_op->read_mask;
+ return 0;
+}
+
+static int omnibook_io_write(const struct omnibook_operation *io_op, u8 value)
+{
+ outb(io_op->write_addr, value);
+ return 0;
+}
+
+/*
+ * Backend interface declarations
+ */
+struct omnibook_backend pio_backend = {
+ .name = "pio",
+ .data = &pio_priv_data,
+ .init = omnibook_pio_init,
+ .exit = omnibook_pio_exit,
+ .byte_read = omnibook_io_read,
+ .byte_write = omnibook_io_write,
+};
+
+/* End of file */
diff --git a/ubuntu/omnibook/polling.c b/ubuntu/omnibook/polling.c
new file mode 100644
index 00000000000..2d28f7e4e1e
--- /dev/null
+++ b/ubuntu/omnibook/polling.c
@@ -0,0 +1,259 @@
+/*
+ * polling.c -- scancode emulation for volume 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+#include <linux/workqueue.h>
+#include <linux/jiffies.h>
+
+/*
+ * XE3GC type key_polling polling:
+ *
+ * Polling interval for keys (100 ms)
+ */
+
+#define OMNIBOOK_POLL msecs_to_jiffies(100)
+
+/*
+ * workqueue manipulations are mutex protected and thus kept in sync with key_polling_enabled
+ */
+static struct workqueue_struct *omnibook_wq;
+static int key_polling_enabled;
+static DEFINE_MUTEX(poll_mutex);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+static void omnibook_key_poller(struct work_struct *work);
+DECLARE_DELAYED_WORK(omnibook_poll_work, *omnibook_key_poller);
+#else
+static void omnibook_key_poller(void *data);
+DECLARE_WORK(omnibook_poll_work, *omnibook_key_poller, NULL);
+#endif
+
+static struct omnibook_feature key_polling_driver;
+static struct input_dev *poll_input_dev;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19))
+ static void omnibook_key_poller(struct work_struct *work)
+#else
+ static void omnibook_key_poller(void *data)
+#endif
+{
+ u8 q0a;
+ int retval;
+
+ mutex_lock(&key_polling_driver.io_op->backend->mutex);
+ __backend_byte_read(key_polling_driver.io_op, &q0a);
+ __backend_byte_write(key_polling_driver.io_op, 0);
+ mutex_unlock(&key_polling_driver.io_op->backend->mutex);
+
+#ifdef CONFIG_OMNIBOOK_DEBUG
+ if (unlikely(q0a & XE3GC_SLPB_MASK))
+ dprintk("Sleep button pressed.\n");
+ if (unlikely(q0a & XE3GC_F5_MASK))
+ dprintk("Fn-F5 - LCD/CRT switch pressed.\n");
+ if (unlikely(q0a & XE3GC_CNTR_MASK))
+ dprintk("Fn+F3/Fn+F4 - Contrast up or down pressed.\n");
+ if (unlikely(q0a & XE3GC_BRGT_MASK))
+ dprintk("Fn+F1/Fn+F2 - Brightness up or down pressed.\n");
+#endif
+
+ /*
+ * Volume button scancode emulaton
+ * It emulates a key press and a release without repeat as other OneTouch buttons do.
+ */
+
+ if (unlikely(q0a & XE3GC_VOLD_MASK)) {
+ dprintk("Fn-down arrow or Volume down pressed.\n");
+ omnibook_report_key(poll_input_dev, KEY_VOLUMEDOWN);
+ }
+ if (unlikely(q0a & XE3GC_VOLU_MASK)) {
+ dprintk("Fn-up arrow or Volume up pressed.\n");
+ omnibook_report_key(poll_input_dev, KEY_VOLUMEUP);
+ }
+ if (unlikely(q0a & XE3GC_MUTE_MASK)) {
+ dprintk("Fn+F7 - Volume mute pressed.\n");
+ omnibook_report_key(poll_input_dev, KEY_MUTE);
+ }
+
+ retval = queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
+ if(unlikely(!retval)) /* here non-zero on success */
+ printk(O_ERR "Key_poller failed to rearm.\n");
+}
+
+static int omnibook_key_polling_enable(void)
+{
+ int retval = 0;
+
+ if(mutex_lock_interruptible(&poll_mutex))
+ return -ERESTARTSYS;
+
+ if(key_polling_enabled)
+ goto out;
+
+ retval = !queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
+ if(retval)
+ printk(O_ERR "Key_poller enabling failed.\n");
+ else {
+ dprintk("Scancode emulation for volume buttons enabled.\n");
+ key_polling_enabled = 1;
+ }
+
+ out:
+ mutex_unlock(&poll_mutex);
+ return retval;
+}
+
+static int omnibook_key_polling_disable(void)
+{
+ if(mutex_lock_interruptible(&poll_mutex))
+ return -ERESTARTSYS;
+
+ if(!key_polling_enabled)
+ goto out;
+
+ cancel_rearming_delayed_workqueue(omnibook_wq, &omnibook_poll_work);
+ dprintk("Scancode emulation for volume buttons disabled.\n");
+ key_polling_enabled = 0;
+
+ out:
+ mutex_unlock(&poll_mutex);
+ return 0;
+}
+
+
+static int omnibook_key_polling_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ if(mutex_lock_interruptible(&poll_mutex))
+ return -ERESTARTSYS;
+
+ len += sprintf(buffer + len, "Volume buttons polling is %s.\n",
+ (key_polling_enabled) ? "enabled" : "disabled");
+#ifdef CONFIG_OMNIBOOK_DEBUG
+ if(key_polling_enabled)
+ len += sprintf(buffer + len, "Will poll in %i msec.\n",
+ jiffies_to_msecs(omnibook_poll_work.timer.expires - jiffies));
+#endif
+ mutex_unlock(&poll_mutex);
+ return len;
+}
+
+static int omnibook_key_polling_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval;
+ switch (*buffer) {
+ case '0':
+ retval = omnibook_key_polling_disable();
+ break;
+ case '1':
+ retval = omnibook_key_polling_enable();
+ break;
+ default:
+ retval = -EINVAL;
+ }
+ return retval;
+}
+
+
+/*
+ * Stop polling upon suspend an restore it upon resume
+ */
+static int omnibook_key_polling_resume(struct omnibook_operation *io_op)
+{
+ int retval = 0;
+
+ mutex_lock(&poll_mutex);
+ if(key_polling_enabled)
+ retval = !queue_delayed_work(omnibook_wq, &omnibook_poll_work, OMNIBOOK_POLL);
+ mutex_unlock(&poll_mutex);
+ return retval;
+}
+
+static int omnibook_key_polling_suspend(struct omnibook_operation *io_op)
+{
+ mutex_lock(&poll_mutex);
+ if(key_polling_enabled)
+ cancel_rearming_delayed_workqueue(omnibook_wq, &omnibook_poll_work);
+ mutex_unlock(&poll_mutex);
+ return 0;
+}
+
+static int __init omnibook_key_polling_init(struct omnibook_operation *io_op)
+{
+ int retval = 0;
+
+ poll_input_dev = input_allocate_device();
+ if (!poll_input_dev) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ poll_input_dev->name = "Omnibook legacy laptop scancode generator";
+ poll_input_dev->phys = "omnibook/input0";
+ poll_input_dev->id.bustype = BUS_HOST;
+
+ /* this device has three keys */
+ set_bit(EV_KEY, poll_input_dev->evbit);
+ set_bit(KEY_VOLUMEDOWN, poll_input_dev->keybit);
+ set_bit(KEY_VOLUMEUP, poll_input_dev->keybit);
+ set_bit(KEY_MUTE, poll_input_dev->keybit);
+
+ retval = input_register_device(poll_input_dev);
+ if (retval) {
+ input_free_device(poll_input_dev);
+ goto out;
+ }
+
+ omnibook_wq = create_singlethread_workqueue("omnibook");
+ if(!omnibook_wq)
+ retval = -ENOMEM;
+ else
+ retval = omnibook_key_polling_enable();
+
+out:
+ return retval;
+}
+
+static void __exit omnibook_key_polling_cleanup(struct omnibook_operation *io_op)
+{
+ omnibook_key_polling_disable();
+ destroy_workqueue(omnibook_wq);
+ input_unregister_device(poll_input_dev);
+}
+
+static struct omnibook_tbl key_polling_table[] __initdata = {
+ {XE3GC, SIMPLE_BYTE(EC, XE3GC_Q0A, 0)},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature key_polling_driver = {
+ .name = "key_polling",
+ .enabled = 0, /* dangerous */
+ .read = omnibook_key_polling_read,
+ .write = omnibook_key_polling_write,
+ .init = omnibook_key_polling_init,
+ .exit = omnibook_key_polling_cleanup,
+ .suspend = omnibook_key_polling_suspend,
+ .resume = omnibook_key_polling_resume,
+ .ectypes = XE3GC,
+ .tbl = key_polling_table,
+};
+
+module_param_named(key_polling, key_polling_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(key_polling, "Use 0 to disable, 1 to enable key polling");
+/* End of file */
diff --git a/ubuntu/omnibook/sections.lds b/ubuntu/omnibook/sections.lds
new file mode 100644
index 00000000000..7fc90dd8832
--- /dev/null
+++ b/ubuntu/omnibook/sections.lds
@@ -0,0 +1,11 @@
+SECTIONS
+{
+ .data :
+ {
+ . = ALIGN(32);
+ _start_features_driver = .;
+ *(.features)
+ _end_features_driver = .;
+ *(.data)
+ }
+}
diff --git a/ubuntu/omnibook/temperature.c b/ubuntu/omnibook/temperature.c
new file mode 100644
index 00000000000..b27b6118fc5
--- /dev/null
+++ b/ubuntu/omnibook/temperature.c
@@ -0,0 +1,55 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_temperature_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int retval;
+ u8 temp;
+
+ if ((retval = backend_byte_read(io_op, &temp)))
+ return retval;
+
+ len += sprintf(buffer + len, "CPU temperature: %2d C\n", temp);
+
+ return len;
+}
+
+static struct omnibook_tbl temp_table[] __initdata = {
+ {XE3GF | TSP10 | TSM70 | TSM30X | TSX205, SIMPLE_BYTE(EC, XE3GF_CTMP, 0)},
+ {XE3GC | AMILOD, SIMPLE_BYTE(EC, XE3GC_CTMP, 0)},
+ {OB500 | OB510 | OB6000 | OB6100 | XE4500 | XE2, SIMPLE_BYTE(EC, OB500_CTMP, 0)},
+ {OB4150, SIMPLE_BYTE(EC, OB4150_TMP, 0)},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature temperature_driver = {
+ .name = "temperature",
+ .enabled = 1,
+ .read = omnibook_temperature_read,
+ .ectypes =
+ XE3GF | XE3GC | OB500 | OB510 | OB6000 | OB6100 | XE4500 | OB4150 | XE2 | AMILOD | TSP10
+ | TSM70 | TSM30X | TSX205,
+ .tbl = temp_table,
+};
+
+module_param_named(temperature, temperature_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(temperature, "Use 0 to disable, 1 to enable thermal status and policy support");
+/* End of file */
diff --git a/ubuntu/omnibook/throttling.c b/ubuntu/omnibook/throttling.c
new file mode 100644
index 00000000000..31d7f6ed5d1
--- /dev/null
+++ b/ubuntu/omnibook/throttling.c
@@ -0,0 +1,83 @@
+/*
+ * throttling.c --CPU throttling control feature
+ *
+ * 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 Mathieu Bérard <mathieu.berard@crans.org>, 2007
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+/*
+ * Throttling level/rate mapping found in ICH6M datasheets
+ * the output is set to mimic the one of /proc/acpi/cpu/CPU0/throttling
+ * XXX: We always assume that there are 8 T-States and one processor.
+ */
+static const int trate[8] = { 0, 12, 25, 37, 50, 62, 75, 87 };
+
+static int omnibook_throttle_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int tstate = 0;
+ int retval, i;
+
+ retval = backend_throttle_get(io_op, &tstate);
+ if (retval < 0)
+ return retval;
+
+ len += sprintf(buffer + len, "state count: 8\n");
+ len += sprintf(buffer + len, "active state: T%d\n", tstate);
+ for (i = 0; i < 8; i += 1)
+ {
+ len += sprintf(buffer + len, " %cT%d: %02d%%\n",
+ (i == tstate ? '*' : ' '),
+ i,
+ trate[i]);
+ }
+
+ return len;
+}
+
+static int omnibook_throttle_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ int data;
+ char *endp;
+
+ data = simple_strtoul(buffer, &endp, 10);
+ if ((endp == buffer) || (data > 7)) /* There are 8 throttling levels */
+ return -EINVAL;
+ else
+ retval = backend_throttle_set(io_op, data);
+
+ return retval;
+}
+
+
+static struct omnibook_tbl throttle_table[] __initdata = {
+ {TSM70 | TSX205, {ACPI,}},
+ {0,}
+};
+
+struct omnibook_feature __declared_feature throttle_driver = {
+ .name = "throttling",
+ .enabled = 1,
+ .read = omnibook_throttle_read,
+ .write = omnibook_throttle_write,
+ .ectypes = TSM70 | TSX205,
+ .tbl = throttle_table,
+};
+
+module_param_named(throttle, throttle_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(throttle, "Use 0 to disable, 1 to enable CPU throttling control");
+
+/* End of file */
diff --git a/ubuntu/omnibook/touchpad.c b/ubuntu/omnibook/touchpad.c
new file mode 100644
index 00000000000..b95e2ecb5cc
--- /dev/null
+++ b/ubuntu/omnibook/touchpad.c
@@ -0,0 +1,126 @@
+/*
+ * 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-2004
+ * Modified by Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_touchpad_set(struct omnibook_operation *io_op, int status)
+{
+ int retval = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if ((retval = __omnibook_toggle(io_op, !!status))) {
+ printk(O_ERR "Failed touchpad %sable command.\n", status ? "en" : "dis");
+ goto out;
+ }
+
+ io_op->backend->touchpad_state = !!status;
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Power management handlers: redisable touchpad on resume (if necessary)
+ */
+static int omnibook_touchpad_resume(struct omnibook_operation *io_op)
+{
+ int retval;
+ mutex_lock(&io_op->backend->mutex);
+ retval = __omnibook_toggle(io_op, !!io_op->backend->touchpad_state);
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+/*
+ * Hardware query is unsupported, so reading is unreliable.
+ */
+static int omnibook_touchpad_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ len +=
+ sprintf(buffer + len, "Last touchpad action was an %s command.\n",
+ io_op->backend->touchpad_state ? "enable" : "disable");
+
+ mutex_unlock(&io_op->backend->mutex);
+ return len;
+}
+
+static int omnibook_touchpad_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int cmd;
+
+ if (*buffer == '0' || *buffer == '1') {
+ cmd = *buffer - '0';
+ if (!omnibook_touchpad_set(io_op, cmd)) {
+ dprintk("%sabling touchpad.\n", cmd ? "En" : "Dis");
+ }
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+static int __init omnibook_touchpad_init(struct omnibook_operation *io_op)
+{
+ mutex_lock(&io_op->backend->mutex);
+ /* Touchpad is assumed to be enabled by default */
+ io_op->backend->touchpad_state = 1;
+ mutex_unlock(&io_op->backend->mutex);
+ return 0;
+}
+
+/*
+ * Reenable touchpad upon exit
+ */
+static void __exit omnibook_touchpad_cleanup(struct omnibook_operation *io_op)
+{
+ omnibook_touchpad_set(io_op, 1);
+ printk(O_INFO "Enabling touchpad.\n");
+}
+
+static struct omnibook_tbl touchpad_table[] __initdata = {
+ {XE3GF | XE3GC | TSP10,
+ COMMAND(KBC, OMNIBOOK_KBC_CMD_TOUCHPAD_ENABLE, OMNIBOOK_KBC_CMD_TOUCHPAD_DISABLE)},
+ {TSM70, {CDI, 0, TSM70_FN_INDEX, 0, TSM70_TOUCHPAD_ON, TSM70_TOUCHPAD_OFF}},
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature touchpad_driver = {
+ .name = "touchpad",
+ .enabled = 1,
+ .read = omnibook_touchpad_read,
+ .write = omnibook_touchpad_write,
+ .init = omnibook_touchpad_init,
+ .exit = omnibook_touchpad_cleanup,
+ .resume = omnibook_touchpad_resume,
+ .ectypes = XE3GF | XE3GC | TSP10 | TSM70,
+ .tbl = touchpad_table,
+};
+
+module_param_named(touchpad, touchpad_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(touchpad, "Use 0 to disable, 1 to enable touchpad handling");
+
+/* End of file */
diff --git a/ubuntu/omnibook/wireless.c b/ubuntu/omnibook/wireless.c
new file mode 100644
index 00000000000..71b0c41b37a
--- /dev/null
+++ b/ubuntu/omnibook/wireless.c
@@ -0,0 +1,108 @@
+/*
+ * wireless.c Wifi feature
+ *
+ * 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 Mathieu Bérard <mathieu.berard@crans.org>, 2006
+ *
+ */
+
+#include "omnibook.h"
+#include "hardware.h"
+
+static int omnibook_wifi_read(char *buffer, struct omnibook_operation *io_op)
+{
+ int len = 0;
+ int retval;
+ unsigned int state;
+
+ if ((retval = backend_aerial_get(io_op, &state)))
+ return retval;
+
+ len +=
+ sprintf(buffer + len, "Wifi adapter is %s", (state & WIFI_EX) ? "present" : "absent");
+ if (state & WIFI_EX)
+ len +=
+ sprintf(buffer + len, " and %s", (state & WIFI_STA) ? "enabled" : "disabled");
+ len += sprintf(buffer + len, ".\n");
+ len +=
+ sprintf(buffer + len, "Wifi Kill switch is %s.\n", (state & KILLSWITCH) ? "on" : "off");
+
+ return len;
+
+}
+
+static int omnibook_wifi_write(char *buffer, struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ unsigned int state;
+
+ if(mutex_lock_interruptible(&io_op->backend->mutex))
+ return -ERESTARTSYS;
+
+ if ((retval = __backend_aerial_get(io_op, &state)))
+ goto out;
+
+ if (*buffer == '0')
+ state &= ~WIFI_STA;
+ else if (*buffer == '1')
+ state |= WIFI_STA;
+ else {
+ retval = -EINVAL;
+ goto out;
+ }
+
+ if ((retval = __backend_aerial_set(io_op, state)))
+ return retval;
+
+ out:
+ mutex_unlock(&io_op->backend->mutex);
+ return retval;
+}
+
+static struct omnibook_feature wifi_driver;
+
+static int __init omnibook_wifi_init(struct omnibook_operation *io_op)
+{
+ int retval = 0;
+ unsigned int state;
+
+/*
+ * Refuse enabling/disabling a non-existent device
+ */
+
+ if ((retval = backend_aerial_get(io_op, &state)))
+ return retval;
+
+ if (!(state & WIFI_EX))
+ wifi_driver.write = NULL;
+
+ return retval;
+}
+
+static struct omnibook_tbl wireless_table[] __initdata = {
+ {TSM70 | TSX205, {ACPI,}}, /* stubs to select backend */
+ {TSM40, {SMI,}}, /* stubs to select backend */
+ {0,}
+};
+
+static struct omnibook_feature __declared_feature wifi_driver = {
+ .name = "wifi",
+ .enabled = 1,
+ .read = omnibook_wifi_read,
+ .write = omnibook_wifi_write,
+ .init = omnibook_wifi_init,
+ .ectypes = TSM70 | TSM40 | TSX205,
+ .tbl = wireless_table,
+};
+
+module_param_named(wifi, wifi_driver.enabled, int, S_IRUGO);
+MODULE_PARM_DESC(wifi, "Use 0 to disable, 1 to enable Wifi adapter control");