hwmon/lm90: Add support for the Maxim MAX6680/MAX6681

Signed-off-by: Rainer Birkenmaier <rainer.birkenmaier@siemens.com>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 24b3b0e..5771130 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -43,6 +43,13 @@
  * 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
@@ -84,20 +91,25 @@
 /*
  * 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 @@
 		 		  &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 @@
 				}
 			}
 		} 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 @@
 		} 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 @@
 		name = "lm86";
 	} else if (kind == max6657) {
 		name = "max6657";
+	} else if (kind == max6680) {
+		name = "max6680";
 	} else if (kind == adt7461) {
 		name = "adt7461";
 	}
@@ -646,7 +674,8 @@
 
 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 @@
 		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)