Saturday, November 03, 2007

Update

Seems like my last post with the cut and paste removed some important parts. I'll try to post a .tar.gz file soon instead.

So with the help of dumping the ec i've located a register where the backlight is stored. The current issue that writing another value into that same register doesn't change anything. The question now is how to make the embedded controller to register this.

Thursday, November 01, 2007

EC Dumper

I've written a simple kernel module that dumps the contents of the embedded controller. This module registers a procfs handle which, in turn outputs the content of the ec memory. A brief warning, though. I have experienced infrequent keyboard lockups after heavy usage.

So without further ado:

/*
* ec_dump.c - Dumps the contents of the embedded controller,
* useful for reverse-engineering backlight, killswitches etc.
*
*
* Copyright (C) 2007 Erik Andrén
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/

#include
#include
#include
#include

#include
#include

int ecdump_read_procmem(char *page, char **start, off_t offset, int count, int *eof, void *data)
{
int i, len = 0;
u8 v;
len += sprintf(page + len, "EC +00 +01 +02 +03 +04 +05 +06 +07 +08 +09 +0a +0b +0c +0d +0e +0f\n");
len += sprintf(page + len, "EC 0x%02x: ", 0);
for (i = 0; i < 256; i++) {
if (!ec_read(i, &v))
if (!v)
len += sprintf(page + len, " ");
else
len += sprintf(page + len, "0x%02x ", v);
else
len += sprintf(page + len, "Failed to read address %d!\n", i);

if (i == 255)
break;

if (i % 16 == 15)
len += sprintf(page + len, "\nEC 0x%02x: ", i);
}
len += sprintf(page + len, "\n");
return len;
}

static int __init ec_dump_init(void)
{
printk ("Loading ec_dump!\n");
create_proc_read_entry("ec_dump", 0, NULL, ecdump_read_procmem, NULL);
return 0;
}

static void __exit ec_dump_exit(void)
{
printk ("Unloading my module.\n");
remove_proc_entry("ec_dump", NULL);
return;
}

module_init(ec_dump_init);
module_exit(ec_dump_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Erik Andrén (erik.andren@gmail.com)");


Tags: Linux, ACPI, EC, kernel module, GPL