]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
hwmon/lm90: Add support for the Maxim MAX6680/MAX6681
authorRainer Birkenmaier <rainer.birkenmaier@siemens.com>
Sat, 9 Jun 2007 14:11:16 +0000 (10:11 -0400)
committerMark M. Hoffman <mhoffman@lightlink.com>
Thu, 19 Jul 2007 18:22:12 +0000 (14:22 -0400)
Signed-off-by: Rainer Birkenmaier <rainer.birkenmaier@siemens.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Documentation/hwmon/lm90
drivers/hwmon/Kconfig
drivers/hwmon/lm90.c

index ba3e94b7117b9f5e790f25558822b405e6aca6c5..aa4a0ec20081bedc6257dac8cee864cbed54faf2 100644 (file)
@@ -48,6 +48,18 @@ Supported chips:
     Addresses scanned: I2C 0x4c, 0x4d (unsupported 0x4e)
     Datasheet: Publicly available at the Maxim website
                http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+  * Maxim MAX6680
+    Prefix: 'max6680'
+    Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
+                           0x4c, 0x4d and 0x4e
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
+  * Maxim MAX6681
+    Prefix: 'max6680'
+    Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
+                           0x4c, 0x4d and 0x4e
+    Datasheet: Publicly available at the Maxim website
+               http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
 
 
 Author: Jean Delvare <khali@linux-fr.org>
@@ -59,11 +71,15 @@ Description
 The LM90 is a digital temperature sensor. It senses its own temperature as
 well as the temperature of up to one external diode. It is compatible
 with many other devices such as the LM86, the LM89, the LM99, the ADM1032,
-the MAX6657, MAX6658 and the MAX6659 all of which are supported by this driver.
-Note that there is no easy way to differentiate between the last three
-variants. The extra address and features of the MAX6659 are not supported by
-this driver. Additionally, the ADT7461 is supported if found in ADM1032
-compatibility mode.
+the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are
+supported by this driver.
+
+Note that there is no easy way to differentiate between the MAX6657,
+MAX6658 and MAX6659 variants. The extra address and features of the
+MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only
+differ in their pinout, therefore they obviously can't (and don't need to)
+be distinguished. Additionally, the ADT7461 is supported if found in
+ADM1032 compatibility mode.
 
 The specificity of this family of chipsets over the ADM1021/LM84
 family is that it features critical limits with hysteresis, and an
@@ -93,18 +109,22 @@ ADM1032:
   * ALERT is triggered by open remote sensor.
   * SMBus PEC support for Write Byte and Receive Byte transactions.
 
-ADT7461
+ADT7461:
   * Extended temperature range (breaks compatibility)
   * Lower resolution for remote temperature
 
 MAX6657 and MAX6658:
   * Remote sensor type selection
 
-MAX6659
+MAX6659:
   * Selectable address
   * Second critical temperature limit
   * Remote sensor type selection
 
+MAX6680 and MAX6681:
+  * Selectable address
+  * Remote sensor type selection
+
 All temperature values are given in degrees Celsius. Resolution
 is 1.0 degree for the local temperature, 0.125 degree for the remote
 temperature.
index 1d9be07c3c1dbb21b2dbe63ccdf62b0f84aaeccd..d1c6be9e2bad61bfe2374844c26a2a4e6b8446e0 100644 (file)
@@ -365,8 +365,8 @@ config SENSORS_LM90
        depends on I2C
        help
          If you say yes here you get support for National Semiconductor LM90,
-         LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and
-         MAX6658 sensor chips.
+         LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657,
+         MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips.
 
          The Analog Devices ADT7461 sensor chip is also supported, but only
          if found in ADM1032 compatibility mode.
index 24b3b0e97537092d702909c42bd9adf9840db8d1..5771130f51ff4df043bb3078836cd643faa46ad2 100644 (file)
  * variants. The extra address and features of the MAX6659 are not
  * supported by this driver.
  *
+ * This driver also supports the MAX6680 and MAX6681, two other sensor
+ * chips made by Maxim. These are quite similar to the other Maxim
+ * chips. Complete datasheet can be obtained at:
+ *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
+ * The MAX6680 and MAX6681 only differ in the pinout so they can be
+ * treated identically.
+ *
  * This driver also supports the ADT7461 chip from Analog Devices but
  * only in its "compatability mode". If an ADT7461 chip is found but
  * is configured in non-compatible mode (where its temperature
 /*
  * Addresses to scan
  * Address is fully defined internally and cannot be changed except for
- * MAX6659.
+ * MAX6659, MAX6680 and MAX6681.
  * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
  * have address 0x4c.
  * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
  * MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
+ * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
+ * 0x4c, 0x4d or 0x4e.
  */
 
-static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
+                                      0x29, 0x2a, 0x2b,
+                                      0x4c, 0x4d, 0x4e,
+                                      I2C_CLIENT_END };
 
 /*
  * Insmod parameters
  */
 
-I2C_CLIENT_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
+I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
 
 /*
  * The LM90 registers
@@ -525,7 +537,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
                                  &reg_convrate) < 0)
                        goto exit_free;
                
-               if (man_id == 0x01) { /* National Semiconductor */
+               if ((address == 0x4C || address == 0x4D)
+                && man_id == 0x01) { /* National Semiconductor */
                        u8 reg_config2;
 
                        if (lm90_read_reg(new_client, LM90_REG_R_CONFIG2,
@@ -548,7 +561,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
                                }
                        }
                } else
-               if (man_id == 0x41) { /* Analog Devices */
+               if ((address == 0x4C || address == 0x4D)
+                && man_id == 0x41) { /* Analog Devices */
                        if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
                         && (reg_config1 & 0x3F) == 0x00
                         && reg_convrate <= 0x0A) {
@@ -562,18 +576,30 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
                } else
                if (man_id == 0x4D) { /* Maxim */
                        /*
-                        * The Maxim variants do NOT have a chip_id register.
-                        * Reading from that address will return the last read
-                        * value, which in our case is those of the man_id
-                        * register. Likewise, the config1 register seems to
-                        * lack a low nibble, so the value will be those of the
-                        * previous read, so in our case those of the man_id
-                        * register.
+                        * The MAX6657, MAX6658 and MAX6659 do NOT have a
+                        * chip_id register. Reading from that address will
+                        * return the last read value, which in our case is
+                        * those of the man_id register. Likewise, the config1
+                        * register seems to lack a low nibble, so the value
+                        * will be those of the previous read, so in our case
+                        * those of the man_id register.
                         */
                        if (chip_id == man_id
+                        && (address == 0x4F || address == 0x4D)
                         && (reg_config1 & 0x1F) == (man_id & 0x0F)
                         && reg_convrate <= 0x09) {
                                kind = max6657;
+                       } else
+                       /* The chip_id register of the MAX6680 and MAX6681
+                        * holds the revision of the chip.
+                        * the lowest bit of the config1 register is unused
+                        * and should return zero when read, so should the
+                        * second to last bit of config1 (software reset)
+                        */
+                       if (chip_id == 0x01
+                        && (reg_config1 & 0x03) == 0x00
+                        && reg_convrate <= 0x07) {
+                               kind = max6680;
                        }
                }
 
@@ -599,6 +625,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
                name = "lm86";
        } else if (kind == max6657) {
                name = "max6657";
+       } else if (kind == max6680) {
+               name = "max6680";
        } else if (kind == adt7461) {
                name = "adt7461";
        }
@@ -646,7 +674,8 @@ exit:
 
 static void lm90_init_client(struct i2c_client *client)
 {
-       u8 config;
+       u8 config, config_orig;
+       struct lm90_data *data = i2c_get_clientdata(client);
 
        /*
         * Start the conversions.
@@ -657,9 +686,20 @@ static void lm90_init_client(struct i2c_client *client)
                dev_warn(&client->dev, "Initialization failed!\n");
                return;
        }
-       if (config & 0x40)
-               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
-                                         config & 0xBF); /* run */
+       config_orig = config;
+
+       /*
+        * Put MAX6680/MAX8881 into extended resolution (bit 0x10,
+        * 0.125 degree resolution) and range (0x08, extend range
+        * to -64 degree) mode for the remote temperature sensor.
+        */
+       if (data->kind == max6680) {
+               config |= 0x18;
+       }
+
+       config &= 0xBF; /* run */
+       if (config != config_orig) /* Only write if changed */
+               i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
 }
 
 static int lm90_detach_client(struct i2c_client *client)