|
@@ -1,7 +1,7 @@
|
|
/*
|
|
/*
|
|
* lm90.c - Part of lm_sensors, Linux kernel modules for hardware
|
|
* lm90.c - Part of lm_sensors, Linux kernel modules for hardware
|
|
* monitoring
|
|
* monitoring
|
|
- * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org>
|
|
|
|
|
|
+ * Copyright (C) 2003-2009 Jean Delvare <khali@linux-fr.org>
|
|
*
|
|
*
|
|
* Based on the lm83 driver. The LM90 is a sensor chip made by National
|
|
* Based on the lm83 driver. The LM90 is a sensor chip made by National
|
|
* Semiconductor. It reports up to two temperatures (its own plus up to
|
|
* Semiconductor. It reports up to two temperatures (its own plus up to
|
|
@@ -661,154 +661,118 @@ static int lm90_detect(struct i2c_client *new_client, int kind,
|
|
{
|
|
{
|
|
struct i2c_adapter *adapter = new_client->adapter;
|
|
struct i2c_adapter *adapter = new_client->adapter;
|
|
int address = new_client->addr;
|
|
int address = new_client->addr;
|
|
- const char *name = "";
|
|
|
|
|
|
+ const char *name = NULL;
|
|
|
|
+ int man_id, chip_id, reg_config1, reg_convrate;
|
|
|
|
|
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
- /*
|
|
|
|
- * Now we do the remaining detection. A negative kind means that
|
|
|
|
- * the driver was loaded with no force parameter (default), so we
|
|
|
|
- * must both detect and identify the chip. A zero kind means that
|
|
|
|
- * the driver was loaded with the force parameter, the detection
|
|
|
|
- * step shall be skipped. A positive 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 LM90 if forced */
|
|
|
|
- if (kind == 0)
|
|
|
|
- kind = lm90;
|
|
|
|
-
|
|
|
|
- if (kind < 0) { /* detection and identification */
|
|
|
|
- int man_id, chip_id, reg_config1, reg_convrate;
|
|
|
|
-
|
|
|
|
- if ((man_id = i2c_smbus_read_byte_data(new_client,
|
|
|
|
|
|
+ /* detection and identification */
|
|
|
|
+ if ((man_id = i2c_smbus_read_byte_data(new_client,
|
|
LM90_REG_R_MAN_ID)) < 0
|
|
LM90_REG_R_MAN_ID)) < 0
|
|
- || (chip_id = i2c_smbus_read_byte_data(new_client,
|
|
|
|
|
|
+ || (chip_id = i2c_smbus_read_byte_data(new_client,
|
|
LM90_REG_R_CHIP_ID)) < 0
|
|
LM90_REG_R_CHIP_ID)) < 0
|
|
- || (reg_config1 = i2c_smbus_read_byte_data(new_client,
|
|
|
|
|
|
+ || (reg_config1 = i2c_smbus_read_byte_data(new_client,
|
|
LM90_REG_R_CONFIG1)) < 0
|
|
LM90_REG_R_CONFIG1)) < 0
|
|
- || (reg_convrate = i2c_smbus_read_byte_data(new_client,
|
|
|
|
|
|
+ || (reg_convrate = i2c_smbus_read_byte_data(new_client,
|
|
LM90_REG_R_CONVRATE)) < 0)
|
|
LM90_REG_R_CONVRATE)) < 0)
|
|
|
|
+ return -ENODEV;
|
|
|
|
+
|
|
|
|
+ if ((address == 0x4C || address == 0x4D)
|
|
|
|
+ && man_id == 0x01) { /* National Semiconductor */
|
|
|
|
+ int reg_config2;
|
|
|
|
+
|
|
|
|
+ reg_config2 = i2c_smbus_read_byte_data(new_client,
|
|
|
|
+ LM90_REG_R_CONFIG2);
|
|
|
|
+ if (reg_config2 < 0)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
-
|
|
|
|
- if ((address == 0x4C || address == 0x4D)
|
|
|
|
- && man_id == 0x01) { /* National Semiconductor */
|
|
|
|
- int reg_config2;
|
|
|
|
-
|
|
|
|
- if ((reg_config2 = i2c_smbus_read_byte_data(new_client,
|
|
|
|
- LM90_REG_R_CONFIG2)) < 0)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- if ((reg_config1 & 0x2A) == 0x00
|
|
|
|
- && (reg_config2 & 0xF8) == 0x00
|
|
|
|
- && reg_convrate <= 0x09) {
|
|
|
|
- if (address == 0x4C
|
|
|
|
- && (chip_id & 0xF0) == 0x20) { /* LM90 */
|
|
|
|
- kind = lm90;
|
|
|
|
- } else
|
|
|
|
- if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
|
|
|
|
- kind = lm99;
|
|
|
|
- dev_info(&adapter->dev,
|
|
|
|
- "Assuming LM99 chip at "
|
|
|
|
- "0x%02x\n", address);
|
|
|
|
- dev_info(&adapter->dev,
|
|
|
|
- "If it is an LM89, pass "
|
|
|
|
- "force_lm86=%d,0x%02x when "
|
|
|
|
- "loading the lm90 driver\n",
|
|
|
|
- i2c_adapter_id(adapter),
|
|
|
|
- address);
|
|
|
|
- } else
|
|
|
|
- if (address == 0x4C
|
|
|
|
- && (chip_id & 0xF0) == 0x10) { /* LM86 */
|
|
|
|
- kind = lm86;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else
|
|
|
|
- if ((address == 0x4C || address == 0x4D)
|
|
|
|
- && man_id == 0x41) { /* Analog Devices */
|
|
|
|
- if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
|
|
|
|
- && (reg_config1 & 0x3F) == 0x00
|
|
|
|
- && reg_convrate <= 0x0A) {
|
|
|
|
- kind = adm1032;
|
|
|
|
- } else
|
|
|
|
- if (chip_id == 0x51 /* ADT7461 */
|
|
|
|
- && (reg_config1 & 0x1B) == 0x00
|
|
|
|
- && reg_convrate <= 0x0A) {
|
|
|
|
- kind = adt7461;
|
|
|
|
- }
|
|
|
|
- } else
|
|
|
|
- if (man_id == 0x4D) { /* Maxim */
|
|
|
|
- /*
|
|
|
|
- * 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 == 0x4C || address == 0x4D)
|
|
|
|
- && (reg_config1 & 0x1F) == (man_id & 0x0F)
|
|
|
|
- && reg_convrate <= 0x09) {
|
|
|
|
- kind = max6657;
|
|
|
|
|
|
+
|
|
|
|
+ if ((reg_config1 & 0x2A) == 0x00
|
|
|
|
+ && (reg_config2 & 0xF8) == 0x00
|
|
|
|
+ && reg_convrate <= 0x09) {
|
|
|
|
+ if (address == 0x4C
|
|
|
|
+ && (chip_id & 0xF0) == 0x20) { /* LM90 */
|
|
|
|
+ name = "lm90";
|
|
} else
|
|
} 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;
|
|
|
|
|
|
+ if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */
|
|
|
|
+ name = "lm99";
|
|
|
|
+ dev_info(&adapter->dev,
|
|
|
|
+ "Assuming LM99 chip at 0x%02x\n",
|
|
|
|
+ address);
|
|
|
|
+ dev_info(&adapter->dev,
|
|
|
|
+ "If it is an LM89, instantiate it "
|
|
|
|
+ "with the new_device sysfs "
|
|
|
|
+ "interface\n");
|
|
} else
|
|
} else
|
|
- /* The chip_id register of the MAX6646/6647/6649
|
|
|
|
- * holds the revision of the chip.
|
|
|
|
- * The lowest 6 bits of the config1 register are
|
|
|
|
- * unused and should return zero when read.
|
|
|
|
- */
|
|
|
|
- if (chip_id == 0x59
|
|
|
|
- && (reg_config1 & 0x3f) == 0x00
|
|
|
|
- && reg_convrate <= 0x07) {
|
|
|
|
- kind = max6646;
|
|
|
|
|
|
+ if (address == 0x4C
|
|
|
|
+ && (chip_id & 0xF0) == 0x10) { /* LM86 */
|
|
|
|
+ name = "lm86";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
- if (kind <= 0) { /* identification failed */
|
|
|
|
- dev_dbg(&adapter->dev,
|
|
|
|
- "Unsupported chip at 0x%02x (man_id=0x%02X, "
|
|
|
|
- "chip_id=0x%02X)\n", address, man_id, chip_id);
|
|
|
|
- return -ENODEV;
|
|
|
|
|
|
+ } else
|
|
|
|
+ if ((address == 0x4C || address == 0x4D)
|
|
|
|
+ && man_id == 0x41) { /* Analog Devices */
|
|
|
|
+ if ((chip_id & 0xF0) == 0x40 /* ADM1032 */
|
|
|
|
+ && (reg_config1 & 0x3F) == 0x00
|
|
|
|
+ && reg_convrate <= 0x0A) {
|
|
|
|
+ name = "adm1032";
|
|
|
|
+ /* The ADM1032 supports PEC, but only if combined
|
|
|
|
+ transactions are not used. */
|
|
|
|
+ if (i2c_check_functionality(adapter,
|
|
|
|
+ I2C_FUNC_SMBUS_BYTE))
|
|
|
|
+ info->flags |= I2C_CLIENT_PEC;
|
|
|
|
+ } else
|
|
|
|
+ if (chip_id == 0x51 /* ADT7461 */
|
|
|
|
+ && (reg_config1 & 0x1B) == 0x00
|
|
|
|
+ && reg_convrate <= 0x0A) {
|
|
|
|
+ name = "adt7461";
|
|
|
|
+ }
|
|
|
|
+ } else
|
|
|
|
+ if (man_id == 0x4D) { /* Maxim */
|
|
|
|
+ /*
|
|
|
|
+ * 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 == 0x4C || address == 0x4D)
|
|
|
|
+ && (reg_config1 & 0x1F) == (man_id & 0x0F)
|
|
|
|
+ && reg_convrate <= 0x09) {
|
|
|
|
+ name = "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) {
|
|
|
|
+ name = "max6680";
|
|
|
|
+ } else
|
|
|
|
+ /*
|
|
|
|
+ * The chip_id register of the MAX6646/6647/6649 holds the
|
|
|
|
+ * revision of the chip. The lowest 6 bits of the config1
|
|
|
|
+ * register are unused and should return zero when read.
|
|
|
|
+ */
|
|
|
|
+ if (chip_id == 0x59
|
|
|
|
+ && (reg_config1 & 0x3f) == 0x00
|
|
|
|
+ && reg_convrate <= 0x07) {
|
|
|
|
+ name = "max6646";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* Fill the i2c board info */
|
|
|
|
- if (kind == lm90) {
|
|
|
|
- name = "lm90";
|
|
|
|
- } else if (kind == adm1032) {
|
|
|
|
- name = "adm1032";
|
|
|
|
- /* The ADM1032 supports PEC, but only if combined
|
|
|
|
- transactions are not used. */
|
|
|
|
- if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
|
|
|
|
- info->flags |= I2C_CLIENT_PEC;
|
|
|
|
- } else if (kind == lm99) {
|
|
|
|
- name = "lm99";
|
|
|
|
- } else if (kind == lm86) {
|
|
|
|
- name = "lm86";
|
|
|
|
- } else if (kind == max6657) {
|
|
|
|
- name = "max6657";
|
|
|
|
- } else if (kind == max6680) {
|
|
|
|
- name = "max6680";
|
|
|
|
- } else if (kind == adt7461) {
|
|
|
|
- name = "adt7461";
|
|
|
|
- } else if (kind == max6646) {
|
|
|
|
- name = "max6646";
|
|
|
|
|
|
+ if (!name) { /* identification failed */
|
|
|
|
+ dev_dbg(&adapter->dev,
|
|
|
|
+ "Unsupported chip at 0x%02x (man_id=0x%02X, "
|
|
|
|
+ "chip_id=0x%02X)\n", address, man_id, chip_id);
|
|
|
|
+ return -ENODEV;
|
|
}
|
|
}
|
|
|
|
+
|
|
strlcpy(info->type, name, I2C_NAME_SIZE);
|
|
strlcpy(info->type, name, I2C_NAME_SIZE);
|
|
|
|
|
|
return 0;
|
|
return 0;
|