Revision: 125 http://svn.sourceforge.net/mactel-linux/?rev=125&view=rev Author: nboichat Date: 2007-05-26 15:33:14 -0700 (Sat, 26 May 2007)
Log Message: ----------- Add 2.6.22 patch series. Added Paths: ----------- trunk/kernel/mactel-patches-2.6.22/ trunk/kernel/mactel-patches-2.6.22/appleir.patch trunk/kernel/mactel-patches-2.6.22/applesmc-use-input-polldev.patch trunk/kernel/mactel-patches-2.6.22/applesmc_add_name.patch trunk/kernel/mactel-patches-2.6.22/applesmc_int.patch trunk/kernel/mactel-patches-2.6.22/appletouch.patch trunk/kernel/mactel-patches-2.6.22/apply trunk/kernel/mactel-patches-2.6.22/series trunk/kernel/mactel-patches-2.6.22/unapply Added: trunk/kernel/mactel-patches-2.6.22/appleir.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.22/appleir.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/appleir.patch 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,429 @@ +Apple IR patch. + +From: James McKenzie <[EMAIL PROTECTED]> + + +--- + + drivers/input/misc/Kconfig | 5 + + drivers/input/misc/Makefile | 1 + drivers/input/misc/appleir.c | 379 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 385 insertions(+), 0 deletions(-) + +diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig +index 842a7b4..00d43d0 100644 +--- a/drivers/input/misc/Kconfig ++++ b/drivers/input/misc/Kconfig +@@ -113,6 +113,10 @@ config INPUT_ATI_REMOTE2 + To compile this driver as a module, choose M here: the module will be + called ati_remote2. + ++config USB_APPLEIR ++ tristate "Apple Mac Mini USB IR receiver (built in)" ++ depends on USB && INPUT ++ + config INPUT_KEYSPAN_REMOTE + tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" + depends on EXPERIMENTAL +@@ -190,3 +194,4 @@ config HP_SDC_RTC + of the HP SDC controller. + + endif ++ +diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile +index 8b2f779..ca41877 100644 +--- a/drivers/input/misc/Makefile ++++ b/drivers/input/misc/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o + obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o + obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o + obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o ++obj-$(CONFIG_USB_APPLEIR) += appleir.o + obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o + obj-$(CONFIG_INPUT_POWERMATE) += powermate.o + obj-$(CONFIG_INPUT_YEALINK) += yealink.o +diff --git a/drivers/input/misc/appleir.c b/drivers/input/misc/appleir.c +new file mode 100644 +index 0000000..170cee6 +--- /dev/null ++++ b/drivers/input/misc/appleir.c +@@ -0,0 +1,379 @@ ++/* ++ * drivers/usb/input/appleir.c - driver for Apple Intel-based Macs IR Receiver ++ * ++ * Copyright (C) 2006 James McKenzie <[EMAIL PROTECTED]> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License v2 as published by the ++ * Free Software Foundation. ++ * ++ * 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 <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/input.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/usb.h> ++#include <linux/usb/input.h> ++#include <linux/mutex.h> ++#include <asm/unaligned.h> ++#include <asm/byteorder.h> ++ ++#define DRIVER_VERSION "v1.2" ++#define DRIVER_AUTHOR "James McKenzie" ++#define DRIVER_DESC "USB Apple MacIntel IR Receiver driver" ++#define DRIVER_LICENSE "GPL" ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE(DRIVER_LICENSE); ++ ++#define USB_VENDOR_ID_APPLE 0x05ac ++#define USB_DEVICE_ID_APPLE_IR 0x8240 ++ ++#define URB_SIZE 32 ++ ++#define MAX_KEYS 8 ++#define MAX_KEYS_MASK (MAX_KEYS - 1) ++ ++static int debug = 1; ++ ++struct appleir { ++ struct input_dev *dev; ++ uint8_t *data; ++ dma_addr_t dma_buf; ++ struct usb_device *usbdev; ++ struct urb *urb; ++ struct timer_list key_up_timer; ++ int current_key; ++ char phys[32]; ++}; ++ ++ ++static struct usb_device_id appleir_ids[] = { ++ { ++ USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR), ++ .driver_info = 0 ++ }, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(usb, appleir_ids); ++ ++/* ++ * Devices report the following, where XX depends on the remote and/or the ++ * receiver (at least 2a, 83, ca, ee have been reported as possible values, it ++ * looks like it is remote control dependent). ++ * The fifth byte's LSB also depends on the hardware. ++ * 25 87 ee XX 0a/0b + ++ * 25 87 ee XX 0c/0d - ++ * 25 87 ee XX 09/08 << ++ * 25 87 ee XX 06/07 >> ++ * 25 87 ee XX 05/04 >" ++ * 25 87 ee 83 03/02 menu ++ * 26 00 00 00 00 for key repeat ++ * ++ * Thomas Glanzmann also observes the following event sometimes sent after a key ++ * is released, which I interpret as a flat battery message: ++ * 25 87 e0 ca 06 flat battery ++ */ ++ ++static int keymap[MAX_KEYS] = { ++ KEY_RESERVED, KEY_MENU, ++ KEY_PLAYPAUSE, KEY_NEXTSONG, ++ KEY_PREVIOUSSONG, KEY_VOLUMEUP, ++ KEY_VOLUMEDOWN, KEY_RESERVED ++}; ++ ++static void dump_packet(struct appleir *appleir, char *msg, ++ uint8_t * data, int len) ++{ ++ int i; ++ ++ printk(KERN_ERR "appleir: %s (%d bytes)", msg, len); ++ ++ for (i = 0; i < len; ++i) { ++ printk(" %02x", data[i]); ++ } ++ ++ printk("\n"); ++} ++ ++ ++static void key_up(struct appleir *appleir, int key) ++{ ++ if (debug) ++ printk (KERN_DEBUG "key %d up\n", key); ++ ++ input_report_key(appleir->dev, key, 0); ++ input_sync(appleir->dev); ++} ++ ++static void key_down(struct appleir *appleir, int key) ++{ ++ if (debug) ++ printk (KERN_DEBUG "key %d down\n", key); ++ ++ input_report_key(appleir->dev, key, 1); ++ input_sync(appleir->dev); ++} ++ ++static void battery_flat(struct appleir *appleir) ++{ ++ printk(KERN_WARNING "appleir: possible flat battery?\n"); ++} ++ ++static void key_up_tick(unsigned long data) ++{ ++ struct appleir *apple_ir = (struct appleir*)data; ++ ++ if (apple_ir->current_key) { ++ key_up(apple_ir, apple_ir->current_key); ++ apple_ir->current_key = 0; ++ } ++} ++ ++static void parse_data(struct appleir *apple_ir, uint8_t *data, int len) ++{ ++ static const uint8_t keydown[] = { 0x25, 0x87, 0xee }; ++ static const uint8_t keyrepeat[] = { 0x26, 0x00, 0x00, 0x00, 0x00 }; ++ static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 }; ++ ++ if (debug) ++ dump_packet(apple_ir, "received", data, len); ++ ++ if (len != 5) ++ return; ++ ++ if (!memcmp(data, keydown, sizeof(keydown))) { ++ /* ++ * If we already have a key down, take it up before marking ++ * this one down. ++ */ ++ if (apple_ir->current_key) ++ key_up(apple_ir, apple_ir->current_key); ++ apple_ir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK]; ++ ++ key_down(apple_ir, apple_ir->current_key); ++ ++ /* ++ * Remote doesn't do key up, either pull them up, in the test ++ * above, or here set a timer which pulls them up after 1/8 s ++ */ ++ mod_timer(&apple_ir->key_up_timer, jiffies + HZ / 8); ++ ++ return; ++ } ++ ++ if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { ++ key_down(apple_ir, apple_ir->current_key); ++ ++ /* ++ * Remote doesn't do key up, either pull them up, in the test ++ * above, or here set a timer which pulls them up after 1/8 s ++ */ ++ mod_timer(&apple_ir->key_up_timer, jiffies + HZ / 8); ++ return; ++ } ++ ++ if (!memcmp(data, flatbattery, sizeof(flatbattery))) { ++ battery_flat(apple_ir); ++ /* Fall through */ ++ } ++ ++ dump_packet(apple_ir, "unknown packet", data, len); ++} ++ ++static void appleir_urb(struct urb *urb) ++{ ++ struct appleir *appleir = urb->context; ++ int retval; ++ ++ switch (urb->status) { ++ case 0: ++ parse_data(appleir, urb->transfer_buffer, urb->actual_length); ++ break; ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ /* this urb is terminated, clean up */ ++ dbg("%s - urb shutting down with status: %d", ++ __FUNCTION__, urb->status); ++ return; ++ default: ++ dbg("%s - nonzero urb status received: %d", ++ __FUNCTION__, urb->status); ++ } ++ ++ retval = usb_submit_urb(urb, GFP_ATOMIC); ++ if (retval) ++ err("%s - usb_submit_urb failed with result %d", ++ __FUNCTION__, retval); ++} ++ ++ ++static int appleir_open(struct input_dev *dev) ++{ ++ struct appleir *appleir = dev->private; ++ ++ if (usb_submit_urb(appleir->urb, GFP_KERNEL)) ++ return -EIO; ++ ++ return 0; ++} ++ ++static void appleir_close(struct input_dev *dev) ++{ ++ struct appleir *appleir = dev->private; ++ usb_kill_urb(appleir->urb); ++ del_timer_sync(&appleir->key_up_timer); ++} ++ ++static int appleir_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_endpoint_descriptor *endpoint; ++ struct appleir *appleir = NULL; ++ struct input_dev *input_dev; ++ int i; ++ int ret = -ENOMEM; ++ ++ appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL); ++ if (!appleir) ++ goto fail; ++ ++ memset(appleir, 0, sizeof(struct appleir)); ++ ++ appleir->data = ++ usb_buffer_alloc(dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf); ++ if (!appleir->data) ++ goto fail_appleir; ++ ++ appleir->urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!appleir->urb) ++ goto fail_buffer; ++ ++ appleir->usbdev = dev; ++ ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ goto fail_urb; ++ ++ appleir->dev = input_dev; ++ ++ if (usb_make_path(dev, appleir->phys, sizeof(appleir->phys)) < 0) ++ goto fail_input_device; ++ ++ strlcpy(appleir->phys, "/input0", sizeof(appleir->phys)); ++ ++ input_dev->name = "Apple MacIntel infrared remote control driver"; ++ input_dev->phys = appleir->phys; ++ usb_to_input_id(dev, &input_dev->id); ++ input_dev->cdev.dev = &intf->dev; ++ input_dev->private = appleir; ++ ++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); ++ input_dev->ledbit[0] = 0; ++ ++ for (i = 0; i < MAX_KEYS; i++) { ++ set_bit(keymap[i], input_dev->keybit); ++ } ++ ++ clear_bit(0, input_dev->keybit); ++ ++ input_dev->open = appleir_open; ++ input_dev->close = appleir_close; ++ ++ endpoint = &intf->cur_altsetting->endpoint[0].desc; ++ ++ usb_fill_int_urb(appleir->urb, dev, ++ usb_rcvintpipe(dev, endpoint->bEndpointAddress), ++ appleir->data, 8, ++ appleir_urb, appleir, endpoint->bInterval); ++ ++ appleir->urb->transfer_dma = appleir->dma_buf; ++ appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ usb_set_intfdata(intf, appleir); ++ ++ init_timer(&appleir->key_up_timer); ++ ++ appleir->key_up_timer.function = key_up_tick; ++ appleir->key_up_timer.data = (unsigned long) appleir; ++ ++ ret = input_register_device(appleir->dev); ++ if (ret < 0) ++ goto fail_timer; ++ ++ return 0; ++ ++fail_timer: ++ del_timer_sync(&appleir->key_up_timer); ++ ++fail_input_device: ++ input_free_device(appleir->dev); ++ ++fail_urb: ++ usb_free_urb(appleir->urb); ++ ++fail_buffer: ++ usb_buffer_free(dev, URB_SIZE, appleir->data, appleir->dma_buf); ++ ++fail_appleir: ++ kfree(appleir); ++ ++fail: ++ return ret; ++} ++ ++static void appleir_disconnect(struct usb_interface *intf) ++{ ++ struct appleir *appleir = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ if (appleir) { ++ input_unregister_device(appleir->dev); ++ del_timer_sync(&appleir->key_up_timer); ++ usb_kill_urb(appleir->urb); ++ usb_free_urb(appleir->urb); ++ usb_buffer_free(interface_to_usbdev(intf), URB_SIZE, ++ appleir->data, appleir->dma_buf); ++ kfree(appleir); ++ } ++} ++ ++static struct usb_driver appleir_driver = { ++ .name = "appleir", ++ .probe = appleir_probe, ++ .disconnect = appleir_disconnect, ++ .id_table = appleir_ids, ++}; ++ ++static int __init appleir_init(void) ++{ ++ int retval; ++ retval = usb_register(&appleir_driver); ++ if (retval) ++ goto out; ++ info(DRIVER_VERSION ":" DRIVER_DESC); ++ out: ++ return retval; ++} ++ ++static void __exit appleir_exit(void) ++{ ++ usb_deregister(&appleir_driver); ++} ++ ++module_init(appleir_init); ++module_exit(appleir_exit); Added: trunk/kernel/mactel-patches-2.6.22/applesmc-use-input-polldev.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.22/applesmc-use-input-polldev.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/applesmc-use-input-polldev.patch 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,221 @@ +HWMON: applesmc - convert to use input-polldev. + +From: Nicolas Boichat <[EMAIL PROTECTED]> + +Switch to using input-polldev skeleton instead of implementing +polling loop by itself. This also fixes problem with trylock +on a mutex in atomic context. + +Signed-off-by: Dmitry Torokhov <[EMAIL PROTECTED]> +--- + + drivers/hwmon/Kconfig | 1 + + drivers/hwmon/applesmc.c | 83 +++++++++++++++++----------------------------- + 2 files changed, 31 insertions(+), 53 deletions(-) + +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 4d1cb5b..cfb2a04 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -623,6 +623,7 @@ config SENSORS_APPLESMC + depends on HWMON && INPUT && X86 + select NEW_LEDS + select LEDS_CLASS ++ select INPUT_POLLDEV + default n + help + This driver provides support for the Apple System Management +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index fd1281f..eb81a64 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -28,7 +28,7 @@ + + #include <linux/delay.h> + #include <linux/platform_device.h> +-#include <linux/input.h> ++#include <linux/input-polldev.h> + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/timer.h> +@@ -59,9 +59,9 @@ + + #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ + #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ +-#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ ++#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ + +-#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ ++#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ + + #define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */ + #define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */ +@@ -99,7 +99,7 @@ static const char* fan_speed_keys[] = { + #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ + #define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ + +-#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */ ++#define APPLESMC_POLL_INTERVAL 50 /* msecs */ + #define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ + #define APPLESMC_INPUT_FLAT 4 + +@@ -121,8 +121,7 @@ static const int debug; + static struct platform_device *pdev; + static s16 rest_x; + static s16 rest_y; +-static struct timer_list applesmc_timer; +-static struct input_dev *applesmc_idev; ++static struct input_polled_dev *applesmc_idev; + static struct class_device *hwmon_class_dev; + + /* Indicates whether this computer has an accelerometer. */ +@@ -134,7 +133,7 @@ static unsigned int applesmc_light; + /* Indicates which temperature sensors set to use. */ + static unsigned int applesmc_temperature_set; + +-static struct mutex applesmc_lock; ++static DEFINE_MUTEX(applesmc_lock); + + /* + * Last index written to key_at_index sysfs file, and value to use for all other +@@ -451,27 +450,12 @@ static void applesmc_calibrate(void) + rest_x = -rest_x; + } + +-static int applesmc_idev_open(struct input_dev *dev) +-{ +- add_timer(&applesmc_timer); +- +- return 0; +-} +- +-static void applesmc_idev_close(struct input_dev *dev) +-{ +- del_timer_sync(&applesmc_timer); +-} +- +-static void applesmc_idev_poll(unsigned long unused) ++static void applesmc_idev_poll(struct input_polled_dev *dev) + { ++ struct input_dev *idev = dev->input; + s16 x, y; + +- /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ +- if (!mutex_trylock(&applesmc_lock)) { +- mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); +- return; +- } ++ mutex_lock(&applesmc_lock); + + if (applesmc_read_motion_sensor(SENSOR_X, &x)) + goto out; +@@ -479,13 +463,11 @@ static void applesmc_idev_poll(unsigned long unused) + goto out; + + x = -x; +- input_report_abs(applesmc_idev, ABS_X, x - rest_x); +- input_report_abs(applesmc_idev, ABS_Y, y - rest_y); +- input_sync(applesmc_idev); ++ input_report_abs(idev, ABS_X, x - rest_x); ++ input_report_abs(idev, ABS_Y, y - rest_y); ++ input_sync(idev); + + out: +- mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); +- + mutex_unlock(&applesmc_lock); + } + +@@ -817,8 +799,7 @@ static ssize_t applesmc_key_at_index_read_show(struct device *dev, + + if (!ret) { + return info[0]; +- } +- else { ++ } else { + return ret; + } + } +@@ -1089,6 +1070,7 @@ static int applesmc_dmi_match(struct dmi_system_id *id) + /* Create accelerometer ressources */ + static int applesmc_create_accelerometer(void) + { ++ struct input_dev *idev; + int ret; + + ret = sysfs_create_group(&pdev->dev.kobj, +@@ -1096,40 +1078,37 @@ static int applesmc_create_accelerometer(void) + if (ret) + goto out; + +- applesmc_idev = input_allocate_device(); ++ applesmc_idev = input_allocate_polled_device(); + if (!applesmc_idev) { + ret = -ENOMEM; + goto out_sysfs; + } + ++ applesmc_idev->poll = applesmc_idev_poll; ++ applesmc_idev->poll_interval = APPLESMC_POLL_INTERVAL; ++ + /* initial calibrate for the input device */ + applesmc_calibrate(); + +- /* initialize the input class */ +- applesmc_idev->name = "applesmc"; +- applesmc_idev->id.bustype = BUS_HOST; +- applesmc_idev->dev.parent = &pdev->dev; +- applesmc_idev->evbit[0] = BIT(EV_ABS); +- applesmc_idev->open = applesmc_idev_open; +- applesmc_idev->close = applesmc_idev_close; +- input_set_abs_params(applesmc_idev, ABS_X, ++ /* initialize the input device */ ++ idev = applesmc_idev->input; ++ idev->name = "applesmc"; ++ idev->id.bustype = BUS_HOST; ++ idev->dev.parent = &pdev->dev; ++ idev->evbit[0] = BIT(EV_ABS); ++ input_set_abs_params(idev, ABS_X, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); +- input_set_abs_params(applesmc_idev, ABS_Y, ++ input_set_abs_params(idev, ABS_Y, + -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); + +- ret = input_register_device(applesmc_idev); ++ ret = input_register_polled_device(applesmc_idev); + if (ret) + goto out_idev; + +- /* start up our timer for the input device */ +- init_timer(&applesmc_timer); +- applesmc_timer.function = applesmc_idev_poll; +- applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD; +- + return 0; + + out_idev: +- input_free_device(applesmc_idev); ++ input_free_polled_device(applesmc_idev); + + out_sysfs: + sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); +@@ -1142,8 +1121,8 @@ out: + /* Release all ressources used by the accelerometer */ + static void applesmc_release_accelerometer(void) + { +- del_timer_sync(&applesmc_timer); +- input_unregister_device(applesmc_idev); ++ input_unregister_polled_device(applesmc_idev); ++ input_free_polled_device(applesmc_idev); + sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); + } + +@@ -1180,8 +1159,6 @@ static int __init applesmc_init(void) + int count; + int i; + +- mutex_init(&applesmc_lock); +- + if (!dmi_check_system(applesmc_whitelist)) { + printk(KERN_WARNING "applesmc: supported laptop not found!\n"); + ret = -ENODEV; Added: trunk/kernel/mactel-patches-2.6.22/applesmc_add_name.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.22/applesmc_add_name.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/applesmc_add_name.patch 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,46 @@ +Add name file needed by lm_sensors user-space applications in applesmc sysfs tree. + +From: Nicolas Boichat <[EMAIL PROTECTED]> + + +--- + + drivers/hwmon/applesmc.c | 7 ++++++- + 1 files changed, 6 insertions(+), 1 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 366f4a1..fd1281f 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1206,11 +1206,13 @@ static int __init applesmc_init(void) + } + + ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_name.attr); ++ if (ret) ++ goto out_device; + + /* Create key enumeration sysfs files */ + ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); + if (ret) +- goto out_device; ++ goto out_name; + + /* create fan files */ + count = applesmc_get_fan_count(); +@@ -1310,6 +1312,8 @@ out_fan_1: + sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); + out_key_enumeration: + sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); ++out_name: ++ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); + out_device: + platform_device_unregister(pdev); + out_driver: +@@ -1335,6 +1339,7 @@ static void __exit applesmc_exit(void) + sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); + sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); + sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); ++ sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); + platform_device_unregister(pdev); + platform_driver_unregister(&applesmc_driver); + release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); Added: trunk/kernel/mactel-patches-2.6.22/applesmc_int.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.22/applesmc_int.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/applesmc_int.patch 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,410 @@ +Interrupt support for the accelerometer. + +From: Nicolas Boichat <[EMAIL PROTECTED]> + + +--- + + drivers/hwmon/applesmc.c | 316 +++++++++++++++++++++++++++++++++++++++++++--- + 1 files changed, 293 insertions(+), 23 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index eb81a64..ff56afd 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -39,14 +39,20 @@ + #include <linux/leds.h> + #include <linux/hwmon.h> + #include <linux/workqueue.h> ++#include <linux/interrupt.h> + + /* data port used by Apple SMC */ + #define APPLESMC_DATA_PORT 0x300 + /* command/status port used by Apple SMC */ + #define APPLESMC_CMD_PORT 0x304 ++/* status port used by Apple SMC to get which interrupt type just happened */ ++#define APPLESMC_INT_PORT 0x31f + + #define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + ++/* Defined in ACPI DSDT table, should we read it from there? */ ++#define APPLESMC_IRQ 6 ++ + #define APPLESMC_MAX_DATA_LENGTH 32 + + #define APPLESMC_STATUS_MASK 0x0f +@@ -57,6 +63,8 @@ + + #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ + ++#define INTERRUPT_OK_KEY "NTOK" /* w-o ui8 */ ++ + #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ + #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ + #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ +@@ -68,6 +76,19 @@ + #define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */ + #define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */ + ++/* ++ * Interrupt controls. ++ * If the norm of the position (sqrt(MO_X^2+MO_Y^2+MO_Z^2)) is smaller than ++ * MOLT (free fall), or bigger than MOHT (high acceleration) for longer than the ++ * value of MOLD (or MOHD), SMC will trigger an interrupt. ++ */ ++#define MOTION_LOW_NORM "MOLT" /* r/w sp78 (2 bytes) */ ++#define MOTION_HIGH_NORM "MOHT" /* r/w sp78 (2 bytes) */ ++#define MOTION_LOW_NORM_INTERVAL "MOLD" /* r/w ui8 */ ++#define MOTION_HIGH_NORM_INTERVAL "MOHD" /* r/w ui8 */ ++ ++#define MSDW_KEY "MSDW" /* r/w flag (1 byte) */ ++ + #define FANS_COUNT "FNum" /* r-o ui8 */ + #define FANS_MANUAL "FS! " /* r-w ui16 */ + #define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ +@@ -347,12 +368,79 @@ static int applesmc_read_motion_sensor(int index, s16* value) + } + + /* ++ * applesmc_init_check_key_value - checks if a given key contains the bytes in ++ * buffer, if not, writes these bytes. ++ * In case of failure retry every INIT_WAIT_MSECS msec, and timeout if it ++ * waited more than INIT_TIMEOUT_MSECS in total. ++ * Returns zero on success or a negative error on failure. Callers must ++ * hold applesmc_lock. ++ */ ++static int applesmc_init_check_key_value(const char* key, u8* buffer, u8 len) ++{ ++ int total, ret, i, compare; ++ u8 rdbuffer[APPLESMC_MAX_DATA_LENGTH]; ++ ++ if (len > APPLESMC_MAX_DATA_LENGTH) { ++ printk(KERN_ERR "applesmc_init_check_key_value: cannot " ++ "read/write more than %d bytes", ++ APPLESMC_MAX_DATA_LENGTH); ++ return -EINVAL; ++ } ++ ++ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { ++ if (!(ret = applesmc_read_key(key, rdbuffer, len))) { ++ compare = 1; ++ for (i = 0; i < len; i++) { ++ if (rdbuffer[i] != buffer[i]) { ++ compare = 0; ++ break; ++ } ++ } ++ ++ if (compare) { ++ return 0; ++ } ++ } ++ ret = applesmc_write_key(key, buffer, len); ++ msleep(INIT_WAIT_MSECS); ++ } ++ ++ if (ret) ++ return ret; ++ else ++ return -EIO; ++} ++ ++irqreturn_t applesmc_irq_handler(int irq, void *dev_id) ++{ ++ u8 int_type = inb(APPLESMC_INT_PORT); ++ ++ switch (int_type) { ++ case 0x60: ++ printk("applesmc: received a free fall interrupt\n"); ++ break; ++ case 0x6f: ++ printk("applesmc: received a high acceleration interrupt\n"); ++ break; ++ case 0x80: ++ printk("applesmc: received a shock interrupt\n"); ++ break; ++ default: ++ printk("applesmc: received an unknown interrupt %x\n", int_type); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* + * applesmc_device_init - initialize the accelerometer. Returns zero on success + * and negative error code on failure. Can sleep. + */ + static int applesmc_device_init(void) + { +- int total, ret = -ENXIO; ++ int total; ++ int ret = -ENXIO; ++ int ret1, ret2; + u8 buffer[2]; + + if (!applesmc_accelerometer) +@@ -360,32 +448,79 @@ static int applesmc_device_init(void) + + mutex_lock(&applesmc_lock); + ++ /* Accept interrupts */ ++ buffer[0] = 0x01; + for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { +- if (debug) +- printk(KERN_DEBUG "applesmc try %d\n", total); +- if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && +- (buffer[0] != 0x00 || buffer[1] != 0x00)) { +- if (total == INIT_TIMEOUT_MSECS) { +- printk(KERN_DEBUG "applesmc: device has" +- " already been initialized" +- " (0x%02x, 0x%02x).\n", +- buffer[0], buffer[1]); +- } else { +- printk(KERN_DEBUG "applesmc: device" +- " successfully initialized" +- " (0x%02x, 0x%02x).\n", +- buffer[0], buffer[1]); +- } +- ret = 0; +- goto out; +- } +- buffer[0] = 0xe0; +- buffer[1] = 0x00; +- applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); ++ ret1 = applesmc_write_key(INTERRUPT_OK_KEY, buffer, 1); ++ msleep(INIT_WAIT_MSECS); ++ ++ if (!ret1) ++ break; ++ } ++ if (ret1) ++ printk(KERN_WARNING "applesmc: Cannot set NTOK key, " ++ "will not receive interrupts.\n"); ++ ++ /* Setup interrupt controls. */ ++ buffer[0] = 20; /* 20 msecs */ ++ ret1 = applesmc_init_check_key_value(MOTION_LOW_NORM_INTERVAL, ++ buffer, 1); ++ ++ buffer[0] = 20; /* 20 msecs */ ++ ret2 = applesmc_init_check_key_value(MOTION_HIGH_NORM_INTERVAL, ++ buffer, 1); ++ ++ if (ret1 || ret2) { ++ printk(KERN_WARNING "applesmc: Cannot set motion sensor " ++ "interrupt interval, might not receive " ++ "some interrupts."); ++ } ++ ++ buffer[0] = 0x00; ++ buffer[1] = 0x60; ++ ret1 = applesmc_init_check_key_value(MOTION_LOW_NORM, buffer, 2); ++ ++ buffer[0] = 0x01; ++ buffer[1] = 0xc0; ++ ret2 = applesmc_init_check_key_value(MOTION_HIGH_NORM, buffer, 2); ++ ++ if (ret1 || ret2) { ++ printk(KERN_WARNING "applesmc: Cannot set motion sensor " ++ "min/max norm parameters, " ++ "might not receive some interrupts."); ++ } ++ ++ /* Mysterious key. */ ++ buffer[0] = 0x01; ++ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { ++ ret1 = applesmc_write_key(MSDW_KEY, buffer, 1); + msleep(INIT_WAIT_MSECS); ++ ++ if (!ret1) ++ break; ++ } ++ if (ret1) ++ printk(KERN_WARNING "applesmc: Cannot set MSDW key\n"); ++ ++ /* Initialize the device. */ ++ buffer[0] = 0xe0; ++ buffer[1] = 0xf8; ++ if (applesmc_init_check_key_value(MOTION_SENSOR_KEY, buffer, 2)) { ++ printk(KERN_WARNING "applesmc: failed to init " ++ "the accelerometer\n"); ++ goto out; + } + +- printk(KERN_WARNING "applesmc: failed to init the device\n"); ++ ret1 = request_irq(APPLESMC_IRQ, applesmc_irq_handler, IRQF_DISABLED, ++ "applesmc_irq_handler", NULL); ++ ++ if (ret1) { ++ printk(KERN_WARNING "applesmc: cannot setup irq handler\n"); ++ } ++ ++ printk(KERN_DEBUG "applesmc: accelerometer " ++ "successfully initialized.\n"); ++ ret = 0; + + out: + mutex_unlock(&applesmc_lock); +@@ -430,9 +565,16 @@ static int applesmc_resume(struct platform_device *dev) + return applesmc_device_init(); + } + ++static int applesmc_remove(struct platform_device *dev) ++{ ++ free_irq(6, NULL); ++ return 0; ++} ++ + static struct platform_driver applesmc_driver = { + .probe = applesmc_probe, + .resume = applesmc_resume, ++ .remove = applesmc_remove, + .driver = { + .name = "applesmc", + .owner = THIS_MODULE, +@@ -894,6 +1036,122 @@ static ssize_t applesmc_key_at_index_store(struct device *dev, + return count; + } + ++static ssize_t applesmc_accelerometer_show(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ int ret; ++ unsigned int value = 0; ++ u8 buffer[2]; ++ char* key; ++ int length; ++ struct sensor_device_attribute_2 *sensor_attr = ++ to_sensor_dev_attr_2(attr); ++ ++ switch(sensor_attr->index) { ++ case 0: ++ key = MOTION_LOW_NORM_INTERVAL; ++ length = 1; ++ break; ++ case 1: ++ key = MOTION_HIGH_NORM_INTERVAL; ++ length = 1; ++ break; ++ case 2: ++ key = MOTION_LOW_NORM; ++ length = 2; ++ break; ++ case 3: ++ key = MOTION_HIGH_NORM; ++ length = 2; ++ break; ++ default: ++ printk("Invalid index for applesmc_accelerometer_show"); ++ return -EINVAL; ++ } ++ ++ mutex_lock(&applesmc_lock); ++ ++ ret = applesmc_read_key(key, buffer, length); ++ if (length == 2) ++ value = ((unsigned int)buffer[0] << 8) | buffer[1]; ++ else if (length == 1) ++ value = buffer[0]; ++ else { ++ printk("Invalid length for applesmc_param_show"); ++ ret = -EINVAL; ++ } ++ ++ mutex_unlock(&applesmc_lock); ++ if (ret) ++ return ret; ++ else ++ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", value); ++} ++ ++static ssize_t applesmc_accelerometer_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *sysfsbuf, size_t count) ++{ ++ int ret; ++ u32 value; ++ u8 buffer[2]; ++ char* key; ++ int length; ++ struct sensor_device_attribute_2 *sensor_attr = ++ to_sensor_dev_attr_2(attr); ++ ++ switch(sensor_attr->index) { ++ case 0: ++ key = MOTION_LOW_NORM_INTERVAL; ++ length = 1; ++ break; ++ case 1: ++ key = MOTION_HIGH_NORM_INTERVAL; ++ length = 1; ++ break; ++ case 2: ++ key = MOTION_LOW_NORM; ++ length = 2; ++ break; ++ case 3: ++ key = MOTION_HIGH_NORM; ++ length = 2; ++ break; ++ default: ++ printk("Invalid index for applesmc_accelerometer_show"); ++ return -EINVAL; ++ } ++ ++ value = simple_strtoul(sysfsbuf, NULL, 10); ++ ++ if (length == 2) { ++ if (value > 0xffff) ++ return -EINVAL; ++ ++ buffer[0] = (value >> 8) & 0xff; ++ buffer[1] = value & 0xff; ++ } else if (length == 1) { ++ if (value > 0xff) ++ return -EINVAL; ++ ++ buffer[0] = value & 0xff; ++ } else { ++ printk("Invalid length for applesmc_param_store"); ++ return -EINVAL; ++ } ++ ++ mutex_lock(&applesmc_lock); ++ ++ ret = applesmc_write_key(key, buffer, length); ++ ++ mutex_unlock(&applesmc_lock); ++ ++ if (ret) ++ return ret; ++ else ++ return count; ++} ++ + static struct led_classdev applesmc_backlight = { + .name = "smc:kbd_backlight", + .default_trigger = "nand-disk", +@@ -905,10 +1163,22 @@ static DEVICE_ATTR(name, 0444, applesmc_name_show, NULL); + static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); + static DEVICE_ATTR(calibrate, 0644, + applesmc_calibrate_show, applesmc_calibrate_store); ++static SENSOR_DEVICE_ATTR(low_norm_trigger_interval, 0644, ++ applesmc_accelerometer_show, applesmc_accelerometer_store, 0); ++static SENSOR_DEVICE_ATTR(high_norm_trigger_interval, 0644, ++ applesmc_accelerometer_show, applesmc_accelerometer_store, 1); ++static SENSOR_DEVICE_ATTR(low_norm_trigger, 0644, ++ applesmc_accelerometer_show, applesmc_accelerometer_store, 2); ++static SENSOR_DEVICE_ATTR(high_norm_trigger, 0644, ++ applesmc_accelerometer_show, applesmc_accelerometer_store, 3); + + static struct attribute *accelerometer_attributes[] = { + &dev_attr_position.attr, + &dev_attr_calibrate.attr, ++ &sensor_dev_attr_low_norm_trigger.dev_attr.attr, ++ &sensor_dev_attr_high_norm_trigger.dev_attr.attr, ++ &sensor_dev_attr_low_norm_trigger_interval.dev_attr.attr, ++ &sensor_dev_attr_high_norm_trigger_interval.dev_attr.attr, + NULL + }; + Added: trunk/kernel/mactel-patches-2.6.22/appletouch.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.22/appletouch.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/appletouch.patch 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,23 @@ +Appletouch driver ATP_THRESHOLD fix. + +From: Ortwin Glück <[EMAIL PROTECTED]> + + +--- + + drivers/input/mouse/appletouch.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c +index e321526..c26af96 100644 +--- a/drivers/input/mouse/appletouch.c ++++ b/drivers/input/mouse/appletouch.c +@@ -127,7 +127,7 @@ MODULE_DEVICE_TABLE (usb, atp_table); + * Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is + * ignored. + */ +-#define ATP_THRESHOLD 5 ++#define ATP_THRESHOLD 3 + + /* MacBook Pro (Geyser 3 & 4) initialization constants */ + #define ATP_GEYSER3_MODE_READ_REQUEST_ID 1 Added: trunk/kernel/mactel-patches-2.6.22/apply =================================================================== --- trunk/kernel/mactel-patches-2.6.22/apply (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/apply 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,36 @@ +#!/bin/sh + +if [ "$1" == "" ]; then + echo "usage ./apply kerneldir" + exit 0 +fi + +WORK=$PWD + +APPLIED="" + +cd $1 + +for i in `cat $WORK/series | grep -v "#"` +do + patch -p1 --dry-run < $WORK/$i > /dev/null + if [ "$?" != "0" ]; then + echo -n "$i" | sed -e "s/.*\/\(.*\)$/\1/" + echo " would not apply cleanly" + for j in $APPLIED + do + echo "$j" | sed -e "s/.*\/\(.*\)$/Reversing \1.../" + patch -s -R -p1 < $WORK/$j + done + exit + fi + echo "$i" | sed -e "s/.*\/\(.*\)$/Applying \1.../" + patch -s -p1 < $WORK/$i + APPLIED="$i $APPLIED" +done + +grep "^EXTRAVERSION *=.*-mactel$" Makefile > /dev/null +if [ $? != 0 ]; then + echo "changing version in Makefile" + sed -i Makefile -e "s/^\(EXTRAVERSION *=.*\)$/\1-mactel/" +fi Property changes on: trunk/kernel/mactel-patches-2.6.22/apply ___________________________________________________________________ Name: svn:executable + * Added: trunk/kernel/mactel-patches-2.6.22/series =================================================================== --- trunk/kernel/mactel-patches-2.6.22/series (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/series 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,6 @@ +# This series applies on GIT commit c420bc9f09a0926b708c3edb27eacba434a4f4ba +applesmc_add_name.patch +applesmc-use-input-polldev.patch +applesmc_int.patch +appletouch.patch +appleir.patch Added: trunk/kernel/mactel-patches-2.6.22/unapply =================================================================== --- trunk/kernel/mactel-patches-2.6.22/unapply (rev 0) +++ trunk/kernel/mactel-patches-2.6.22/unapply 2007-05-26 22:33:14 UTC (rev 125) @@ -0,0 +1,39 @@ +#!/bin/sh + +if [ "$1" == "" ]; then + echo "usage ./unapply kerneldir" + exit 0 +fi + +WORK=$PWD + +REVERSED="" + +cd $1 + +LIST="" +for i in `cat $WORK/series | grep -v "#"` +do + LIST="$i $LIST" +done + +for i in $LIST +do + patch -R -p1 --dry-run < $WORK/$i > /dev/null + if [ "$?" != "0" ]; then + echo -n "$i" | sed -e "s/.*\/\(.*\)$/\1/" + echo " would not reverse cleanly" + for j in $REVERSED + do + echo "$j" | sed -e "s/.*\/\(.*\)$/Applying \1.../" + patch -s -p1 < $WORK/$j + done + exit + fi + echo "$i" | sed -e "s/.*\/\(.*\)$/Reversing \1.../" + patch -s -R -p1 < $WORK/$i + REVERSED="$i $REVERSED" +done + +echo "changing version in Makefile" +sed -i Makefile -e "s/^\(EXTRAVERSION *=.*\)-mactel$/\1/" Property changes on: trunk/kernel/mactel-patches-2.6.22/unapply ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- 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/ _______________________________________________ Mactel-linux-devel mailing list Mactel-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel