On Mon, 28 May 2007, Richard Hughes wrote: > I've been hacking to make the nvram hardware buttons on thinkpad exposed > as a hardware mixer device. This requires the nvram to be polled in > kernel space, and then examined to see if the volume and mute status has > changed. I have attached code to export a simple mono tuner, but this > needs further testing and integration. I've also prepared a preliminary > patch to add the polling to the thinkpad_acpi driver. Thanks. As usual, idea accepted, and let's work together to get it into shape for merging. > Please review, and make sure I'm on the right lines. I also can't see > the input patches in the ibm-acpi-2.6 tree, so I've done this against > linus. This isn't for merging, it's just a preview for comments. The tree you need is at: http://repo.or.cz/w/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git input-hotkeys It is being updated as I fix the input-hotkey stuff, so it will get rewinded and you will need to rebase from time to time. BTW, please read the patch descriptions, and suggest any changes you might like on how I should credit your work on them. The above tree is based on 2.6.20, but I will need one based on 2.6.22-rc3 (input API changed) for merging, so I will forward-port it as soon as it is nearly done. Still, 2.6.20 is what I run right now, so it is my main development platform. You *are* welcome to work in any kernel version you see fit, we can change whatever is needed when merging. > +#include <linux/freezer.h> Stay away from the freeer if you can help it. Can we use the standard worker thread interface for this? Using lax timers if possible, so that we are no-tick kernel friendly? Nothing in thinkpad-acpi (so far) needs strict timings for polling or firing, not even the fan watchdog. Although we do need at least 2Hz (and 4Hz seems better) for the nvram polling. I don't know if the no-tick friendly timers can do that. The open/close hooks should go into the git tree tonight. When it does, please use them to enable/disable polling: if nothing is reading us, we don't poll. > +/* NVRAM is a simple data structure that is polled, parsed and then compared > + * to a previous version. > + * Any differences are exposed as bit differences in the struct. */ > +struct tp_nvram_state_struct { > + char thinkpad_toggle; /* ThinkPad button */ > + char zoom_toggle; /* zoom toggle */ > + char display_toggle; /* display toggle */ > + char home_toggle; /* Home button */ > + char search_toggle; /* Search button */ > + char mail_toggle; /* Mail button */ > + char thinklight_toggle; /* ThinkLight */ > + char hibernate_toggle; /* hibernation/suspend toggle */ > + char display_state; /* display state */ > + char expand_toggle; /* hv expansion state */ > + char brightness_level; /* brightness level */ > + char brightness_toggle; /* brightness toggle */ > + char volume_level; /* volume level */ > + char volume_toggle; /* volume toggle */ > + char mute_toggle; /* mute toggle */ > +}; Make this a u32 bitfield, and use 0 and 1 for values, please. > +static void thinkpad_read_nvram (struct tp_nvram_state_struct *state) > +{ > + char data[6]; > + > + /* read 6 bytes of nvram */ > + data[0] = nvram_read_byte(0x56); > + data[1] = nvram_read_byte(0x57); > + data[2] = nvram_read_byte(0x58); > + data[3] = nvram_read_byte(0x59); > + data[4] = nvram_read_byte(0x5e); > + data[5] = nvram_read_byte(0x60); All magic constants need an appropriate #define, please. > + /* process and extract states */ > + state->home_toggle = ( data[0] & 0x01); > + state->search_toggle = ( data[0] & 0x02) >> 1; > + state->mail_toggle = ( data[0] & 0x04) >> 2; > + state->thinkpad_toggle = ( data[1] & 0x08) >> 3; > + state->zoom_toggle = (~data[1] & 0x20) >> 5; > + state->display_toggle = ( data[1] & 0x40) >> 6; > + state->thinklight_toggle = ( data[2] & 0x10) >> 4; > + state->expand_toggle = ( data[3] & 0x10) >> 4; > + state->brightness_level = ( data[4] & 0x07); > + state->brightness_toggle = ( data[4] & 0x20) >> 5; > + state->volume_level = ( data[5] & 0x0f); > + state->volume_toggle = ( data[5] & 0x80) >> 7; > + state->mute_toggle = ( data[5] & 0x40) >> 6; More magic constants... > + /* find new button presses that are not acpi events */ > + if (new_nvram_state.thinkpad_toggle != last_nvram_state.thinkpad_toggle) { > + emit_keycode (KEY_COMPOSE); // thinkpad key We need to get this through the input driver keycode map, see above git tree... > /* > * Thinkpad soundcard mixer interface > * Copyright (c) by Richard Hughes <richard@xxxxxxxxxxx> I won't go into this one right now (I also have something like it around, but EC based), and I'd rather go over both codes later and merge a mix with the best ideas from both. But my bandwidth is a bit limited, so I shall go at it after the input work is done, and after breaking the driver into various files (which I was planning to have done already, but the input work is more useful and far more interesting :p). -- "One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie." -- The Silicon Valley Tarot Henrique Holschuh ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ ibm-acpi-devel mailing list ibm-acpi-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/ibm-acpi-devel