Revision: 102 http://svn.sourceforge.net/mactel-linux/?rev=102&view=rev Author: nboichat Date: 2007-04-09 03:54:35 -0700 (Mon, 09 Apr 2007)
Log Message: ----------- New features for applesmc: 1. Add support for keys enumeration. 2. IRQ support for the accelerometer. 3. Add more temperature sensors on the Macbook Pro. 4. Add fan description reading. Added Paths: ----------- trunk/kernel/mactel-patches-2.6.21/0011-applesmc2.patch Added: trunk/kernel/mactel-patches-2.6.21/0011-applesmc2.patch =================================================================== --- trunk/kernel/mactel-patches-2.6.21/0011-applesmc2.patch (rev 0) +++ trunk/kernel/mactel-patches-2.6.21/0011-applesmc2.patch 2007-04-09 10:54:35 UTC (rev 102) @@ -0,0 +1,652 @@ +New features for applesmc: 1. Add support for keys enumeration. 2. IRQ support for the accelerometer. 3. Add more temperature sensors on the Macbook Pro. 4. Add fan description reading. + +From: Nicolas Boichat <[EMAIL PROTECTED]> + + +--- + + drivers/hwmon/applesmc.c | 471 ++++++++++++++++++++++++++++++++++++++++------ + 1 files changed, 410 insertions(+), 61 deletions(-) + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index 581ed3e..c68391d 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -37,40 +37,71 @@ + #include <linux/hwmon-sysfs.h> + #include <asm/io.h> + #include <linux/leds.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 ++/* 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 5 /* 0x300-0x304 */ ++#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ + +-#define APPLESMC_STATUS_MASK 0x0f +-#define APPLESMC_READ_CMD 0x10 +-#define APPLESMC_WRITE_CMD 0x11 ++#define APPLESMC_MAX_DATA_LENGTH 32 ++ ++/* Defined in ACPI DSDT table, should we read it from there? */ ++#define APPLESMC_IRQ 6 ++ ++#define APPLESMC_STATUS_MASK 0x0f ++#define APPLESMC_READ_CMD 0x10 ++#define APPLESMC_WRITE_CMD 0x11 ++#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 ++#define APPLESMC_GET_KEY_INFO_CMD 0x13 ++ ++#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ ++ ++#define INTERRUPT_OK_KEY "NTOK" /* w-o ui8 */ + + #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o length 6 */ + #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o length 6 */ +-#define BACKLIGHT_KEY "LKSB" /* w-o */ ++#define BACKLIGHT_KEY "LKSB" /* w-o length 2 */ ++ ++#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) */ ++#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */ ++#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */ + +-#define CLAMSHELL_KEY "MSLD" /* r-o length 1 (unused) */ ++/* Interrupt controls. */ ++/* Don't know what these parameters control. */ ++#define MOTION_SENSOR_PARAM_1L "MOLD" /* r/w ui8 */ ++#define MOTION_SENSOR_PARAM_1H "MOHD" /* r/w ui8 */ + +-#define MOTION_SENSOR_X_KEY "MO_X" /* r-o length 2 */ +-#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o length 2 */ +-#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o length 2 */ +-#define MOTION_SENSOR_KEY "MOCN" /* r/w length 2 */ ++/* ++ * 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), SMC will trigger ++ * an interrupt. ++ */ ++#define MOTION_MIN_NORM "MOLT" /* r/w sp78 (2 bytes) */ ++#define MOTION_MAX_NORM "MOHT" /* r/w sp78 (2 bytes) */ ++ ++#define MSDW_KEY "MSDW" /* r/w flag (1 byte) */ + +-#define FANS_COUNT "FNum" /* r-o length 1 */ +-#define FANS_MANUAL "FS! " /* r-w length 2 */ +-#define FAN_ACTUAL_SPEED "F0Ac" /* r-o length 2 */ +-#define FAN_MIN_SPEED "F0Mn" /* r-o length 2 */ +-#define FAN_MAX_SPEED "F0Mx" /* r-o length 2 */ +-#define FAN_SAFE_SPEED "F0Sf" /* r-o length 2 */ +-#define FAN_TARGET_SPEED "F0Tg" /* r-w length 2 */ ++#define FANS_COUNT "FNum" /* r-o ui8 */ ++#define FANS_MANUAL "FS! " /* r-w ui16 */ ++#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 */ ++#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 */ ++#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 */ ++#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 */ ++#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 */ ++#define FAN_ID "F0ID" /* r-o char[16] */ + + /* Temperature sensors keys. First set for Macbook(Pro), second for Macmini */ +-static const char* temperature_sensors_sets[][8] = { +- { "TB0T", "TC0D", "TC0P", "Th0H", "Ts0P", "Th1H", "Ts1P", NULL }, ++static const char* temperature_sensors_sets[][13] = { ++ { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", ++ "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, + { "TC0D", "TC0P", NULL } + }; + +@@ -122,6 +153,9 @@ static unsigned int applesmc_temperature_set; + + static struct mutex applesmc_lock; + ++/* Last index written to key_at_index sysfs file. */ ++static unsigned int key_at_index; ++ + /* + * __wait_status - Wait up to 100ms for the status port to get a certain value + * (masked with 0x0f), returning zero if the value is obtained. Callers must +@@ -152,17 +186,22 @@ static int __wait_status(u8 val) + */ + static int applesmc_read_key(const char* key, u8* buffer, u8 len) + { +- int ret = -EIO; + int i; + ++ if (len > APPLESMC_MAX_DATA_LENGTH) { ++ printk(KERN_ERR "applesmc_read_key: cannot read more than " ++ APPLESMC_MAX_DATA_LENGTH " bytes"); ++ return -EINVAL; ++ } ++ + outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); + if (__wait_status(0x0c)) +- goto out; ++ return -EIO; + + for (i = 0; i < 4; i++) { + outb(key[i], APPLESMC_DATA_PORT); + if (__wait_status(0x04)) +- goto out; ++ return -EIO; + } + if (debug) + printk(KERN_DEBUG "<%s", key); +@@ -173,7 +212,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) + + for (i = 0; i < len; i++) { + if (__wait_status(0x05)) +- goto out; ++ return -EIO; + buffer[i] = inb(APPLESMC_DATA_PORT); + if (debug) + printk(KERN_DEBUG "<%x", buffer[i]); +@@ -181,10 +220,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) + if (debug) + printk(KERN_DEBUG "\n"); + +- ret = 0; +- +-out: +- return ret; ++ return 0; + } + + /* +@@ -194,30 +230,100 @@ out: + */ + static int applesmc_write_key(const char* key, u8* buffer, u8 len) + { +- int ret = -EIO; + int i; + ++ if (len > APPLESMC_MAX_DATA_LENGTH) { ++ printk(KERN_ERR "applesmc_write_key: cannot write more than " ++ APPLESMC_MAX_DATA_LENGTH " bytes"); ++ return -EINVAL; ++ } ++ + outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); + if (__wait_status(0x0c)) +- goto out; ++ return -EIO; + + for (i = 0; i < 4; i++) { + outb(key[i], APPLESMC_DATA_PORT); + if (__wait_status(0x04)) +- goto out; ++ return -EIO; + } + + outb(len, APPLESMC_DATA_PORT); + + for (i = 0; i < len; i++) { + if (__wait_status(0x04)) +- goto out; ++ return -EIO; + outb(buffer[i], APPLESMC_DATA_PORT); + } + +- ret = 0; +-out: +- return ret; ++ return 0; ++} ++ ++/* ++ * applesmc_get_key_at_index - get key at index, and put the result in key. ++ * Returns zero on success or a negative error on failure. Callers must ++ * hold applesmc_lock. ++ */ ++static int applesmc_get_key_at_index(int index, char* key) ++{ ++ int i; ++ u8 readkey[4]; ++ readkey[0] = index >> 24; ++ readkey[1] = index >> 16; ++ readkey[2] = index >> 8; ++ readkey[3] = index; ++ ++ outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); ++ if (__wait_status(0x0c)) ++ return -EIO; ++ ++ for (i = 0; i < 4; i++) { ++ outb(readkey[i], APPLESMC_DATA_PORT); ++ if (__wait_status(0x04)) ++ return -EIO; ++ } ++ ++ outb(4, APPLESMC_DATA_PORT); ++ ++ for (i = 0; i < 4; i++) { ++ if (__wait_status(0x05)) ++ return -EIO; ++ key[i] = inb(APPLESMC_DATA_PORT); ++ } ++ key[4] = 0; ++ ++ return 0; ++} ++ ++/* ++ * applesmc_get_key_info - get key info, and put the result in info (char[6]). ++ * Returns zero on success or a negative error on failure. Callers must ++ * hold applesmc_lock. ++ */ ++static int applesmc_get_key_info(char* key, char* info) ++{ ++ int i; ++ ++ outb(APPLESMC_GET_KEY_INFO_CMD, APPLESMC_CMD_PORT); ++ if (__wait_status(0x0c)) ++ return -EIO; ++ ++ for (i = 0; i < 4; i++) { ++ outb(key[i], APPLESMC_DATA_PORT); ++ if (__wait_status(0x04)) ++ return -EIO; ++ } ++ ++ outb(5, APPLESMC_DATA_PORT); ++ ++ for (i = 0; i < 6; i++) { ++ if (__wait_status(0x05)) ++ return -EIO; ++ info[i] = inb(APPLESMC_DATA_PORT); ++ } ++ info[5] = 0; ++ ++ return 0; + } + + /* +@@ -249,12 +355,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 " ++ APPLESMC_MAX_DATA_LENGTH " bytes"); ++ 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_NONE; ++} ++ ++/* + * 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) +@@ -262,32 +435,76 @@ 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] = 0x14; ++ ret1 = applesmc_init_check_key_value(MOTION_SENSOR_PARAM_1L, buffer, 1); ++ ++ buffer[0] = 0x14; ++ ret2 = applesmc_init_check_key_value(MOTION_SENSOR_PARAM_1H, buffer, 1); ++ ++ if (ret1 || ret2) { ++ printk(KERN_WARNING "applesmc: Cannot set motion sensor " ++ "parameter 1, might not receive some interrupts."); ++ } ++ ++ buffer[0] = 0x00; ++ buffer[1] = 0x60; ++ ret1 = applesmc_init_check_key_value(MOTION_MIN_NORM, buffer, 2); ++ ++ buffer[0] = 0x01; ++ buffer[1] = 0xc0; ++ ret2 = applesmc_init_check_key_value(MOTION_MAX_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); +@@ -332,9 +549,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, +@@ -575,6 +799,33 @@ out: + return count; + } + ++static ssize_t applesmc_show_fan_id(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ int ret; ++ char newkey[5]; ++ u8 buffer[17]; ++ struct sensor_device_attribute_2 *sensor_attr = ++ to_sensor_dev_attr_2(attr); ++ ++ newkey[0] = FAN_ID[0]; ++ newkey[1] = '0' + sensor_attr->index; ++ newkey[2] = FAN_ID[2]; ++ newkey[3] = FAN_ID[3]; ++ newkey[4] = 0; ++ ++ mutex_lock(&applesmc_lock); ++ ++ ret = applesmc_read_key(newkey, buffer, 16); ++ buffer[16] = 0; ++ ++ mutex_unlock(&applesmc_lock); ++ if (ret) ++ return ret; ++ else ++ return sprintf(sysfsbuf, "%s\n", buffer+4); ++} ++ + static ssize_t applesmc_calibrate_show(struct device *dev, + struct device_attribute *attr, char *sysfsbuf) + { +@@ -591,6 +842,77 @@ static ssize_t applesmc_calibrate_store(struct device *dev, + return count; + } + ++static ssize_t applesmc_key_count_show(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ int ret; ++ u8 buffer[4]; ++ u32 count; ++ ++ mutex_lock(&applesmc_lock); ++ ++ ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); ++ count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + ++ ((u32)buffer[2]<<8) + buffer[3]; ++ ++ mutex_unlock(&applesmc_lock); ++ if (ret) ++ return ret; ++ else ++ return sprintf(sysfsbuf, "%d\n", count); ++} ++ ++static ssize_t applesmc_key_at_index_show(struct device *dev, ++ struct device_attribute *attr, char *sysfsbuf) ++{ ++ char key[5]; ++ char info[6]; ++ u8 buffer[APPLESMC_MAX_DATA_LENGTH]; ++ char outbuffer[256]; ++ int ret, ret2; ++ int i; ++ ++ outbuffer[0] = 0; ++ ++ mutex_lock(&applesmc_lock); ++ ++ ret = applesmc_get_key_at_index(key_at_index, key); ++ ++ if (!ret && key[0]) { ++ applesmc_get_key_info(key, info); ++ ++ printk("Reading %s len %d.\n", key, info[0]); ++ ret2 = applesmc_read_key(key, buffer, info[0]); ++ printk("Ret %d, buf[0]=%x.\n", ret2, buffer[0]); ++ if (!ret2) { ++ for (i = 0; i < info[0]; i++) { ++ printk("buffer[%d]=%02x\n", i, buffer[i]); ++ sprintf(outbuffer+(i*2), "%02x", buffer[i]); ++ } ++ outbuffer[info[0]*2] = 0; ++ } ++ } ++ ++ mutex_unlock(&applesmc_lock); ++ ++ if (!ret && key[0]) ++ return sprintf(sysfsbuf, "%d: %s [%d:%s] - %s\n", key_at_index, key, info[0], info+1, outbuffer); ++ else ++ return sprintf(sysfsbuf, "%d=invalid\n", key_at_index); ++} ++ ++static ssize_t applesmc_key_at_index_store(struct device *dev, ++ struct device_attribute *attr, const char *sysfsbuf, size_t count) ++{ ++ mutex_lock(&applesmc_lock); ++ ++ key_at_index = simple_strtoul(sysfsbuf, NULL, 10); ++ ++ mutex_unlock(&applesmc_lock); ++ ++ return count; ++} ++ + static void applesmc_backlight_set(struct led_classdev *led_cdev, + enum led_brightness value) + { +@@ -615,6 +937,9 @@ static DEVICE_ATTR(calibrate, 0644, + + static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); + ++static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL); ++static DEVICE_ATTR(key_at_index, 0600, applesmc_key_at_index_show, applesmc_key_at_index_store); ++ + /* + * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries. + * - show actual speed +@@ -643,6 +968,9 @@ static SENSOR_DEVICE_ATTR_2(fan##offset##_target_speed, S_IRUGO | S_IWUSR, \ + static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \ + applesmc_show_fan_manual, applesmc_store_fan_manual, offset); \ + \ ++static SENSOR_DEVICE_ATTR(fan##offset##_id, S_IRUGO, \ ++ applesmc_show_fan_id, NULL, offset); \ ++\ + static struct attribute *fan##offset##_attributes[] = { \ + &sensor_dev_attr_fan##offset##_actual_speed.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_minimum_speed.dev_attr.attr, \ +@@ -650,6 +978,7 @@ static struct attribute *fan##offset##_attributes[] = { \ + &sensor_dev_attr_fan##offset##_safe_speed.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_target_speed.dev_attr.attr, \ + &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \ ++ &sensor_dev_attr_fan##offset##_id.dev_attr.attr, \ + NULL \ + }; + +@@ -682,6 +1011,16 @@ static SENSOR_DEVICE_ATTR(temperature_5, S_IRUGO, + applesmc_show_temperature, NULL, 5); + static SENSOR_DEVICE_ATTR(temperature_6, S_IRUGO, + applesmc_show_temperature, NULL, 6); ++static SENSOR_DEVICE_ATTR(temperature_7, S_IRUGO, ++ applesmc_show_temperature, NULL, 7); ++static SENSOR_DEVICE_ATTR(temperature_8, S_IRUGO, ++ applesmc_show_temperature, NULL, 8); ++static SENSOR_DEVICE_ATTR(temperature_9, S_IRUGO, ++ applesmc_show_temperature, NULL, 9); ++static SENSOR_DEVICE_ATTR(temperature_10, S_IRUGO, ++ applesmc_show_temperature, NULL, 10); ++static SENSOR_DEVICE_ATTR(temperature_11, S_IRUGO, ++ applesmc_show_temperature, NULL, 11); + + static struct attribute *temperature_attributes[] = { + &sensor_dev_attr_temperature_0.dev_attr.attr, +@@ -691,6 +1030,11 @@ static struct attribute *temperature_attributes[] = { + &sensor_dev_attr_temperature_4.dev_attr.attr, + &sensor_dev_attr_temperature_5.dev_attr.attr, + &sensor_dev_attr_temperature_6.dev_attr.attr, ++ &sensor_dev_attr_temperature_7.dev_attr.attr, ++ &sensor_dev_attr_temperature_8.dev_attr.attr, ++ &sensor_dev_attr_temperature_9.dev_attr.attr, ++ &sensor_dev_attr_temperature_10.dev_attr.attr, ++ &sensor_dev_attr_temperature_11.dev_attr.attr, + }; + + /* Module stuff */ +@@ -881,6 +1225,11 @@ static int __init applesmc_init(void) + goto out_accelerometer; + } + ++ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_key_count.attr); ++ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_key_at_index.attr); ++ if (ret) ++ goto out_accelerometer; ++ + printk(KERN_INFO "applesmc: driver successfully loaded.\n"); + return 0; + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys-and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Mactel-linux-devel mailing list Mactel-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel