From 4253d35fd213deb505a1646268495ca0e62f55c5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathieu=20B=C3=A9rard?= Date: Wed, 16 Aug 2006 20:47:45 +0000 Subject: [PATCH] Merge branch (81:HEAD) back to trunk Resolve conflics (why so much hate ?) --- Makefile | 8 +- ac.c | 74 ++-- apmemu.c | 3 +- battery.c | 3 +- blank.c | 46 +-- compal.c | 456 ++++++++++++++++++++++++ debian/docs | 2 +- display.c | 82 ++--- doc/CREDITS | 2 +- doc/ChangeLog | 12 +- doc/README | 17 +- doc/README-2.6 | 20 -- doc/{README-OneTouch => README-Hotkeys} | 39 +- doc/TODO | 17 +- dock.c | 63 ++-- ec.c | 111 +++--- ec.h | 47 ++- fan.c | 73 ++-- fan_policy.c | 17 +- hotkeys.c | 211 +++++++++++ info.c | 1 + init.c | 97 +++-- lcd.c | 135 ++----- omnibook.h | 48 ++- onetouch.c | 182 ---------- sections.lds | 3 +- temperature.c | 6 +- touchpad.c | 13 +- 28 files changed, 1055 insertions(+), 733 deletions(-) create mode 100644 compal.c delete mode 100644 doc/README-2.6 rename doc/{README-OneTouch => README-Hotkeys} (80%) create mode 100644 hotkeys.c delete mode 100644 onetouch.c diff --git a/Makefile b/Makefile index b465dfe..31b0c1e 100644 --- a/Makefile +++ b/Makefile @@ -42,15 +42,17 @@ RM = rm -f FIND = find endif -DEBUG = #-D DEBUG -g -O0 +DEBUG = # -D OMNIBOOK_DEBUG -g -O0 + EXTRA_CFLAGS += -D OMNIBOOK_STANDALONE $(DEBUG) EXTRA_LDFLAGS += $(src)/sections.lds OBJS = ac.o battery.o blank.o display.o dock.o \ - ec.o fan.o fan_policy.o init.o lcd.o onetouch.o \ + ec.o fan.o fan_policy.o init.o lcd.o hotkeys.o \ temperature.o touchpad.o dump.o info.o \ - apmemu.o muteled.o + apmemu.o muteled.o compal.o + # All extra flags delt with automagically diff --git a/ac.c b/ac.c index 6689d82..2307eb1 100644 --- a/ac.c +++ b/ac.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -22,61 +23,25 @@ #include "ec.h" +static const struct omnibook_io_operation ac_io_table[] = { + { XE3GF|TSP10|TSM30X, EC, XE3GF_ADP, 0, XE3GF_ADP_MASK}, + { XE3GC|AMILOD, EC, XE3GC_STA1, 0, XE3GC_ADP_MASK}, + { OB500|OB510|OB6000|OB6100|XE4500, EC, OB500_STA2, 0, OB500_ADP_MASK}, + { OB4150, EC, OB4150_ADP, 0, OB4150_ADP_MASK}, + { XE2, EC, XE2_STA1, 0, XE2_ADP_MASK}, + { 0,} +}; + +static struct omnibook_io_operation *ac_io; + int omnibook_get_ac(void) { u8 ac; int retval; - /* - * XE3GF - * TSP10 - * TSM30X - */ - if (omnibook_ectype & (XE3GF|TSP10|TSM30X) ) { - if ((retval = omnibook_ec_read(XE3GF_ADP, &ac))) - return retval; - retval = (ac & XE3GF_ADP_MASK) ? 1 : 0; - /* - * XE3GC - * AMILOD - */ - } else if (omnibook_ectype & (XE3GC|AMILOD) ) { - if ((retval = omnibook_ec_read(XE3GC_STA1, &ac))) - return retval; - retval = (ac & XE3GC_ADP_MASK) ? 1 : 0; - /* - * OB500 - * OB510 - * 0B6000 - * 0B61000 - * XE4500 - */ - } else if (omnibook_ectype & (OB500|OB510|OB6000|OB6100|XE4500) ) { - if ((retval = omnibook_ec_read(OB500_STA2, &ac))) - return retval; - retval = (ac & OB500_ADP_MASK) ? 1 : 0; - /* - * OB4150 - */ - } else if (omnibook_ectype & OB4150 ) { - if ((retval = omnibook_ec_read(OB4150_ADP, &ac))) - return retval; - retval = (ac & OB4150_ADP_MASK) ? 1 : 0; - /* - * XE2 - */ - } else if (omnibook_ectype & XE2) { - if ((retval = omnibook_ec_read(XE2_STA1, &ac))) - return retval; - retval = (ac & XE2_ADP_MASK) ? 1 : 0; - /* - * UNKNOWN - */ - } else { - printk(KERN_INFO - "%s: AC adapter status monitoring is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); - retval = -ENODEV; - } + + retval = omnibook_io_read( ac_io, &ac); + if (!retval) + retval = ac ? 1 : 0; return retval; } @@ -94,10 +59,17 @@ static int omnibook_ac_read(char *buffer) return len; } +static int omnibook_ac_init(void) +{ + ac_io = omnibook_io_match(ac_io_table); + return ac_io ? 0 : -ENODEV; +} + static struct omnibook_feature __declared_feature ac_feature = { .name = "ac", .enabled = 1, .read = omnibook_ac_read, + .init = omnibook_ac_init, .ectypes = XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|XE2|AMILOD|TSP10|TSM30X, }; diff --git a/apmemu.c b/apmemu.c index c8624e1..192fca5 100644 --- a/apmemu.c +++ b/apmemu.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -140,7 +141,7 @@ static int omnibook_apmemu_init(void) { #ifdef CONFIG_APM if (!apm_info.disabled) { - printk(KERN_INFO "%s: Real APM support is present, emulation is not necessary.\n", OMNIBOOK_MODULE_NAME); + printk(O_INFO "Real APM support is present, emulation is not necessary.\n"); return -ENODEV; } #endif diff --git a/battery.c b/battery.c index 4b2e00e..3c352fb 100644 --- a/battery.c +++ b/battery.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -556,7 +557,7 @@ static struct omnibook_feature __declared_feature battery_feature = { .name = "battery", .enabled = 1, .read = omnibook_battery_read, - .ectypes = XE3GF|XE3GC|AMILOD|TSP10|TSM30X, /* FIXME: OB500|OB6000|OB6100|XE4500 */ + .ectypes = XE3GF|XE3GC|AMILOD|TSP10, /* FIXME: OB500|OB6000|OB6100|XE4500 */ }; diff --git a/blank.c b/blank.c index 86d57e4..b4d31f5 100644 --- a/blank.c +++ b/blank.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -20,6 +21,7 @@ #include #endif +#include #include "ec.h" static int omnibook_console_blank_enabled = 0; @@ -39,8 +41,7 @@ int omnibook_lcd_blank(int blank) * TSM40 */ if (omnibook_ectype & (XE3GF|XE3GC|AMILOD|TSP10|TSM30X|TSM40) ) { - cmd = - blank ? OMNIBOOK_KBC_CMD_LCD_OFF : OMNIBOOK_KBC_CMD_LCD_ON; + cmd = blank ? OMNIBOOK_KBC_CMD_LCD_OFF : OMNIBOOK_KBC_CMD_LCD_ON; if ((retval = omnibook_kbc_command(OMNIBOOK_KBC_CONTROL_CMD, cmd))) return retval; @@ -50,28 +51,23 @@ int omnibook_lcd_blank(int blank) * XE2 */ } else if (omnibook_ectype & (OB500|OB6000|XE2) ) { - if ((retval = omnibook_io_read(OB500_GPO1, &cmd))) - return retval; + cmd = inb(OB500_GPO1); cmd = blank ? cmd & ~OB500_BKLT_MASK : cmd | OB500_BKLT_MASK; - if ((retval = omnibook_io_write(OB500_GPO1, cmd))) - return retval; + outb(cmd, OB500_GPO1); /* * OB510 - * 0B61000 + * OB61000 */ } else if (omnibook_ectype & (OB510|OB6100) ) { - if ((retval = omnibook_io_read(OB510_GPO2, &cmd))) - return retval; + cmd = inb(OB510_GPO2); cmd = blank ? cmd & ~OB510_BKLT_MASK : cmd | OB510_BKLT_MASK; - if ((retval = omnibook_io_write(OB510_GPO2, cmd))) - return retval; + outb(cmd, OB510_GPO2); /* * UNKNOWN */ } else { - printk(KERN_INFO - "%s: LCD console blanking is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO + "LCD console blanking is unsupported on this machine.\n"); retval = -ENODEV; } return retval; @@ -82,14 +78,13 @@ static int omnibook_console_blank_enable(void) if (omnibook_console_blank_enabled == 0) { if (console_blank_hook == NULL) { console_blank_hook = omnibook_lcd_blank; - printk(KERN_INFO - "%s: LCD backlight turn off at console blanking is enabled.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO + "LCD backlight turn off at console blanking is enabled.\n"); + omnibook_console_blank_enabled = 1; } else { - printk(KERN_INFO - "%s: There is a console blanking solution already registered.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO + "There is a console blanking solution already registered.\n"); } } return 0; @@ -99,18 +94,13 @@ static int omnibook_console_blank_disable(void) { if (console_blank_hook == omnibook_lcd_blank) { console_blank_hook = NULL; - printk(KERN_INFO - "%s: LCD backlight turn off at console blanking is disabled.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "LCD backlight turn off at console blanking is disabled.\n"); omnibook_console_blank_enabled = 0; } else if (console_blank_hook) { - printk(KERN_WARNING - "%s: You can not disable another console blanking solution.\n", - OMNIBOOK_MODULE_NAME); + printk(O_WARN "You can not disable another console blanking solution.\n"); return -EBUSY; } else { - printk(KERN_INFO "%s: Console blanking already disabled.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Console blanking already disabled.\n"); return 0; } return 0; diff --git a/compal.c b/compal.c new file mode 100644 index 0000000..8b6df94 --- /dev/null +++ b/compal.c @@ -0,0 +1,456 @@ +/* + * 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 , 2006 + * + */ + +#ifdef OMNIBOOK_STANDALONE +#include "omnibook.h" +#else +#include +#endif + +#include +#include +#include + +#include +#include +#include "ec.h" + +/* + * PCI Config space regiser + * Laptop with Intel ICH Chipset + * Called GEN1_DEC according to ICH6M spec + */ +#define INTEL_LPC_GEN1_DEC 0x84 +#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 + +/* + * We protect access to the Command/Data/Index interface by a Mutex + */ +static DECLARE_MUTEX(compal_sem); + + +/* + * Private data of this backend + */ +static struct kref *refcount; /* Reference counter 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. + */ +static 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_31, 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(unsigned int 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(unsigned int command, unsigned int 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 <= 100; 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; + } else + udelay(100); + } + printk(O_ERR "check_cdimode_flag 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: + 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( (inb(ioport_base + PIO_PORT_COMMAND1)!= 0xf4) || + (inb(ioport_base + PIO_PORT_COMMAND2)!= 0x32) || + 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: + 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. + */ +int omnibook_cdimode_init(void) +{ + int retval = 0; + int i; + +/* ectypes other than TSM30X have no business with this backend */ + if(!(omnibook_ectype & TSM30X)) + return -ENODEV; + + if(!refcount) { + /* Fist use of the backend */ + down(&compal_sem); + dprintk("Try to init cdimode\n"); + refcount = kmalloc(sizeof(struct kref),GFP_KERNEL); + if(!refcount) { + retval= -ENOMEM; + goto out; + } + + kref_init(refcount); + + /* 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")) { + 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"); + goto out; + } else { + dprintk("Cdimode has already been initialized\n"); + kref_get(refcount); + return 0; + } + +error3: + clear_cdimode_pci(); +error2: + pci_dev_put(lpc_bridge); + lpc_bridge = NULL; +error1: + kfree(refcount); +out: + up(&compal_sem); + return retval; +} + +void cdimode_free(struct kref *ref) +{ + dprintk("Cdimode not used anymore: disposing\n"); + pci_dev_put(lpc_bridge); + release_region(ioport_base,4); + kfree(refcount); +} + +void omnibook_cdimode_exit(void) +{ +/* ectypes other than TSM30X have no business with this backend */ + BUG_ON(!(omnibook_ectype & TSM30X)); + dprintk("Trying to dispose cdimode\n"); + kref_put(refcount,cdimode_free); +} + +/* + * Read EC index and write result to value + * 'EC index' here is unrelated to an index in the EC registers + */ +int omnibook_cdimode_read(unsigned int index, u8 *value) +{ + int retval = 0; + + BUG_ON(!(omnibook_ectype & TSM30X)); + + if(!lpc_bridge) + return -ENODEV; + + if(down_interruptible(&compal_sem)) + return -ERESTARTSYS; + + retval = enable_cdimode(); + if(retval) + goto out; + retval = send_ec_cmd(0xfbfd,index); + if(retval) + goto error; + retval = read_ec_cmd(0xfbfe,value); + +error: + clear_cdimode(); +out: + clear_cdimode_pci(); + up(&compal_sem); + return retval; +} + +/* + * Write value + * 'EC index' here is unrelated to an index in the EC registers + */ +int omnibook_cdimode_write(unsigned int index, u8 value) +{ + int retval = 0; + + BUG_ON(!(omnibook_ectype & TSM30X)); + + if(!lpc_bridge) + return -ENODEV; + + if(down_interruptible(&compal_sem)) + return -ERESTARTSYS; + + retval = enable_cdimode(); + if(retval) + goto out; + retval = send_ec_cmd(0xfbfd,index); + if(retval) + goto error; + retval = send_ec_cmd(0xfbfe,value); + +error: + clear_cdimode(); +out: + clear_cdimode_pci(); + up(&compal_sem); + 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 + +/* End of file */ diff --git a/debian/docs b/debian/docs index 7682c66..3c91ad9 100644 --- a/debian/docs +++ b/debian/docs @@ -2,6 +2,6 @@ doc/BUGS doc/CREDITS doc/README-1st doc/README -doc/README-OneTouch +doc/README-Hotkeys doc/TODO misc/hotkeys diff --git a/display.c b/display.c index 725afc2..99281c7 100644 --- a/display.c +++ b/display.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -22,78 +23,43 @@ #include "ec.h" -static int omnibook_get_display(void) -{ - int retval = 0; - u8 sta; - - /* - * XE3GF - * TSP10 - * TSM30X - * TSM40 - */ - if (omnibook_ectype & (XE3GF|TSP10|TSM30X|TSM40) ) { - if ((retval = omnibook_ec_read(XE3GF_STA1, &sta))) - return retval; - retval = (sta & XE3GF_SHDD_MASK) ? 1 : 0; - /* - * XE3GC - */ - } else if (omnibook_ectype & XE3GC ) { - if ((retval = omnibook_ec_read(XE3GC_STA1, &sta))) - return retval; - retval = (sta & XE3GC_CRTI_MASK) ? 1 : 0; - /* - * OB500 - * OB510 - * OB6000 - * OB6100 - * XE4500 - */ - } else if (omnibook_ectype & (OB500|OB510|OB6000|OB6100|XE4500) ) { - if ((retval = omnibook_ec_read(OB500_STA1, &sta))) - return retval; - retval = (sta & OB500_CRTS_MASK) ? 1 : 0; - /* - * OB4150 - */ - } else if (omnibook_ectype & OB4150 ) { - if ((retval = omnibook_ec_read(OB4150_STA2, &sta))) - return retval; - retval = (sta & OB4150_CRST_MASK) ? 1 : 0; - /* - * UNKNOWN - */ - } else { - printk(KERN_INFO - "%s: External display status monitoring is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); - retval = -ENODEV; - } - return retval; -} +static const struct omnibook_io_operation display_io_table[] = { + { XE3GF|TSP10|TSM30X|TSM40, EC, XE3GF_STA1, 0, XE3GF_SHDD_MASK}, + { XE3GC, EC, XE3GC_STA1, 0, XE3GC_CRTI_MASK}, + { OB500|OB510|OB6000|OB6100|XE4500, EC, OB500_STA1, 0, OB500_CRTS_MASK}, + { OB4150, EC, OB4150_STA2, 0, OB4150_CRST_MASK}, + { 0,} +}; + +static struct omnibook_io_operation *display_io; static int omnibook_display_read(char *buffer) { int len = 0; - int display; - - display = omnibook_get_display(); - if (display < 0) - return display; - + int retval; + u8 sta; + + if ((retval = omnibook_io_read(display_io, &sta))) + return retval; len += sprintf(buffer + len, "External display is %s\n", - (display) ? "present" : "not present"); + (sta) ? "present" : "not present"); return len; } +static int omnibook_display_init(void) +{ + display_io = omnibook_io_match(display_io_table); + return display_io ? 0 : -ENODEV; +} + + static struct omnibook_feature __declared_feature display_feature = { .name = "display", .enabled = 1, .read = omnibook_display_read, + .init = omnibook_display_init, .ectypes = XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|OB4150|TSP10|TSM30X|TSM40, }; diff --git a/doc/CREDITS b/doc/CREDITS index 6ebe8ad..c525a4b 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -1,4 +1,4 @@ -The module is written by +The module was originally written by * Soós Péter diff --git a/doc/ChangeLog b/doc/ChangeLog index df44390..abdf626 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -2,11 +2,21 @@ Changelog file for omnibook package: ------------------------------------ 2.XXXXXXXX Mathieu Bérard +* 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. * Add dmi info for Toshiba Satellite M100 (Thanks Sertaç Ö. Yıldız) And fix it * Add dmi info for Toshiba Satellite A105 (Thanks Mikkel L. Ellertson) the support is pretty minimalistic (LCD brigtness only) this - also inaugurate ectype 14 + also ingurate ectype 14 * Cleanup/Fix in Makefile Include explicit depmod in the 'load' target * Improvements in the Debian packages by Julien Valroff diff --git a/doc/README b/doc/README index c5c8939..265ebbf 100644 --- a/doc/README +++ b/doc/README @@ -97,8 +97,8 @@ How does it work? What is working? ---------------- - 1. Enabling OneTouch buttons. See README-OneTouch for details. - You may enable or disable it via /proc/omnibook/onetouch. + 1. Enabling hotkey buttons. See README-Hotkeys for details. + You may enable or disable it via /proc/omnibook/hotkeys. There is a power management handler for reenabling the buttons at resume if they were enabled previously. @@ -116,10 +116,9 @@ What is working? There is a power management handler for redisabling the touchpad at resume if it was disabled previously. - 6. Emulate /proc/apm battery status monitoring. On my HP OmniBook XE3 GF the + 6. Emulate /proc/apm battery status monitoring. On the HP OmniBook XE3 GF the APM subsystem unable to monitor the battery but there are many status - monitoring application using /proc/apm to get info. So I disable APM and - use this module and I'm happy :). + monitoring application using /proc/apm to get info. Note: this is working only if you have AC adapter and battery status monitoring enabled (see ac and battery module parameters). @@ -133,16 +132,16 @@ What is working? How to use? ----------- - 1. The OneTouch buttons are enabled by default by this module. + 1. The hotkeys are enabled by default by this module. To disable it use the command: - echo 0 > /proc/omnibook/onetouch + echo 0 > /proc/omnibook/hotkeys The command - echo 1 > /proc/omnibook/onetouch + echo 1 > /proc/omnibook/hotkeys - enables OneTouch buttons. + enables hotkeys buttons. 2. Console (LCD display) blanking is enabled by this module on machines that support it. It only enabled if another blanking solution diff --git a/doc/README-2.6 b/doc/README-2.6 deleted file mode 100644 index fa4051f..0000000 --- a/doc/README-2.6 +++ /dev/null @@ -1,20 +0,0 @@ -Additional notes using omnibook module on kernel 2.6 ----------------------------------------------------- - -1. General support ------------------- - -Finally a working kernel 2.6 support solution was added to Makefile -(thanks to Mark Chappell ). It permit to build, -install and load the omnibook module. Now the module unload is working -for 2.6 series kernels (thanks to math_b@users.sourceforge.net). - -2. OneTouch buttons -------------------- - -OneTouch buttons are enabled on most models by kernel series 2.5/2.6 -at startup without this module, and someone asked me: Why have you need it -yet? Sometimes it is useful to disable them e.g. if you travel with your -laptop on train or plane, and want to prevent accidental pressing buttons -on front/side of your laptop. - diff --git a/doc/README-OneTouch b/doc/README-Hotkeys similarity index 80% rename from doc/README-OneTouch rename to doc/README-Hotkeys index a4d4313..387515a 100644 --- a/doc/README-OneTouch +++ b/doc/README-Hotkeys @@ -1,16 +1,12 @@ -Kernel Support for OneTouch buttons of HP OmniBooks -=================================================== +Kernel Support for Special hotkey buttons +========================================= -Some HP OmniBook (and other) laptops have special multimedia keys -(aka OneTouch buttons). These or some of them are disabled by default -and need to be enabled. +Some laptops have special multimedia keys, their branding name varies +on laptop manufacturer (OneTouch for HP omnibook, one can also encounter the +names E-Keys, EasyAcess, you name it). +They may be disabled by default and need to be enabled. -Note: these buttons may be enabled by kernel series 2.5/2.6 at startup without - this module, but sometimes it is useful to disable them e.g. if you - travel with your laptop, and want to prevent accidental pressing - buttons on front/side of your laptop. - -This module try to detect your HP OmniBook and enable OneTouch buttons +This module try to detect your laptop model and enable those hotkey buttons to generate scancodes. Look in syslog messages for "keyboard: unknown scancode e0 xx" messages to identify the scancode assigned to button. Use setkeycodes from console-tools @@ -162,8 +158,8 @@ Bluetooth e058 Wifi e056 -Toshiba Satellite M70 ---------------------- +Toshiba Satellite M70 or M40X +----------------------------- Lock (Fn + F1) e06e Light Bubble (Fn + F2) e062 @@ -174,8 +170,8 @@ Brightness Down (Fn + F6) e06f Brightness Up (Fn + F7) e059 Toggle Wifi (Fn + F8) e016 Touchpad On/Off (Fn + F9) e01e/e01f -Zoom - (Fn + 1) e01a -Zoom + (Fn + 2) e01b +Zoom - (Fn + 1) e01a +Zoom + (Fn + 2) e01b Zoom (Fn + Space) e043 Internet e013 Media Player e014 @@ -186,18 +182,15 @@ Prev e074 Wifi Kill Switch e015 -There are programs specifically designed for such application keys (e.g. -hotkeys: http://ypwong.org/hotkeys/) or kernel level support for such -keys at http://rick.vanrein.org/linux/funkey/. +There are programs specifically designed for such application keys as +gnome-keybinding-properties for Gnome Desktop. -XE3L machines are same as XE3 models but they have application launcher -buttons only but do not have multimedia (CD and volume control) buttons. +HP omnibook XE3L machines are same as XE3 models but they have application +launcher buttons only but do not have multimedia (CD and volume control) buttons. The extra buttons near the touchpad are not OneTouch buttons. You need driver for touchpad to use them. If you have Synaptics touchpad you may -try the driver can be found at http://www.mobilix.org/touchpad_driver.html. -Newer version can be found at -http://w1.894.telia.com/~u89404340/touchpad/index.html +try the driver can be found at http://web.telia.com/~u89404340/touchpad/ The ("Big Blue") Sleep button also not a OneTouch button, it usually handled by APM or ACPI stuff depending on your BIOS implementation. diff --git a/doc/TODO b/doc/TODO index 1c74f46..6759b9f 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,11 +1,22 @@ TODO ==== +* See if/how key polling can be ported to 2.6 +* LED API support +* Clarify the TSM40 situation +* Create a clean access method to the i8042 kbd controller (this will require + a kernel patch) +* We use I/O ports without a request_region ( ec.c blank.c fan.c) +* To be cleaned: blank fan +* To much global variables sometimes + +Items imported from previous version: + * Fix LCD brighness handling on XE3GF style machines * Fully support OB5xx, OB6xxx and XE4500 style machines * Battery support for OB5xx, OB6xxx and XE4500 style machines + +Will probably always remain here: + * Adding more features of embedded controller * Support more machines -* See if/how key polling can be ported to 2.6 -* LED API support -* Implement IndexMode access to EC for TSM70 diff --git a/dock.c b/dock.c index 3412b0e..1301e54 100644 --- a/dock.c +++ b/dock.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -22,53 +23,24 @@ #include "ec.h" -static int omnibook_get_dock(void) -{ - u8 dock; - int retval; - /* - * XE3GF - */ - if (omnibook_ectype & (XE3GF) ) { - if ((retval = omnibook_ec_read(XE3GF_CSPR, &dock))) - return retval; - retval = (dock & XE3GF_CSPR_MASK) ? 1 : 0; - /* - * OB500 - * OB510 - * OB6000 - * OB6100 - */ - } else if (omnibook_ectype & (OB500|OB510|OB6000|OB6100) ) { - if ((retval = omnibook_ec_read(OB500_STA1, &dock))) - return retval; - retval = (dock & OB500_DCKS_MASK) ? 1 : 0; - /* - * OB4150 - */ - } else if (omnibook_ectype & (OB4150) ) { - if ((retval = omnibook_ec_read(OB4150_DCID, &dock))) - return retval; - retval = (dock) ? 1 : 0; - } else { - printk(KERN_INFO - "%s: Docking station handling is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); - retval = -ENODEV; - } +static const struct omnibook_io_operation dock_io_table[] = { + { XE3GF, EC, XE3GF_CSPR, 0, XE3GF_CSPR_MASK}, + { OB500|OB510|OB6000|OB6100, EC, OB500_STA1, 0, OB500_DCKS_MASK}, + { OB4150, EC, OB4150_DCID, 0, 0}, + { 0,} +}; - return retval; -} +static struct omnibook_io_operation *dock_io; static int omnibook_dock_read(char *buffer) { int len = 0; - int dock; - - dock = omnibook_get_dock(); - if (dock < 0) - return dock; - + u8 dock; + int retval; + + if ((retval = omnibook_io_read(dock_io, &dock))) + return retval; + len += sprintf(buffer + len, "Laptop is %s\n", (dock) ? "docked" : "undocked"); @@ -76,10 +48,17 @@ static int omnibook_dock_read(char *buffer) return len; } +static int omnibook_dock_init(void) +{ + dock_io = omnibook_io_match(dock_io_table); + return dock_io ? 0 : -ENODEV; +} + static struct omnibook_feature __declared_feature dock_feature = { .name = "dock", .enabled = 0, .read = omnibook_dock_read, + .init = omnibook_dock_init, .ectypes = XE3GF|OB500|OB510|OB6000|OB6100|OB4150, }; diff --git a/ec.c b/ec.c index e3f97e3..bd206b3 100644 --- a/ec.c +++ b/ec.c @@ -13,7 +13,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 - * Written by Mathieu Bérard , 2006 + * Modified by Mathieu Bérard , 2006 */ #include @@ -27,15 +27,6 @@ #include #include "ec.h" -/* - * For (dumb) compatibility with kernel older than 2.6.9 - */ - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) -#define ioread8(addr) readb(addr) -#define iowrite8(val,addr) writeb(val,addr) -#endif - /* * For compatibility with kernel older than 2.6.11 */ @@ -44,6 +35,7 @@ #define DEFINE_SPINLOCK(s) spinlock_t s = SPIN_LOCK_UNLOCKED #endif +extern int omnibook_ectype; /* * Interrupt control @@ -121,14 +113,9 @@ int omnibook_ec_read(u8 addr, u8 *data) int retval; #ifdef CONFIG_ACPI_EC - if (!acpi_disabled) - { - retval = ec_read(addr, data); - if (!retval) - return retval; - } + if (likely(!acpi_disabled)) + return ec_read(addr, data); #endif - spin_lock_irqsave(&omnibook_ec_lock, flags); retval = omnibook_ec_wait(OMNIBOOK_EC_STAT_IBF); if (retval) @@ -161,12 +148,8 @@ int omnibook_ec_write(u8 addr, u8 data) int retval; #ifdef CONFIG_ACPI_EC - if (!acpi_disabled) - { - retval = ec_write(addr, data); - if (!retval) - return retval; - } + if (likely(!acpi_disabled)) + return ec_write(addr, data); #endif spin_lock_irqsave(&omnibook_ec_lock, flags); @@ -283,59 +266,71 @@ int omnibook_kbc_command(u8 cmd, u8 data) } /* - * Read a value from a system I/O address + * Common pattern selector: + * Match an ectype and return pointer to corresponding io_operation. + * Also make corresponding backend initialisation if necessary */ - -int inline omnibook_io_read(u32 addr, u8 * data) -{ - *data = inb(addr); - return 0; -} - -/* - * Write a value to a system I/O address - */ - -int inline omnibook_io_write(u32 addr, u8 data) +void *omnibook_io_match(const struct omnibook_io_operation *io_op) { - outb(data, addr); - return 0; + int i; + void *matched = NULL; + for (i = 0; io_op[i].ectypes ; i++) { + if (omnibook_ectype & io_op[i].ectypes) + if (io_op[i].type == CDI && omnibook_cdimode_init()) + continue; + matched = (void *) &io_op[i]; + break; + } + return matched; } /* - * Read a value from a system memory address + * Simple read function for common pattern + * Given an io_operation they read an address and apply a mask on the result */ -int omnibook_mem_read(u32 addr, u8 * data) +int omnibook_io_read(struct omnibook_io_operation *io_op, u8 *value) { - unsigned long flags; - char *base; + int retval = 0; - spin_lock_irqsave(&omnibook_ec_lock, flags); - base = ioremap(addr, 1); - *data = ioread8(base); - iounmap(base); - spin_unlock_irqrestore(&omnibook_ec_lock, flags); + switch(io_op->type) { + case EC: + retval = omnibook_ec_read( io_op->read, value); + break; + case CDI: + retval = omnibook_cdimode_read( io_op->read, value); + break; + default: + BUG(); + } + + if (io_op->mask) + *value = *value & io_op->mask; - return 0; + return retval; } /* - * Write a value to a system memory address + * Simple write function for common pattern + * Given an io_operation they write value at an given address */ -int omnibook_mem_write(u32 addr, u8 data) +int omnibook_io_write(struct omnibook_io_operation *io_op, u8 value) { - unsigned long flags; - char *base; + int retval = 0; - spin_lock_irqsave(&omnibook_ec_lock, flags); - base = ioremap(addr, 1); - iowrite8(data, base); - iounmap(base); - spin_unlock_irqrestore(&omnibook_ec_lock, flags); + switch(io_op->type) { + case EC: + retval = omnibook_ec_write( io_op->write, value); + break; + case CDI: + retval = omnibook_cdimode_write( io_op->write, value); + break; + default: + BUG(); + } - return 0; + return retval; } /* End of file */ diff --git a/ec.h b/ec.h index 1a4726d..cd22be5 100644 --- a/ec.h +++ b/ec.h @@ -13,18 +13,39 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 - * Written by Mathieu Bérard , 2006 + * Modified by Mathieu Bérard , 2006 */ extern int omnibook_ec_read(u8 addr, u8 *data); extern int omnibook_ec_write(u8 addr, u8 data); extern int omnibook_kbc_command(u8 cmd, u8 data); -extern int omnibook_io_read(u32 addr, u8 * data); -extern int omnibook_io_write(u32 addr, u8 data); -extern int omnibook_mem_read(u32 addr, u8 * data); -extern int omnibook_mem_write(u32 addr, u8 data); + +struct omnibook_io_operation; + +extern int omnibook_io_read(struct omnibook_io_operation *io_op, u8 *value); +extern int omnibook_io_write(struct omnibook_io_operation *io_op, u8 value); +void *omnibook_io_match(const struct omnibook_io_operation *io_op); + +extern int omnibook_cdimode_read(unsigned int index, u8 *value); +extern int omnibook_cdimode_write(unsigned int index, u8 value); +extern void omnibook_cdimode_exit(void); +extern int omnibook_cdimode_init(void); +/* + * Storage of generic (EC,PIO,...) addresses, read masks, and corresponding ectypes + * This is for use with the omnibook_io_{read/write} and omnibook_io_match + * helper functions + */ + +struct omnibook_io_operation { + int ectypes; /* ectype */ + enum { BAD, EC, PIO, MMIO, CDI} type; /* address space */ + u8 read; /* read address */ + u8 write; /* write address */ + u8 mask; /* read mask */ +}; + /* * Embedded controller adresses */ @@ -314,4 +335,18 @@ extern int omnibook_mem_write(u32 addr, u8 data); #define XE3GC_BCMD 0xFFFFEBC -/* End of file */ +/* + * 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 + */ + +#define TSM70_FN_INDEX 0x45 +#define TSM70_FN_ENABLE 0x75 +#define TSM70_LCD_READ 0x5C +#define TSM70_LCD_WRITE 0x5D diff --git a/fan.c b/fan.c index 340f4f4..31c35d3 100644 --- a/fan.c +++ b/fan.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -21,6 +22,7 @@ #endif #include +#include #include "ec.h" static int omnibook_get_fan(void) @@ -40,15 +42,13 @@ static int omnibook_get_fan(void) * OB500 */ } else if (omnibook_ectype & (OB500) ) { - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; + fan = inb(OB500_GPO1); retval = (fan & OB500_FAN_OFF_MASK) ? 0 : 1; /* * OB510 */ } else if (omnibook_ectype & (OB510) ) { - if ((retval = omnibook_io_read(OB510_GPIO, &fan))) - return retval; + fan = inb(OB510_GPIO); retval = (fan & OB510_FAN_OFF_MASK) ? 0 : 1; /* * OB6000 @@ -70,13 +70,10 @@ static int omnibook_get_fan(void) * XE2 */ } else if (omnibook_ectype & (XE2) ) { - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; + fan = inb(OB500_GPO1); retval = (fan & XE2_FAN_MASK) ? 0 : 1; } else { - printk(KERN_INFO - "%s: Fan status monitoring is unsupported on this machie.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Fan status monitoring is unsupported on this machie.\n"); retval = -ENODEV; } @@ -86,7 +83,7 @@ static int omnibook_get_fan(void) static int omnibook_fan_on(void) { u8 fan; - int retval; + int retval = 0; /* * XE3GF @@ -101,22 +98,15 @@ static int omnibook_fan_on(void) * OB500 */ } else if (omnibook_ectype & (OB500) ) { - - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB500_GPO1, fan & ~OB500_FAN_ON_MASK))) - return retval; + fan = inb(OB500_GPO1); + outb(fan & ~OB500_FAN_ON_MASK, OB500_GPO1); + /* * OB510 */ } else if (omnibook_ectype & (OB510) ) { - - if ((retval = omnibook_io_read(OB510_GPIO, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB510_GPIO, fan & ~OB510_FAN_ON_MASK))) - return retval; + fan = inb(OB510_GPIO); + outb(fan & ~OB510_FAN_ON_MASK, OB510_GPIO); /* * OB6000 * OB6100 @@ -140,16 +130,10 @@ static int omnibook_fan_on(void) * XE2 */ } else if (omnibook_ectype & (XE2) ) { - - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB500_GPO1, fan & ~XE2_FAN_MASK))) - return retval; + fan = inb(OB500_GPO1); + outb(fan & ~XE2_FAN_MASK, OB500_GPO1); } else { - printk(KERN_INFO - "%s: Direct fan control is unsupported on this machie.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Direct fan control is unsupported on this machie.\n"); retval = -ENODEV; } @@ -159,7 +143,7 @@ static int omnibook_fan_on(void) static int omnibook_fan_off(void) { u8 fan; - int retval; + int retval = 0; /* * XE3GF @@ -190,20 +174,14 @@ static int omnibook_fan_off(void) * OB500 */ } else if (omnibook_ectype & (OB500) ) { - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB500_GPO1, fan | OB500_FAN_OFF_MASK))) - return retval; + fan = inb(OB500_GPO1); + outb(fan | OB500_FAN_OFF_MASK, OB500_GPO1); /* * OB510 */ } else if (omnibook_ectype & (OB510) ) { - if ((retval = omnibook_io_read(OB510_GPIO, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB510_GPIO, fan | OB510_FAN_OFF_MASK))) - return retval; + fan = inb(OB510_GPIO); + outb(fan | OB510_FAN_OFF_MASK, OB510_GPIO); /* * OB6000 * OB6100 @@ -226,15 +204,10 @@ static int omnibook_fan_off(void) * XE2 */ } else if (omnibook_ectype & (XE2) ) { - if ((retval = omnibook_io_read(OB500_GPO1, &fan))) - return retval; - if ((retval = - omnibook_io_write(OB500_GPO1, fan | XE2_FAN_MASK))) - return retval; + fan = inb(OB500_GPO1); + outb(fan | XE2_FAN_MASK, OB500_GPO1); } else { - printk(KERN_INFO - "%s: Direct fan control is unsupported on this machie.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Direct fan control is unsupported on this machie.\n"); retval = -ENODEV; } diff --git a/fan_policy.c b/fan_policy.c index db740cc..e7aeca6 100644 --- a/fan_policy.c +++ b/fan_policy.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -60,9 +61,7 @@ static int omnibook_get_fan_policy(void) omnibook_fan_policy[i] = tmp; } } else { - printk(KERN_INFO - "%s: Fan policy is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Fan policy is unsupported on this machine.\n"); retval = -ENODEV; } @@ -95,9 +94,7 @@ static int omnibook_set_fan_policy(void) return retval; } } else { - printk(KERN_INFO - "%s: Fan policy is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Fan policy is unsupported on this machine.\n"); retval = -ENODEV; } @@ -128,9 +125,7 @@ static int omnibook_set_fan_policy_defaults(void) return retval; } } else { - printk(KERN_INFO - "%s: Fan policy is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Fan policy is unsupported on this machine.\n"); retval = -ENODEV; } @@ -187,9 +182,7 @@ static int omnibook_fan_policy_write(char *buffer) b = buffer; do { - - pr_debug("n=[%i] b=[%s]\n", n, b); - + dprintk("n=[%i] b=[%s]\n", n, b); if (n > OMNIBOOK_FAN_LEVELS) return -EINVAL; if (!isspace(*b)) { diff --git a/hotkeys.c b/hotkeys.c new file mode 100644 index 0000000..d6da6bc --- /dev/null +++ b/hotkeys.c @@ -0,0 +1,211 @@ +/* + * 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 , 2002-2004 + * Modified by Mathieu Bérard , 2006 + */ + +#ifdef OMNIBOOK_STANDALONE +#include "omnibook.h" +#else +#include +#endif + +#include "ec.h" + +/* + * There is no information about reading Hotkeys status + */ +static int omnibook_hotkeys_enabled = 0; + +/* + * Some laptop model have require more work to enable an Fn+button hotkeys + */ +static int omnibook_fnkeys_enabled = 0; + +/* + * Enable hotkeys sending command to the i8042 + */ +static int omnibook_hotkeys_on(void) +{ + int retval; + + if ((retval =omnibook_kbc_command + (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE))) { + printk(O_ERR "Hotkeys enable command failed.\n"); + return retval; + } + omnibook_hotkeys_enabled = 1; + printk(O_INFO "Enabling Hotkey buttons.\n"); + return 0; +} + +/* + * Disable hotkeys sending command to the i8042 + */ +static int omnibook_hotkeys_off(void) +{ + int retval; + + if ((retval = omnibook_kbc_command + (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE))) { + printk(O_ERR "Hotkeys disable command failed.\n"); + return retval; + } + omnibook_hotkeys_enabled = 0; + printk(O_INFO "Disabling Hotkey buttons.\n"); + return 0; +} + +/* + * Enable Fn+foo key writing 75h to EC index 45h + */ +static int omnibook_fnkeys_on(void) +{ + int retval; + + if ((retval = omnibook_cdimode_write(TSM70_FN_INDEX, TSM70_FN_ENABLE))) { + printk(O_ERR "fnkeys enable command failed.\n"); + return retval; + } + omnibook_fnkeys_enabled = 1; + printk(O_INFO "Enabling Fn keys.\n"); + return 0; +} + +/* + * FIXME Not implemented + */ +static int omnibook_fnkeys_off(void) +{ + printk(O_WARN "Disabling of Fn keys not implemented.\n"); + return 0; +} + +/* + * Power management handlers + */ + +/* + * omnibook_*keys_enabled = 1 means here "It was enabled prior to suspend, + * please reenable" + */ +static int omnibook_hotkeys_resume(void) +{ + int retval = 0; + retval = (omnibook_hotkeys_enabled ? omnibook_hotkeys_on() : 0); + if (omnibook_ectype & TSM30X) + retval = (omnibook_fnkeys_enabled ? omnibook_fnkeys_on() : 0); + return retval; +} + +static int omnibook_hotkeys_suspend(void) +{ + int retval = 0; + retval = (omnibook_hotkeys_enabled ? omnibook_hotkeys_off() : 0); + if (omnibook_ectype & TSM30X) + retval = (omnibook_fnkeys_enabled ? omnibook_fnkeys_off() : 0); + return retval; +} + +static int omnibook_hotkeys_enable(void) +{ + int retval = 0; + + if (!omnibook_hotkeys_enabled ) + retval = omnibook_hotkeys_on(); + if ((!omnibook_fnkeys_enabled) && ( omnibook_ectype & TSM30X )) + retval = omnibook_fnkeys_on(); + + return retval; +} + +static int omnibook_hotkeys_disable(void) +{ + int retval = 0; + + if (omnibook_hotkeys_enabled ) + retval = omnibook_hotkeys_off(); + if (omnibook_fnkeys_enabled && ( omnibook_ectype & TSM30X )) + retval = omnibook_fnkeys_off(); + + return retval; +} + +static int omnibook_hotkeys_read(char *buffer) +{ + int len = 0; + + len += sprintf(buffer + len, "Hotkey buttons are %s\n", + (omnibook_hotkeys_enabled) ? "enabled" : "disabled"); + + if (omnibook_ectype & TSM30X ) + len += sprintf(buffer + len, "Fn keys are %s\n", + (omnibook_fnkeys_enabled) ? "enabled" : "disabled"); + return len; +} + +static int omnibook_hotkeys_write(char *buffer) +{ + int retval = 0; + switch (*buffer) { + case '0': + retval = omnibook_hotkeys_disable(); + break; + case '1': + retval = omnibook_hotkeys_enable(); + break; + default: + retval = -EINVAL; + } + return retval; +} + +static int omnibook_hotkeys_init(void) +{ + int retval = 0; + + if ((omnibook_ectype & TSM30X) && omnibook_cdimode_init()) { + retval = -ENODEV; + goto out; + } + + retval = omnibook_hotkeys_enable(); + +out: + return retval; +} + +static void omnibook_hotkeys_cleanup(void) +{ + omnibook_hotkeys_disable(); + + if (omnibook_ectype & TSM30X) + omnibook_cdimode_exit(); +} + +static struct omnibook_feature __declared_feature hotkeys_feature = { + .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|TSM30X, +}; + +module_param_named(hotkeys, hotkeys_feature.enabled, int, S_IRUGO); +MODULE_PARM_DESC(hotkeys, "Use 0 to disable, 1 to enable hotkeys handling"); +/* End of file */ diff --git a/info.c b/info.c index 642319e..4049d88 100644 --- a/info.c +++ b/info.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE diff --git a/init.c b/init.c index 4f65f52..9ff2303 100644 --- a/init.c +++ b/init.c @@ -12,7 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 - * Written by Mathieu Bérard , 2006 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -87,7 +87,6 @@ static struct platform_device omnibook_device = { /* 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 _features_start[]; extern struct omnibook_feature _features_end[]; @@ -182,39 +181,35 @@ static int __init omnibook_init(struct omnibook_feature *feature) if (retval) return -ENODEV; } - if (feature->name) { - if (feature->read) { - pmode = S_IFREG | S_IRUGO; - if (feature->write) { - pmode |= S_IWUSR; - if (omnibook_userset) - pmode |= S_IWUGO; - } - /* - * Special case for apmemu - */ - if (feature->proc_entry) { - proc_entry = - create_proc_entry(feature->proc_entry, pmode, - NULL); - } else { - proc_entry = - create_proc_entry(feature->name, pmode, - omnibook_proc_root); - } - if (!proc_entry) { - printk(KERN_ERR - "%s: unable to create proc entry %s\n", - OMNIBOOK_MODULE_NAME, feature->name); - return -ENOENT; - } - proc_entry->data = feature; - proc_entry->read_proc = &procfile_read_dispatch; - if (feature->write) - proc_entry->write_proc = - &procfile_write_dispatch; - proc_entry->owner = THIS_MODULE; + if (feature->name && feature->read) { + pmode = S_IFREG | S_IRUGO; + if (feature->write) { + pmode |= S_IWUSR; + if (omnibook_userset) + pmode |= S_IWUGO; + } + /* + * Special case for apmemu + */ + if (feature->proc_entry) { + proc_entry = create_proc_entry(feature->proc_entry, pmode, + NULL); + } else { + 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(); + return -ENOENT; + } + proc_entry->data = feature; + proc_entry->read_proc = &procfile_read_dispatch; + if (feature->write) + proc_entry->write_proc = &procfile_write_dispatch; + proc_entry->owner = THIS_MODULE; } list_add_tail(&feature->list, &omnibook_available_feature->list); return 0; @@ -249,7 +244,7 @@ static int __init omnibook_probe(struct platform_device *dev) omnibook_init(feature); } - printk(KERN_INFO "%s: Enabled features:",OMNIBOOK_MODULE_NAME); + printk(O_INFO "Enabled features:"); list_for_each(p, &omnibook_available_feature->list) { feature = list_entry(p, struct omnibook_feature, list); if (feature->name) @@ -279,6 +274,7 @@ static int __exit omnibook_remove(struct platform_device *dev) remove_proc_entry(feature->name, omnibook_proc_root); } kfree(omnibook_available_feature); + return 0; } @@ -296,9 +292,9 @@ static int omnibook_suspend(struct platform_device *dev, pm_message_t state) if (feature->suspend) { retval = feature->suspend(); if (!retval) - printk(KERN_ERR - "%s: unable to suspend the %s feature", - OMNIBOOK_MODULE_NAME, feature->name); + printk(O_ERR + "Unable to suspend the %s feature", + feature->name); } } return 0; @@ -318,9 +314,9 @@ static int omnibook_resume(struct platform_device *dev) if (feature->resume) { retval = feature->resume(); if (!retval) - printk(KERN_ERR - "%s: unable to resume the %s feature", - OMNIBOOK_MODULE_NAME, feature->name); + printk(O_ERR + "Unable to resume the %s feature", + feature->name); } } return 0; @@ -353,24 +349,19 @@ static int __init omnibook_module_init(void) { int retval; - printk(KERN_INFO "%s: Driver version %s.\n", OMNIBOOK_MODULE_NAME, - OMNIBOOK_MODULE_VERSION); + printk(O_INFO "Driver version %s.\n", OMNIBOOK_MODULE_VERSION); if (omnibook_ectype != NONE) - printk(KERN_WARNING - "%s: Forced load with EC firmware type %i.\n", - OMNIBOOK_MODULE_NAME, ffs(omnibook_ectype)); + printk(O_WARN + "Forced load with EC firmware type %i.\n", ffs(omnibook_ectype)); else if ( dmi_check_system(omnibook_ids) ) - printk(KERN_INFO "%s: %s detected.\n", - OMNIBOOK_MODULE_NAME, laptop_model); + printk(O_INFO "%s detected.\n", laptop_model); else - printk(KERN_INFO "%s: Unknown model detected.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Unknown model.\n"); omnibook_proc_root = proc_mkdir(OMNIBOOK_MODULE_NAME, NULL); if (!omnibook_proc_root) { - printk(KERN_ERR "%s: Unable to create /proc/%s.\n", - OMNIBOOK_MODULE_NAME, OMNIBOOK_MODULE_NAME); + printk(O_ERR "Unable to create /proc/%s.\n", OMNIBOOK_MODULE_NAME); return -ENOENT; } @@ -429,7 +420,7 @@ static void __exit omnibook_module_cleanup(void) if (omnibook_proc_root) remove_proc_entry("omnibook", NULL); - printk(KERN_INFO "%s: module is unloaded.\n", OMNIBOOK_MODULE_NAME); + printk(O_INFO "Module is unloaded.\n"); } module_init(omnibook_module_init); diff --git a/lcd.c b/lcd.c index b205f9d..2e4c2f7 100644 --- a/lcd.c +++ b/lcd.c @@ -13,6 +13,7 @@ * * Written by Maciek Górniak , 2002 * Modified by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -46,118 +47,46 @@ static struct backlight_properties omnibookbl_data = { #endif -static int omnibook_get_lcd_brightness(void) +static const struct omnibook_io_operation lcd_io_table[] = { + { TSM30X, CDI, TSM70_LCD_READ, TSM70_LCD_WRITE, 0}, + { XE3GF|TSP10|TSM40, EC, XE3GF_BRTS, XE3GF_BRTS, XE3GF_BRTS_MASK}, + { XE3GC, EC, XE3GC_BTVL, XE3GC_BTVL, XE3GC_BTVL_MASK}, + { AMILOD, EC, AMILOD_CBRG, AMILOD_CBRG, XE3GC_BTVL_MASK}, + { TSA105, EC, A105_BNDT, A105_BNDT, A105_BNDT_MASK}, + { 0,} +}; + +static struct omnibook_io_operation *lcd_io; + +#ifdef CONFIG_OMNIBOOK_BACKLIGHT +static int omnibook_get_backlight(struct backlight_device *bd) { int retval = 0; u8 brgt; - - /* - * XE3GF - * TSP10 - * TSM30X - * TSM40 - */ - if (omnibook_ectype & (XE3GF|TSP10|TSM30X|TSM40) ) { - if ((retval = omnibook_ec_read(XE3GF_BRTS, &brgt))) - return retval; - retval = brgt &= XE3GF_BRTS_MASK; - /* - * XE3GC - */ - } else if (omnibook_ectype & (XE3GC) ) { - if ((retval = omnibook_ec_read(XE3GC_BTVL, &brgt))) - return retval; - retval = brgt &= XE3GC_BTVL_MASK; - /* - * AMILOD - */ - } else if (omnibook_ectype & (AMILOD) ) { + retval = omnibook_io_read(lcd_io, &brgt); + if (!retval) + retval = brgt; - if ((retval = omnibook_ec_read(AMILOD_CBRG, &brgt))) - return retval; - retval = brgt &= AMILOD_CBRG_MASK; - /* - * TSA105 - */ - } else if (omnibook_ectype & (TSA105) ) { - if ((retval = omnibook_ec_read(A105_BNDT, &brgt))) - return retval; - retval = brgt &= A105_BNDT_MASK; - } else { - printk(KERN_INFO - "%s: LCD brightness handling is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); - retval = -ENODEV; - } - - return retval; -} - -static int omnibook_set_lcd_brightness(int brgt) -{ - int retval = 0; - - brgt = - (brgt > omnibook_max_brightness) ? omnibook_max_brightness : brgt; - - /* - * XE3GF - * TSP10 - * TSM30X - * TSM40 - */ - if (omnibook_ectype & (XE3GF|TSP10|TSM30X|TSM40) ) { - if ((retval = omnibook_ec_write(XE3GF_BRTS, brgt))) - return retval; - /* - * XE3GC - */ - } else if (omnibook_ectype & (XE3GC) ) { - if ((retval = omnibook_ec_write(XE3GC_BTVL, brgt))) - return retval; - /* - * AMILOD - */ - } else if (omnibook_ectype & (AMILOD) ) { - if ((retval = omnibook_ec_write(AMILOD_CBRG, brgt))) - return retval; - /* - * TSA105 - */ - } else if (omnibook_ectype & (TSA105) ) { - if ((retval = omnibook_ec_write(A105_BNDT, brgt))) - return retval; - } else { - printk(KERN_INFO - "%s: LCD brightness handling is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); - retval = -ENODEV; - } return retval; } -#ifdef CONFIG_OMNIBOOK_BACKLIGHT -static int omnibook_get_backlight(struct backlight_device *bd) -{ - return omnibook_get_lcd_brightness(); -} - static int omnibook_set_backlight(struct backlight_device *bd) { int intensity = bd->props->brightness; - return omnibook_set_lcd_brightness(intensity); + return omnibook_io_write(lcd_io, intensity); } #endif static int omnibook_brightness_read(char *buffer) { int len = 0; - int brgt; + int retval; + u8 brgt; - brgt = omnibook_get_lcd_brightness(); - if (brgt < 0) - return brgt; + retval = omnibook_io_read(lcd_io, &brgt); + if (retval) + return retval; len += sprintf(buffer + len, "LCD brightness: %2d\n", brgt); @@ -178,7 +107,7 @@ static int omnibook_brightness_write(char *buffer) if ((endp == buffer) || (brgt < 0) || (brgt > omnibook_max_brightness)) return -EINVAL; else - omnibook_set_lcd_brightness(brgt); + omnibook_io_write(lcd_io, brgt); } return 0; } @@ -200,16 +129,18 @@ static int omnibook_brightness_init(void) else omnibook_max_brightness = 10; - printk(KERN_INFO "%s: LCD brightness is between 0 and %i.\n", - OMNIBOOK_MODULE_NAME, omnibook_max_brightness); + printk(O_INFO "LCD brightness is between 0 and %i.\n", + omnibook_max_brightness); + + if (!(lcd_io = omnibook_io_match(lcd_io_table))) + return -ENODEV; #ifdef CONFIG_OMNIBOOK_BACKLIGHT - omnibookbl_data.max_brightness = omnibook_max_brightness, + omnibookbl_data.max_brightness = omnibook_max_brightness; omnibook_backlight_device = backlight_device_register(OMNIBOOK_MODULE_NAME, NULL, &omnibookbl_data); if (IS_ERR(omnibook_backlight_device)) { - printk(KERN_ERR "%s: Unable to register as backlight device.\n", - OMNIBOOK_MODULE_NAME); + printk(O_ERR "Unable to register as backlight device.\n"); return -ENODEV; } #endif @@ -221,8 +152,10 @@ static void omnibook_brightness_cleanup(void) #ifdef CONFIG_OMNIBOOK_BACKLIGHT backlight_device_unregister(omnibook_backlight_device); #endif -} + if(lcd_io->type == CDI) + omnibook_cdimode_exit(); +} static struct omnibook_feature __declared_feature lcd_feature = { .name = "lcd", .enabled = 1, diff --git a/omnibook.h b/omnibook.h index 5b60b82..0d80948 100644 --- a/omnibook.h +++ b/omnibook.h @@ -13,6 +13,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #include @@ -33,23 +34,22 @@ extern int omnibook_ectype; - #define NONE 0 /* 0 Default/unknown EC type */ -#define XE3GF 1 /* 1 HP OmniBook XE3 GF, most Toshiba Satellites and more */ -#define XE3GC 2 /* 2 HP OmniBook XE3 GC, GD, GE and compatible */ -#define OB500 4 /* 3 HP OmniBook 500 and compatible */ -#define OB510 8 /* 4 HP OmniBook 510 */ -#define OB6000 16 /* 5 HP OmniBook 6000 */ -#define OB6100 32 /* 6 HP OmniBook 6100 */ -#define XE4500 64 /* 7 HP OmniBook xe4500 and compatible */ -#define OB4150 128 /* 8 HP OmniBook 4150 */ -#define XE2 256 /* 9 HP OmniBook XE2 */ -#define AMILOD 512 /* 10 Fujitsu Amilo D */ -#define TSP10 1024 /* 11 Toshiba Satellite P10, P15, P20 and compatible */ -#define TSM30X 2048 /* 12 Toshiba Satellite M30X, M35X, M40X, M70 and compatible */ -#define TSM40 4096 /* 13 Toshiba Satellite M40 */ -#define TSA105 8192 /* 14 Toshiba Satellite A105 */ - +#define XE3GF (1<<0) /* 1 HP OmniBook XE3 GF, most Toshiba Satellites and more */ +#define XE3GC (1<<1) /* 2 HP OmniBook XE3 GC, GD, GE and compatible */ +#define OB500 (1<<2) /* 3 HP OmniBook 500 and compatible */ +#define OB510 (1<<3) /* 4 HP OmniBook 510 */ +#define OB6000 (1<<4) /* 5 HP OmniBook 6000 */ +#define OB6100 (1<<5) /* 6 HP OmniBook 6100 */ +#define XE4500 (1<<6) /* 7 HP OmniBook xe4500 and compatible */ +#define OB4150 (1<<7) /* 8 HP OmniBook 4150 */ +#define XE2 (1<<8) /* 9 HP OmniBook XE2 */ +#define AMILOD (1<<9) /* 10 Fujitsu Amilo D */ +#define TSP10 (1<<10) /* 11 Toshiba Satellite P10, P15, P20 and compatible */ +#define TSM30X (1<<11) /* 12 Toshiba Satellite M30X, M35X, M40X, M70 and compatible */ +#define TSM40 (1<<12) /* 13 Toshiba Satellite M40 */ +#define TSA105 (1<<13) /* 14 Toshiba Satellite A105 */ + /* * This represent a feature provided by this module */ @@ -81,6 +81,7 @@ struct omnibook_battery_state { u8 gauge; /* Gauge in % */ u8 status; /* 0 - unknown, 1 - charged, 2 - discharging, 3 - charging, 4 - critical) */ }; + enum { OMNIBOOK_BATTSTAT_UNKNOWN, OMNIBOOK_BATTSTAT_CHARGED, @@ -95,9 +96,22 @@ extern int omnibook_get_ac(void); extern int omnibook_get_battery_status(int num, struct omnibook_battery_state *battstat); extern int set_omnibook_param(const char *val, struct kernel_param *kp); - #define __declared_feature __attribute__ (( __section__(".features"), __aligned__(__alignof__ (struct omnibook_feature)))) __attribute_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 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 /* * Configuration for standalone compilation: diff --git a/onetouch.c b/onetouch.c deleted file mode 100644 index 1cc147b..0000000 --- a/onetouch.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * onetouch.c -- code to handling OneTouch buttons - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * Written by Soós Péter , 2002-2004 - */ - -#ifdef OMNIBOOK_STANDALONE -#include "omnibook.h" -#else -#include -#endif - -#include "ec.h" - -/* There is no information about reading OneTouch status */ -static int omnibook_onetouch_enabled = 0; - -static int omnibook_onetouch_on(void) -{ - if (omnibook_kbc_command - (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_ENABLE)) { - printk(KERN_ERR "%s: failed OneTouch enable command.\n", - OMNIBOOK_MODULE_NAME); - return -EIO; - } - return 0; -} - -static int omnibook_onetouch_off(void) -{ - if (omnibook_kbc_command - (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_ONETOUCH_DISABLE)) { - printk(KERN_ERR "%s: failed OneTouch disable command.\n", - OMNIBOOK_MODULE_NAME); - return -EIO; - } - return 0; -} - -/* - * Power management handlers - */ -static int omnibook_onetouch_resume(void) -{ - int retval; - retval = (omnibook_onetouch_enabled ? omnibook_onetouch_on() : 0); - return retval; -} - -static int omnibook_onetouch_suspend(void) -{ - int retval; - retval = (omnibook_onetouch_enabled ? omnibook_onetouch_off() : 0); - return retval; -} - -static int omnibook_onetouch_enable(void) -{ - /* - * XE3GF - * XE3GC - * OB500 - * OB510 - * OB6000 - * OB6100 - * XE4500 - * AMILOD - * TSP10 - * TSM30X - */ - if (omnibook_ectype & (XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|AMILOD|TSP10|TSM30X) ) { - if (!omnibook_onetouch_enabled) { - if (omnibook_onetouch_on()) - return -EIO; - omnibook_onetouch_enabled = 1; - printk(KERN_INFO - "%s: OneTouch buttons (if any) are enabled.\n", - OMNIBOOK_MODULE_NAME); - } - } else { - omnibook_onetouch_enabled = 0; - return -ENODEV; - } - return 0; -} - -static int omnibook_onetouch_disable(void) -{ - /* - * XE3GF - * XE3GC - * OB500 - * OB510 - * OB6000 - * OB6100 - * XE4500 - * AMILOD - * TSP10 - * TSM30X - */ - if (omnibook_ectype & (XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|AMILOD|TSP10|TSM30X) ) { - if (omnibook_onetouch_enabled) { - if (omnibook_onetouch_off()) { - return -EIO; - } - omnibook_onetouch_enabled = 0; - printk(KERN_INFO - "%s: OneTouch buttons (if any) are disabled.\n", - OMNIBOOK_MODULE_NAME); - } - } else { - omnibook_onetouch_enabled = 0; - return -ENODEV; - } - return 0; -} - -static int omnibook_onetouch_read(char *buffer) -{ - int len = 0; - - len += - sprintf(buffer + len, "OneTouch buttons are %s\n", - (omnibook_onetouch_enabled) ? "enabled" : "disabled"); - - return len; -} - -static int omnibook_onetouch_write(char *buffer) -{ - switch (*buffer) { - case '0': - omnibook_onetouch_disable(); - break; - case '1': - omnibook_onetouch_enable(); - break; - default: - return -EINVAL; - } - return 0; -} - -static int omnibook_onetouch_init(void) -{ - int retval; - - if ((retval = omnibook_onetouch_enable())) - return retval; - return 0; -} - -static void omnibook_onetouch_cleanup(void) -{ - omnibook_onetouch_disable(); -} - -static struct omnibook_feature __declared_feature onetouch_feature = { - .name = "onetouch", - .enabled = 1, - .read = omnibook_onetouch_read, - .write = omnibook_onetouch_write, - .init = omnibook_onetouch_init, - .exit = omnibook_onetouch_cleanup, - .suspend = omnibook_onetouch_suspend, - .resume = omnibook_onetouch_resume, - .ectypes = XE3GF|XE3GC|OB500|OB510|OB6000|OB6100|XE4500|AMILOD|TSP10|TSM30X, -}; - -module_param_named(onetouch, onetouch_feature.enabled, int, S_IRUGO); -MODULE_PARM_DESC(onetouch, "Use 0 to disable, 1 to enable onetouch handling"); -/* End of file */ diff --git a/sections.lds b/sections.lds index c06ae7e..70a539d 100644 --- a/sections.lds +++ b/sections.lds @@ -1,8 +1,9 @@ SECTIONS{ - .features : + .data : { _features_start = .; *(.features) _features_end = .; + *(.data) } } diff --git a/temperature.c b/temperature.c index 18dddab..869ea43 100644 --- a/temperature.c +++ b/temperature.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -64,9 +65,8 @@ static int omnibook_get_cpu_temp(void) return retval; retval = temp; } else { - printk(KERN_INFO - "%s: Temperature monitoring is unsupported on this machine.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO + "Temperature monitoring is unsupported on this machine.\n"); retval = -ENODEV; } return retval; diff --git a/touchpad.c b/touchpad.c index 5ba5abb..672f3a5 100644 --- a/touchpad.c +++ b/touchpad.c @@ -12,6 +12,7 @@ * General Public License for more details. * * Written by Soós Péter , 2002-2004 + * Modified by Mathieu Bérard , 2006 */ #ifdef OMNIBOOK_STANDALONE @@ -29,8 +30,7 @@ static int omnibook_touchpad_on(void) { if (omnibook_kbc_command (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_TOUCHPAD_ENABLE)) { - printk(KERN_ERR "%s: failed touchpad enable command.\n", - OMNIBOOK_MODULE_NAME); + printk(O_ERR "Failed touchpad enable command.\n"); return -EIO; } return 0; @@ -40,8 +40,7 @@ static int omnibook_touchpad_off(void) { if (omnibook_kbc_command (OMNIBOOK_KBC_CONTROL_CMD, OMNIBOOK_KBC_CMD_TOUCHPAD_DISABLE)) { - printk(KERN_ERR "%s: failed touchpad disable command.\n", - OMNIBOOK_MODULE_NAME); + printk(O_ERR "Failed touchpad disable command.\n"); return -EIO; } return 0; @@ -70,8 +69,7 @@ static int omnibook_touchpad_enable(void) if (omnibook_touchpad_on()) return -EIO; omnibook_touchpad_enabled = 1; - printk(KERN_INFO "%s: Touchpad is enabled.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Touchpad is enabled.\n"); } /* * These models have stickpointer, not touchpad: @@ -102,8 +100,7 @@ static int omnibook_touchpad_disable(void) return -EIO; } omnibook_touchpad_enabled = 0; - printk(KERN_INFO "%s: Touchpad is disabled.\n", - OMNIBOOK_MODULE_NAME); + printk(O_INFO "Touchpad is disabled.\n"); } /* * These models have stickpointer, not touchpad: -- 2.43.5