vserver 1.9.5.x5
[linux-2.6.git] / drivers / i2c / chips / lm83.c
index f50e934..552321e 100644 (file)
  * addresses.
  */
 
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { 0x18, 0x1a, 0x29, 0x2b,
-       0x4c, 0x4e, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+                                       0x29, 0x2a, 0x2b,
+                                       0x4c, 0x4d, 0x4e,
+                                       I2C_CLIENT_END };
 static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
 
 /*
  * Insmod parameters
@@ -80,11 +80,14 @@ SENSORS_INSMOD_1(lm83);
 
 /*
  * Conversions and various macros
- * The LM83 uses signed 8-bit values.
+ * The LM83 uses signed 8-bit values with LSB = 1 degree Celcius.
  */
 
-#define TEMP_FROM_REG(val)     ((val > 127 ? val-256 : val) * 1000)
-#define TEMP_TO_REG(val)       ((val < 0 ? val+256 : val) / 1000)
+#define TEMP_FROM_REG(val)     ((val) * 1000)
+#define TEMP_TO_REG(val)       ((val) <= -128000 ? -128 : \
+                                (val) >= 127000 ? 127 : \
+                                (val) < 0 ? ((val) - 500) / 1000 : \
+                                ((val) + 500) / 1000)
 
 static const u8 LM83_REG_R_TEMP[] = {
        LM83_REG_R_LOCAL_TEMP,
@@ -140,9 +143,9 @@ struct lm83_data {
        unsigned long last_updated; /* in jiffies */
 
        /* registers values */
-       u8 temp_input[4];
-       u8 temp_high[4];
-       u8 temp_crit;
+       s8 temp_input[4];
+       s8 temp_high[4];
+       s8 temp_crit;
        u16 alarms; /* bitvector, combined */
 };
 
@@ -150,7 +153,7 @@ struct lm83_data {
  * Internal variables
  */
 
-static int lm83_id = 0;
+static int lm83_id;
 
 /*
  * Sysfs stuff
@@ -178,7 +181,8 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \
 { \
        struct i2c_client *client = to_i2c_client(dev); \
        struct lm83_data *data = i2c_get_clientdata(client); \
-       data->value = TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
+       long val = simple_strtol(buf, NULL, 10); \
+       data->value = TEMP_TO_REG(val); \
        i2c_smbus_write_byte_data(client, reg, data->value); \
        return count; \
 }
@@ -206,8 +210,11 @@ static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_high3,
     set_temp_high3);
 static DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_high4,
     set_temp_high4);
-static DEVICE_ATTR(temp_crit, S_IWUSR | S_IRUGO, show_temp_crit,
+static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL);
+static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL);
+static DEVICE_ATTR(temp3_crit, S_IWUSR | S_IRUGO, show_temp_crit,
     set_temp_crit);
+static DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL);
 static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
 /*
@@ -216,7 +223,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
 
 static int lm83_attach_adapter(struct i2c_adapter *adapter)
 {
-       if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
+       if (!(adapter->class & I2C_CLASS_HWMON))
                return 0;
        return i2c_detect(adapter, &addr_data, lm83_detect);
 }
@@ -259,6 +266,11 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
         * means that the driver was loaded with the force parameter and a
         * given kind of chip is requested, so both the detection and the
         * identification steps are skipped. */
+
+       /* Default to an LM83 if forced */
+       if (kind == 0)
+               kind = lm83;
+
        if (kind < 0) { /* detection */
                if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1)
                    & 0xA8) != 0x00) ||
@@ -322,7 +334,10 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
        device_create_file(&new_client->dev, &dev_attr_temp2_max);
        device_create_file(&new_client->dev, &dev_attr_temp3_max);
        device_create_file(&new_client->dev, &dev_attr_temp4_max);
-       device_create_file(&new_client->dev, &dev_attr_temp_crit);
+       device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+       device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+       device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+       device_create_file(&new_client->dev, &dev_attr_temp4_crit);
        device_create_file(&new_client->dev, &dev_attr_alarms);
 
        return 0;