Merge git://git.samba.org/sfrench/cifs-2.6
[firefly-linux-kernel-4.4.55.git] / drivers / hwmon / w83l786ng.c
index 063bd9508d8a1505dadba8699e806a1c93901356..5850b77060885e696989c75e63f2618c38ff5001 100644 (file)
@@ -1,28 +1,28 @@
 /*
   w83l786ng.c - Linux kernel driver for hardware monitoring
   Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org>
-
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation - version 2.
-
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
-
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301 USA.
-*/
* w83l786ng.c - Linux kernel driver for hardware monitoring
* Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation - version 2.
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
+ */
 
 /*
   Supports following chips:
-
   Chip       #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
   w83l786ng  3       2       2       2       0x7b    0x5ca3  yes     no
-*/
* Supports following chips:
+ *
* Chip        #vin    #fanin  #pwm    #temp   wchipid vendid  i2c     ISA
* w83l786ng   3       2       2       2       0x7b    0x5ca3  yes     no
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
 
 #define W83L786NG_REG_CONFIG           0x40
 #define W83L786NG_REG_ALARM1           0x41
-#define W83L786NG_REG_ALARM2           0x42
+#define W83L786NG_REG_ALARM2           0x42
 #define W83L786NG_REG_GPIO_EN          0x47
 #define W83L786NG_REG_MAN_ID2          0x4C
 #define W83L786NG_REG_MAN_ID1          0x4D
@@ -89,19 +89,23 @@ FAN_TO_REG(long rpm, int div)
        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
 }
 
-#define FAN_FROM_REG(val,div)  ((val) == 0   ? -1 : \
+#define FAN_FROM_REG(val, div) ((val) == 0   ? -1 : \
                                ((val) == 255 ? 0 : \
                                1350000 / ((val) * (div))))
 
 /* for temp */
-#define TEMP_TO_REG(val)       (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \
-                                   : (val)) / 1000, 0, 0xff))
-#define TEMP_FROM_REG(val)     (((val) & 0x80 ? (val)-0x100 : (val)) * 1000)
-
-/* The analog voltage inputs have 8mV LSB. Since the sysfs output is
-   in mV as would be measured on the chip input pin, need to just
-   multiply/divide by 8 to translate from/to register values. */
-#define IN_TO_REG(val)          (SENSORS_LIMIT((((val) + 4) / 8), 0, 255))
+#define TEMP_TO_REG(val)       (SENSORS_LIMIT(((val) < 0 ? \
+                                               (val) + 0x100 * 1000 \
+                                               : (val)) / 1000, 0, 0xff))
+#define TEMP_FROM_REG(val)     (((val) & 0x80 ? \
+                                 (val) - 0x100 : (val)) * 1000)
+
+/*
+ * The analog voltage inputs have 8mV LSB. Since the sysfs output is
+ * in mV as would be measured on the chip input pin, need to just
+ * multiply/divide by 8 to translate from/to register values.
+ */
+#define IN_TO_REG(val)         (SENSORS_LIMIT((((val) + 4) / 8), 0, 255))
 #define IN_FROM_REG(val)       ((val) * 8)
 
 #define DIV_FROM_REG(val)      (1 << (val))
@@ -116,7 +120,7 @@ DIV_TO_REG(long val)
                        break;
                val >>= 1;
        }
-       return ((u8) i);
+       return (u8)i;
 }
 
 struct w83l786ng_data {
@@ -125,7 +129,7 @@ struct w83l786ng_data {
        char valid;                     /* !=0 if following fields are valid */
        unsigned long last_updated;     /* In jiffies */
        unsigned long last_nonvolatile; /* In jiffies, last time we update the
-                                          nonvolatile registers */
+                                        * nonvolatile registers */
 
        u8 in[3];
        u8 in_max[3];
@@ -137,10 +141,10 @@ struct w83l786ng_data {
        u8 temp[2][3];
        u8 pwm[2];
        u8 pwm_mode[2]; /* 0->DC variable voltage
-                          1->PWM variable duty cycle */
+                        * 1->PWM variable duty cycle */
 
        u8 pwm_enable[2]; /* 1->manual
-                            2->thermal cruise (also called SmartFan I) */
+                          * 2->thermal cruise (also called SmartFan I) */
        u8 tolerance[2];
 };
 
@@ -186,11 +190,11 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value)
 #define show_in_reg(reg) \
 static ssize_t \
 show_##reg(struct device *dev, struct device_attribute *attr, \
-           char *buf) \
+          char *buf) \
 { \
        int nr = to_sensor_dev_attr(attr)->index; \
        struct w83l786ng_data *data = w83l786ng_update_device(dev); \
-       return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \
+       return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
 }
 
 show_in_reg(in)
@@ -199,13 +203,16 @@ show_in_reg(in_max)
 
 #define store_in_reg(REG, reg) \
 static ssize_t \
-store_in_##reg (struct device *dev, struct device_attribute *attr, \
-               const char *buf, size_t count) \
+store_in_##reg(struct device *dev, struct device_attribute *attr, \
+              const char *buf, size_t count) \
 { \
        int nr = to_sensor_dev_attr(attr)->index; \
        struct i2c_client *client = to_i2c_client(dev); \
        struct w83l786ng_data *data = i2c_get_clientdata(client); \
-       unsigned long val = simple_strtoul(buf, NULL, 10); \
+       unsigned long val; \
+       int err = kstrtoul(buf, 10, &val); \
+       if (err) \
+               return err; \
        mutex_lock(&data->update_lock); \
        data->in_##reg[nr] = IN_TO_REG(val); \
        w83l786ng_write_value(client, W83L786NG_REG_IN_##REG(nr), \
@@ -241,8 +248,8 @@ static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
 { \
        int nr = to_sensor_dev_attr(attr)->index; \
        struct w83l786ng_data *data = w83l786ng_update_device(dev); \
-        return sprintf(buf,"%d\n", \
-                FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
+       return sprintf(buf, "%d\n", \
+               FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \
 }
 
 show_fan_reg(fan);
@@ -255,9 +262,13 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
        int nr = to_sensor_dev_attr(attr)->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       u32 val;
+       unsigned long val;
+       int err;
+
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
 
-       val = simple_strtoul(buf, NULL, 10);
        mutex_lock(&data->update_lock);
        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
        w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr),
@@ -276,10 +287,12 @@ show_fan_div(struct device *dev, struct device_attribute *attr,
        return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
 }
 
-/* Note: we save and restore the fan minimum here, because its value is
-   determined in part by the fan divisor.  This follows the principle of
-   least surprise; the user doesn't expect the fan minimum to change just
-   because the divisor changed. */
+/*
+ * Note: we save and restore the fan minimum here, because its value is
+ * determined in part by the fan divisor.  This follows the principle of
+ * least surprise; the user doesn't expect the fan minimum to change just
+ * because the divisor changed.
+ */
 static ssize_t
 store_fan_div(struct device *dev, struct device_attribute *attr,
              const char *buf, size_t count)
@@ -294,11 +307,18 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
        u8 keep_mask = 0;
        u8 new_shift = 0;
 
+       unsigned long val;
+       int err;
+
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
+
        /* Save fan_min */
        mutex_lock(&data->update_lock);
        min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
 
-       data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
+       data->fan_div[nr] = DIV_TO_REG(val);
 
        switch (nr) {
        case 0:
@@ -371,16 +391,20 @@ store_temp(struct device *dev, struct device_attribute *attr,
        int index = sensor_attr->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       s32 val;
+       long val;
+       int err;
+
+       err = kstrtol(buf, 10, &val);
+       if (err)
+               return err;
 
-       val = simple_strtol(buf, NULL, 10);
        mutex_lock(&data->update_lock);
        data->temp[nr][index] = TEMP_TO_REG(val);
        w83l786ng_write_value(client, W83L786NG_REG_TEMP[nr][index],
                              data->temp[nr][index]);
        mutex_unlock(&data->update_lock);
 
-        return count;
+       return count;
 }
 
 static struct sensor_device_attribute_2 sda_temp_input[] = {
@@ -403,8 +427,8 @@ static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
 };
 
 #define show_pwm_reg(reg) \
-static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
-                          char *buf) \
+static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
+                         char *buf) \
 { \
        struct w83l786ng_data *data = w83l786ng_update_device(dev); \
        int nr = to_sensor_dev_attr(attr)->index; \
@@ -422,8 +446,13 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
        int nr = to_sensor_dev_attr(attr)->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       u32 val = simple_strtoul(buf, NULL, 10);
        u8 reg;
+       unsigned long val;
+       int err;
+
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
 
        if (val > 1)
                return -EINVAL;
@@ -445,7 +474,13 @@ store_pwm(struct device *dev, struct device_attribute *attr,
        int nr = to_sensor_dev_attr(attr)->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255);
+       unsigned long val;
+       int err;
+
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
+       val = SENSORS_LIMIT(val, 0, 255);
 
        mutex_lock(&data->update_lock);
        data->pwm[nr] = val;
@@ -461,11 +496,15 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
        int nr = to_sensor_dev_attr(attr)->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       u32 val = simple_strtoul(buf, NULL, 10);
-
        u8 reg;
+       unsigned long val;
+       int err;
 
-       if (!val || (val > 2))  /* only modes 1 and 2 are supported */
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
+
+       if (!val || val > 2)  /* only modes 1 and 2 are supported */
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
@@ -513,10 +552,13 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
        int nr = to_sensor_dev_attr(attr)->index;
        struct i2c_client *client = to_i2c_client(dev);
        struct w83l786ng_data *data = i2c_get_clientdata(client);
-       u32 val;
        u8 tol_tmp, tol_mask;
+       unsigned long val;
+       int err;
 
-       val = simple_strtoul(buf, NULL, 10);
+       err = kstrtoul(buf, 10, &val);
+       if (err)
+               return err;
 
        mutex_lock(&data->update_lock);
        tol_mask = w83l786ng_read_value(client,
@@ -524,9 +566,8 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
        tol_tmp = SENSORS_LIMIT(val, 0, 15);
        tol_tmp &= 0x0f;
        data->tolerance[nr] = tol_tmp;
-       if (nr == 1) {
+       if (nr == 1)
                tol_tmp <<= 4;
-       }
 
        w83l786ng_write_value(client, W83L786NG_REG_TOLERANCE,
                              tol_mask | tol_tmp);
@@ -591,9 +632,8 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
        u16 man_id;
        u8 chip_id;
 
-       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
-       }
 
        /* Detection */
        if ((w83l786ng_read_value(client, W83L786NG_REG_CONFIG) & 0x80)) {
@@ -652,7 +692,8 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
        data->fan_div[1] = (reg_tmp >> 4) & 0x07;
 
        /* Register sysfs hooks */
-       if ((err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group)))
+       err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group);
+       if (err)
                goto exit_remove;
 
        data->hwmon_dev = hwmon_device_register(dev);
@@ -769,21 +810,8 @@ static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
        return data;
 }
 
-static int __init
-sensors_w83l786ng_init(void)
-{
-       return i2c_add_driver(&w83l786ng_driver);
-}
-
-static void __exit
-sensors_w83l786ng_exit(void)
-{
-       i2c_del_driver(&w83l786ng_driver);
-}
+module_i2c_driver(w83l786ng_driver);
 
 MODULE_AUTHOR("Kevin Lo");
 MODULE_DESCRIPTION("w83l786ng driver");
 MODULE_LICENSE("GPL");
-
-module_init(sensors_w83l786ng_init);
-module_exit(sensors_w83l786ng_exit);