hwmon: (lm85) Fix various errors on attribute writes
[cascardo/linux.git] / drivers / hwmon / lm85.c
index bed4af3..ef627ea 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2002, 2003  Philip Pokorny <ppokorny@penguincomputing.com>
  * Copyright (c) 2003        Margit Schubert-While <margitsw@t-online.de>
  * Copyright (c) 2004        Justin Thiessen <jthiessen@penguincomputing.com>
- * Copyright (C) 2007--2009  Jean Delvare <jdelvare@suse.de>
+ * Copyright (C) 2007--2014  Jean Delvare <jdelvare@suse.de>
  *
  * Chip details at           <http://www.national.com/ds/LM/LM85.pdf>
  *
@@ -39,7 +39,7 @@
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
 
 enum chips {
-       any_chip, lm85b, lm85c,
+       lm85,
        adm1027, adt7463, adt7468,
        emc6d100, emc6d102, emc6d103, emc6d103s
 };
@@ -75,9 +75,6 @@ enum chips {
 #define LM85_COMPANY_NATIONAL          0x01
 #define LM85_COMPANY_ANALOG_DEV                0x41
 #define LM85_COMPANY_SMSC              0x5c
-#define LM85_VERSTEP_VMASK              0xf0
-#define LM85_VERSTEP_GENERIC           0x60
-#define LM85_VERSTEP_GENERIC2          0x70
 #define LM85_VERSTEP_LM85C             0x60
 #define LM85_VERSTEP_LM85B             0x62
 #define LM85_VERSTEP_LM96000_1         0x68
@@ -158,7 +155,7 @@ static inline u16 FAN_TO_REG(unsigned long val)
 
 /* Temperature is reported in .001 degC increments */
 #define TEMP_TO_REG(val)       \
-               clamp_val(SCALE(val, 1000, 1), -127, 127)
+               DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000)
 #define TEMPEXT_FROM_REG(val, ext)     \
                SCALE(((val) << 4) + (ext), 16, 1000)
 #define TEMP_FROM_REG(val)     ((val) * 1000)
@@ -192,7 +189,7 @@ static const int lm85_range_map[] = {
        13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
 };
 
-static int RANGE_TO_REG(int range)
+static int RANGE_TO_REG(long range)
 {
        int i;
 
@@ -214,7 +211,7 @@ static const int adm1027_freq_map[8] = { /* 1 Hz */
        11, 15, 22, 29, 35, 44, 59, 88
 };
 
-static int FREQ_TO_REG(const int *map, int freq)
+static int FREQ_TO_REG(const int *map, unsigned long freq)
 {
        int i;
 
@@ -351,9 +348,9 @@ static const struct i2c_device_id lm85_id[] = {
        { "adm1027", adm1027 },
        { "adt7463", adt7463 },
        { "adt7468", adt7468 },
-       { "lm85", any_chip },
-       { "lm85b", lm85b },
-       { "lm85c", lm85c },
+       { "lm85", lm85 },
+       { "lm85b", lm85 },
+       { "lm85c", lm85 },
        { "emc6d100", emc6d100 },
        { "emc6d101", emc6d100 },
        { "emc6d102", emc6d102 },
@@ -463,6 +460,9 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
        if (err)
                return err;
 
+       if (val > 255)
+               return -EINVAL;
+
        data->vrm = val;
        return count;
 }
@@ -1281,7 +1281,7 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
 {
        struct i2c_adapter *adapter = client->adapter;
        int address = client->addr;
-       const char *type_name;
+       const char *type_name = NULL;
        int company, verstep;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -1297,16 +1297,6 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
                "Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
                address, company, verstep);
 
-       /* All supported chips have the version in common */
-       if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC &&
-           (verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC2) {
-               dev_dbg(&adapter->dev,
-                       "Autodetection failed: unsupported version\n");
-               return -ENODEV;
-       }
-       type_name = "lm85";
-
-       /* Now, refine the detection */
        if (company == LM85_COMPANY_NATIONAL) {
                switch (verstep) {
                case LM85_VERSTEP_LM85C:
@@ -1323,6 +1313,7 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
                                        "Found Winbond WPCD377I, ignoring\n");
                                return -ENODEV;
                        }
+                       type_name = "lm85";
                        break;
                }
        } else if (company == LM85_COMPANY_ANALOG_DEV) {
@@ -1357,12 +1348,11 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
                        type_name = "emc6d103s";
                        break;
                }
-       } else {
-               dev_dbg(&adapter->dev,
-                       "Autodetection failed: unknown vendor\n");
-               return -ENODEV;
        }
 
+       if (!type_name)
+               return -ENODEV;
+
        strlcpy(info->type, type_name, I2C_NAME_SIZE);
 
        return 0;