Revision: 49
          http://svn.sourceforge.net/mactel-linux/?rev=49&view=rev
Author:   nboichat
Date:     2006-10-15 00:33:49 -0700 (Sun, 15 Oct 2006)

Log Message:
-----------
Add fan control to applesmc.

Modified Paths:
--------------
    trunk/kernel/mactel-patches-2.6.18/applesmc.patch

Modified: trunk/kernel/mactel-patches-2.6.18/applesmc.patch
===================================================================
--- trunk/kernel/mactel-patches-2.6.18/applesmc.patch   2006-10-14 05:24:47 UTC 
(rev 48)
+++ trunk/kernel/mactel-patches-2.6.18/applesmc.patch   2006-10-15 07:33:49 UTC 
(rev 49)
@@ -41,17 +41,20 @@
  obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
 diff -pruN linux-2.6.18/drivers/hwmon.vanilla/applesmc.c 
linux-2.6.18/drivers/hwmon/applesmc.c
 --- linux-2.6.18/drivers/hwmon.vanilla/applesmc.c      1970-01-01 
07:30:00.000000000 +0730
-+++ linux-2.6.18/drivers/hwmon/applesmc.c      2006-10-14 13:09:10.000000000 
+0800
-@@ -0,0 +1,575 @@
++++ linux-2.6.18/drivers/hwmon/applesmc.c      2006-10-15 15:19:30.000000000 
+0800
+@@ -0,0 +1,809 @@
 +/*
 + * drivers/hwmon/applesmc.c - driver for Apple's SMC (various sensors)
 + *
 + * Copyright (C) 2006 Nicolas Boichat <[EMAIL PROTECTED]>
 + *
-+ * Based on hdaps.c driver :
++ * Based on hdaps.c driver:
 + * Copyright (C) 2005 Robert Love <[EMAIL PROTECTED]>
 + * Copyright (C) 2005 Jesper Juhl <[EMAIL PROTECTED]>
 + *
++ * Fan control based on smcFanControl:
++ * Copyright (C) 2006 Hendrik Holtmann <[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.
@@ -87,15 +90,25 @@
 +#define APPLESMC_READ_CMD     0x10
 +#define APPLESMC_WRITE_CMD    0x11
 +
-+#define LIGHT_SENSOR_LEFT_KEY "ALV0" //0x414c5630, r-o length 6
-+#define LIGHT_SENSOR_RIGHT_KEY        "ALV1" //0x414c5631, r-o length 6
-+#define BACKLIGHT_KEY                 "LKSB" //0x4c4b5342, w-o
-+#define CLAMSHELL_KEY                 "MSLD" //0x4d534c44, r-o length 1 
(unused)
-+#define MOTION_SENSOR_X_KEY   "MO_X" //0x4d4f5f58, r-o length 2
-+#define MOTION_SENSOR_Y_KEY   "MO_Y" //0x4d4f5f58, r-o length 2
-+#define MOTION_SENSOR_Z_KEY   "MO_Z" //0x4d4f5f58, r-o length 2
-+#define MOTION_SENSOR_KEY       "MOCN" //0x4d4f434e, r/w length 2
++#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 CLAMSHELL_KEY                 "MSLD" //r-o length 1 (unused)
++
++#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
++
++#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 INIT_TIMEOUT_MSECS    5000    /* wait up to 5s for device init ... */
 +#define INIT_WAIT_MSECS               50      /* ... in 50ms increments */
 +
@@ -117,11 +130,6 @@
 +/* Indicate whether this computer has light sensors and keyboard backlight. */
 +static unsigned int applesmc_light = 0;
 +
-+#if 0
-+static unsigned int hdaps_invert;
-+static u8 km_activity;
-+#endif
-+
 +static DECLARE_MUTEX(applesmc_sem);
 +
 +/*
@@ -287,7 +295,26 @@
 +      return ret;
 +}
 +
++/*
++ * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
++ * applesmc_sem.
++ */
++static int applesmc_get_fan_count(void)
++{
++      int ret;
++      u8 buffer[1];
 +
++      down(&applesmc_sem);
++
++      ret = applesmc_read_key(FANS_COUNT, buffer, 1);
++
++      up(&applesmc_sem);
++      if (ret)
++              return ret;
++      else
++              return buffer[0];
++}
++
 +/* Device model stuff */
 +static int applesmc_probe(struct platform_device *dev)
 +{
@@ -393,15 +420,125 @@
 +              goto out;
 +      ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6);
 +      right = buffer[2];
++
++out:
++      up(&applesmc_sem);
 +      if (ret)
++              return ret;
++      else
++              return sprintf(buf, "(%d,%d)\n", left, right);
++}
++
++static ssize_t applesmc_show_fan_speed(struct device *dev, char *buf,
++                                                      char* key, int offset)
++{
++      int ret;
++      u16 speed = 0;
++      char newkey[5];
++      u8 buffer[2];
++
++      newkey[0] = key[0];
++      newkey[1] = '0' + offset;
++      newkey[2] = key[2];
++      newkey[3] = key[3];
++      newkey[4] = 0;
++
++      down(&applesmc_sem);
++
++      ret = applesmc_read_key(newkey, buffer, 2);
++      speed = (buffer[0] << 8 | buffer[1]) >> 2;
++
++      up(&applesmc_sem);
++      if (ret)
++              return ret;
++      else
++              return sprintf(buf, "%d\n", speed);
++}
++
++static ssize_t applesmc_store_fan_speed(struct device *dev, const char *buf,
++                                      size_t count, char* key, int offset)
++{
++      int ret;
++      u32 speed;
++      char newkey[5];
++      u8 buffer[2];
++
++      speed = simple_strtoul(buf, NULL, 10);
++
++      if (speed > 0x4000) /* Bigger than a 14-bit value */
++              return -EINVAL;
++
++      newkey[0] = key[0];
++      newkey[1] = '0' + offset;
++      newkey[2] = key[2];
++      newkey[3] = key[3];
++      newkey[4] = 0;
++
++      down(&applesmc_sem);
++
++      buffer[0] = (speed >> 6) & 0xff;
++      buffer[1] = (speed << 2) & 0xff;
++      ret = applesmc_write_key(newkey, buffer, 2);
++
++      up(&applesmc_sem);
++      if (ret)
++              return ret;
++      else
++              return count;
++}
++
++static ssize_t applesmc_show_fan_manual(struct device *dev, char *buf,
++                                                              int offset)
++{
++      int ret;
++      u16 manual = 0;
++      u8 buffer[2];
++
++      down(&applesmc_sem);
++
++      ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
++      manual = ((buffer[0] << 8 | buffer[1]) >> offset) & 0x01;
++
++      up(&applesmc_sem);
++      if (ret)
++              return ret;
++      else
++              return sprintf(buf, "%d\n", manual);
++}
++
++static ssize_t applesmc_store_fan_manual(struct device *dev, const char *buf,
++                                              size_t count, int offset)
++{
++      int ret;
++      u8 buffer[2];
++      u32 input;
++      u16 val;
++
++      input = simple_strtoul(buf, NULL, 10);
++
++      down(&applesmc_sem);
++
++      ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
++      val = (buffer[0] << 8 | buffer[1]);
++      if (ret)
 +              goto out;
 +
++      if (input)
++              val = val | (0x01 << offset);
++      else 
++              val = val & ~(0x01 << offset);
++
++      buffer[0] = (val >> 8) & 0xFF;
++      buffer[1] = val & 0xFF;
++
++      ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
++
 +out:
 +      up(&applesmc_sem);
 +      if (ret)
 +              return ret;
 +      else
-+              return sprintf(buf, "(%d,%d)\n", left, right);
++              return count;
 +}
 +
 +static ssize_t applesmc_calibrate_show(struct device *dev,
@@ -464,7 +601,82 @@
 +      .attrs = applesmc_attributes,
 +};
 +
++#define sysfs_fan_speeds_offset(offset) \
++static ssize_t show_fan_actual_speed_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++      return applesmc_show_fan_speed(dev, buf, FAN_ACTUAL_SPEED, offset); \
++} \
++static DEVICE_ATTR(fan##offset##_actual_speed, S_IRUGO, \
++                                      show_fan_actual_speed_##offset, NULL); \
++\
++static ssize_t show_fan_minimum_speed_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++      return applesmc_show_fan_speed(dev, buf, FAN_MIN_SPEED, offset); \
++} \
++static DEVICE_ATTR(fan##offset##_minimum_speed, S_IRUGO, \
++                              show_fan_minimum_speed_##offset, NULL); \
++\
++static ssize_t show_fan_maximum_speed_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++      return applesmc_show_fan_speed(dev, buf, FAN_MAX_SPEED, offset); \
++} \
++static DEVICE_ATTR(fan##offset##_maximum_speed, S_IRUGO, \
++                              show_fan_maximum_speed_##offset, NULL); \
++\
++static ssize_t show_fan_safe_speed_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++      return applesmc_show_fan_speed(dev, buf, FAN_SAFE_SPEED, offset); \
++} \
++static DEVICE_ATTR(fan##offset##_safe_speed, S_IRUGO, \
++                                      show_fan_safe_speed_##offset, NULL); \
++\
++static ssize_t show_fan_target_speed_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++    return applesmc_show_fan_speed(dev, buf, FAN_TARGET_SPEED, offset); \
++} \
++static ssize_t store_fan_target_speed_##offset (struct device *dev, \
++              struct device_attribute *attr, const char *buf, size_t count) \
++{ \
++    return applesmc_store_fan_speed(dev, buf, count, FAN_TARGET_SPEED, 
offset); \
++} \
++static DEVICE_ATTR(fan##offset##_target_speed, S_IRUGO | S_IWUSR, \
++      show_fan_target_speed_##offset, store_fan_target_speed_##offset);
 +
++#define sysfs_fan_manual_offset(offset) \
++static ssize_t show_fan_manual_##offset (struct device *dev, \
++                              struct device_attribute *attr, char *buf) \
++{ \
++    return applesmc_show_fan_manual(dev, buf, offset); \
++} \
++static ssize_t store_fan_manual_##offset (struct device *dev, \
++              struct device_attribute *attr, const char *buf, size_t count) \
++{ \
++    return applesmc_store_fan_manual(dev, buf, count, offset); \
++} \
++static DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
++                 show_fan_manual_##offset, store_fan_manual_##offset);
++
++
++sysfs_fan_speeds_offset(0);
++sysfs_fan_manual_offset(0);
++sysfs_fan_speeds_offset(1);
++sysfs_fan_manual_offset(1);
++
++#define device_create_file_fan(client, offset) \
++do { \
++sysfs_create_file(client, &dev_attr_fan##offset##_actual_speed.attr); \
++sysfs_create_file(client, &dev_attr_fan##offset##_minimum_speed.attr); \
++sysfs_create_file(client, &dev_attr_fan##offset##_maximum_speed.attr); \
++sysfs_create_file(client, &dev_attr_fan##offset##_safe_speed.attr); \
++sysfs_create_file(client, &dev_attr_fan##offset##_target_speed.attr); \
++sysfs_create_file(client, &dev_attr_fan##offset##_manual.attr); \
++} while (0)
++
 +/* Module stuff */
 +
 +/* applesmc_light_dmi_match - found a match.  return one, short-circuiting 
the hunt. */
@@ -545,6 +757,28 @@
 +      if (ret)
 +              goto out_device;
 +
++      /* create fan files */
++      ret = applesmc_get_fan_count();
++      if (ret < 0) {
++              printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
++      }
++      else {
++              printk(KERN_INFO "applesmc: %d fans found.\n", ret);
++
++              switch (ret) {
++              default:
++                      printk(KERN_WARNING "applesmc: More than 2 fans found,"
++                                      " but at most 2 fans are supported"
++                                              " by the driver.\n");
++              case 2:
++                      device_create_file_fan(&pdev->dev.kobj, 1);
++              case 1:
++                      device_create_file_fan(&pdev->dev.kobj, 0);
++              case 0:
++                      ;
++              }
++      }
++
 +      applesmc_idev = input_allocate_device();
 +      if (!applesmc_idev) {
 +              ret = -ENOMEM;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Mactel-linux-devel mailing list
Mactel-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel

Reply via email to