staging: hv: make the block driver depend on LBDAF
[safe/jmp/linux-2.6] / drivers / hwmon / lm90.c
index 1aff757..7cc2708 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * lm90.c - Part of lm_sensors, Linux kernel modules for hardware
  *          monitoring
- * Copyright (C) 2003-2008  Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2010  Jean Delvare <khali@linux-fr.org>
  *
  * 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
 static const unsigned short normal_i2c[] = {
        0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
-/*
- * Insmod parameters
- */
-
-I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680,
-                   max6646);
+enum chips { lm90, adm1032, lm99, lm86, max6657, adt7461, max6680, max6646,
+       w83l771 };
 
 /*
  * The LM90 registers
@@ -152,11 +148,11 @@ I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680,
  * Functions declaration
  */
 
-static int lm90_detect(struct i2c_client *client, int kind,
-                      struct i2c_board_info *info);
+static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info);
 static int lm90_probe(struct i2c_client *client,
                      const struct i2c_device_id *id);
 static void lm90_init_client(struct i2c_client *client);
+static void lm90_alert(struct i2c_client *client, unsigned int flag);
 static int lm90_remove(struct i2c_client *client);
 static struct lm90_data *lm90_update_device(struct device *dev);
 
@@ -179,6 +175,7 @@ static const struct i2c_device_id lm90_id[] = {
        { "max6659", max6657 },
        { "max6680", max6680 },
        { "max6681", max6680 },
+       { "w83l771", w83l771 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, lm90_id);
@@ -190,9 +187,10 @@ static struct i2c_driver lm90_driver = {
        },
        .probe          = lm90_probe,
        .remove         = lm90_remove,
+       .alert          = lm90_alert,
        .id_table       = lm90_id,
        .detect         = lm90_detect,
-       .address_data   = &addr_data,
+       .address_list   = normal_i2c,
 };
 
 /*
@@ -207,6 +205,9 @@ struct lm90_data {
        int kind;
        int flags;
 
+       u8 config_orig;         /* Original configuration register value */
+       u8 alert_alarms;        /* Which alarm bits trigger ALERT# */
+
        /* registers values */
        s8 temp8[4];    /* 0: local low limit
                           1: local high limit
@@ -656,159 +657,131 @@ static int lm90_read_reg(struct i2c_client* client, u8 reg, u8 *value)
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
-static int lm90_detect(struct i2c_client *new_client, int kind,
+static int lm90_detect(struct i2c_client *new_client,
                       struct i2c_board_info *info)
 {
        struct i2c_adapter *adapter = new_client->adapter;
        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))
                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
-                || (chip_id = i2c_smbus_read_byte_data(new_client,
+        || (chip_id = i2c_smbus_read_byte_data(new_client,
                                                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
-                || (reg_convrate = i2c_smbus_read_byte_data(new_client,
+        || (reg_convrate = i2c_smbus_read_byte_data(new_client,
                                                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;
-               
-               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
-                       /* 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
-                       /* 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";
+               }
+       } else
+       if (address == 0x4C
+        && man_id == 0x5C) { /* Winbond/Nuvoton */
+               if ((chip_id & 0xFE) == 0x10 /* W83L771AWG/ASG */
+                && (reg_config1 & 0x2A) == 0x00
+                && reg_convrate <= 0x08) {
+                       name = "w83l771";
                }
        }
 
-       /* 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);
 
        return 0;
@@ -836,6 +809,19 @@ static int lm90_probe(struct i2c_client *new_client,
                        new_client->flags &= ~I2C_CLIENT_PEC;
        }
 
+       /* Different devices have different alarm bits triggering the
+        * ALERT# output */
+       switch (data->kind) {
+       case lm90:
+       case lm99:
+       case lm86:
+               data->alert_alarms = 0x7b;
+               break;
+       default:
+               data->alert_alarms = 0x7c;
+               break;
+       }
+
        /* Initialize the LM90 chip */
        lm90_init_client(new_client);
 
@@ -872,7 +858,7 @@ exit:
 
 static void lm90_init_client(struct i2c_client *client)
 {
-       u8 config, config_orig;
+       u8 config;
        struct lm90_data *data = i2c_get_clientdata(client);
 
        /*
@@ -884,7 +870,7 @@ static void lm90_init_client(struct i2c_client *client)
                dev_warn(&client->dev, "Initialization failed!\n");
                return;
        }
-       config_orig = config;
+       data->config_orig = config;
 
        /* Check Temperature Range Select */
        if (data->kind == adt7461) {
@@ -902,7 +888,7 @@ static void lm90_init_client(struct i2c_client *client)
        }
 
        config &= 0xBF; /* run */
-       if (config != config_orig) /* Only write if changed */
+       if (config != data->config_orig) /* Only write if changed */
                i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config);
 }
 
@@ -917,10 +903,46 @@ static int lm90_remove(struct i2c_client *client)
                device_remove_file(&client->dev,
                                   &sensor_dev_attr_temp2_offset.dev_attr);
 
+       /* Restore initial configuration */
+       i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+                                 data->config_orig);
+
        kfree(data);
        return 0;
 }
 
+static void lm90_alert(struct i2c_client *client, unsigned int flag)
+{
+       struct lm90_data *data = i2c_get_clientdata(client);
+       u8 config, alarms;
+
+       lm90_read_reg(client, LM90_REG_R_STATUS, &alarms);
+       if ((alarms & 0x7f) == 0) {
+               dev_info(&client->dev, "Everything OK\n");
+       } else {
+               if (alarms & 0x61)
+                       dev_warn(&client->dev,
+                                "temp%d out of range, please check!\n", 1);
+               if (alarms & 0x1a)
+                       dev_warn(&client->dev,
+                                "temp%d out of range, please check!\n", 2);
+               if (alarms & 0x04)
+                       dev_warn(&client->dev,
+                                "temp%d diode open, please check!\n", 2);
+
+               /* Disable ALERT# output, because these chips don't implement
+                 SMBus alert correctly; they should only hold the alert line
+                 low briefly. */
+               if ((data->kind == adm1032 || data->kind == adt7461)
+                && (alarms & data->alert_alarms)) {
+                       dev_dbg(&client->dev, "Disabling ALERT#\n");
+                       lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+                       i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1,
+                                                 config | 0x80);
+               }
+       }
+}
+
 static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
 {
        int err;
@@ -1008,6 +1030,21 @@ static struct lm90_data *lm90_update_device(struct device *dev)
                }
                lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
 
+               /* Re-enable ALERT# output if it was originally enabled and
+                * relevant alarms are all clear */
+               if ((data->config_orig & 0x80) == 0
+                && (data->alarms & data->alert_alarms) == 0) {
+                       u8 config;
+
+                       lm90_read_reg(client, LM90_REG_R_CONFIG1, &config);
+                       if (config & 0x80) {
+                               dev_dbg(&client->dev, "Re-enabling ALERT#\n");
+                               i2c_smbus_write_byte_data(client,
+                                                         LM90_REG_W_CONFIG1,
+                                                         config & ~0x80);
+                       }
+               }
+
                data->last_updated = jiffies;
                data->valid = 1;
        }