diff options
Diffstat (limited to 'drivers/hwmon/emc6w201.c')
| -rw-r--r-- | drivers/hwmon/emc6w201.c | 106 |
1 files changed, 60 insertions, 46 deletions
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c index e0ef32378ac..f76a74cb6dc 100644 --- a/drivers/hwmon/emc6w201.c +++ b/drivers/hwmon/emc6w201.c @@ -1,6 +1,6 @@ /* * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201 - * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2011 Jean Delvare <jdelvare@suse.de> * * 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 @@ -18,7 +18,6 @@ */ #include <linux/module.h> -#include <linux/delay.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/jiffies.h> @@ -50,7 +49,7 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; #define EMC6W201_REG_TEMP_HIGH(nr) (0x57 + (nr) * 2) #define EMC6W201_REG_FAN_MIN(nr) (0x62 + (nr) * 2) -enum { input, min, max } subfeature; +enum subfeature { input, min, max }; /* * Per-device data @@ -78,8 +77,9 @@ static u16 emc6w201_read16(struct i2c_client *client, u8 reg) lsb = i2c_smbus_read_byte_data(client, reg); msb = i2c_smbus_read_byte_data(client, reg + 1); - if (lsb < 0 || msb < 0) { - dev_err(&client->dev, "16-bit read failed at 0x%02x\n", reg); + if (unlikely(lsb < 0 || msb < 0)) { + dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", + 16, "read", reg); return 0xFFFF; /* Arbitrary value */ } @@ -95,10 +95,39 @@ static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val) int err; err = i2c_smbus_write_byte_data(client, reg, val & 0xff); - if (!err) + if (likely(!err)) err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8); - if (err < 0) - dev_err(&client->dev, "16-bit write failed at 0x%02x\n", reg); + if (unlikely(err < 0)) + dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", + 16, "write", reg); + + return err; +} + +/* Read 8-bit value from register */ +static u8 emc6w201_read8(struct i2c_client *client, u8 reg) +{ + int val; + + val = i2c_smbus_read_byte_data(client, reg); + if (unlikely(val < 0)) { + dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", + 8, "read", reg); + return 0x00; /* Arbitrary value */ + } + + return val; +} + +/* Write 8-bit value to register */ +static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val) +{ + int err; + + err = i2c_smbus_write_byte_data(client, reg, val); + if (unlikely(err < 0)) + dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", + 8, "write", reg); return err; } @@ -114,25 +143,25 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { for (nr = 0; nr < 6; nr++) { data->in[input][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_IN(nr)); data->in[min][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_IN_LOW(nr)); data->in[max][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_IN_HIGH(nr)); } for (nr = 0; nr < 6; nr++) { data->temp[input][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_TEMP(nr)); data->temp[min][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_TEMP_LOW(nr)); data->temp[max][nr] = - i2c_smbus_read_byte_data(client, + emc6w201_read8(client, EMC6W201_REG_TEMP_HIGH(nr)); } @@ -158,7 +187,7 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev) * Sysfs callback functions */ -static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 }; +static const s16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 }; static ssize_t show_in(struct device *dev, struct device_attribute *devattr, char *buf) @@ -182,7 +211,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr, long val; u8 reg; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -191,8 +220,8 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr, : EMC6W201_REG_IN_HIGH(nr); mutex_lock(&data->update_lock); - data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255); - err = i2c_smbus_write_byte_data(client, reg, data->in[sf][nr]); + data->in[sf][nr] = clamp_val(val, 0, 255); + err = emc6w201_write8(client, reg, data->in[sf][nr]); mutex_unlock(&data->update_lock); return err < 0 ? err : count; @@ -219,7 +248,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, long val; u8 reg; - err = strict_strtol(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err < 0) return err; @@ -228,8 +257,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, : EMC6W201_REG_TEMP_HIGH(nr); mutex_lock(&data->update_lock); - data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128); - err = i2c_smbus_write_byte_data(client, reg, data->temp[sf][nr]); + data->temp[sf][nr] = clamp_val(val, -127, 128); + err = emc6w201_write8(client, reg, data->temp[sf][nr]); mutex_unlock(&data->update_lock); return err < 0 ? err : count; @@ -261,7 +290,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, int err; unsigned long val; - err = strict_strtoul(buf, 10, &val); + err = kstrtoul(buf, 10, &val); if (err < 0) return err; @@ -269,7 +298,7 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, val = 0xFFFF; } else { val = DIV_ROUND_CLOSEST(5400000U, val); - val = SENSORS_LIMIT(val, 0, 0xFFFE); + val = clamp_val(val, 0, 0xFFFE); } mutex_lock(&data->update_lock); @@ -444,7 +473,7 @@ static int emc6w201_detect(struct i2c_client *client, /* Check configuration */ config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG); - if ((config & 0xF4) != 0x04) + if (config < 0 || (config & 0xF4) != 0x04) return -ENODEV; if (!(config & 0x01)) { dev_err(&client->dev, "Monitoring not enabled\n"); @@ -462,11 +491,10 @@ static int emc6w201_probe(struct i2c_client *client, struct emc6w201_data *data; int err; - data = kzalloc(sizeof(struct emc6w201_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); mutex_init(&data->update_lock); @@ -474,7 +502,7 @@ static int emc6w201_probe(struct i2c_client *client, /* Create sysfs attribute */ err = sysfs_create_group(&client->dev.kobj, &emc6w201_group); if (err) - goto exit_free; + return err; /* Expose as a hwmon device */ data->hwmon_dev = hwmon_device_register(&client->dev); @@ -487,9 +515,6 @@ static int emc6w201_probe(struct i2c_client *client, exit_remove: sysfs_remove_group(&client->dev.kobj, &emc6w201_group); - exit_free: - kfree(data); - exit: return err; } @@ -499,7 +524,6 @@ static int emc6w201_remove(struct i2c_client *client) hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&client->dev.kobj, &emc6w201_group); - kfree(data); return 0; } @@ -522,18 +546,8 @@ static struct i2c_driver emc6w201_driver = { .address_list = normal_i2c, }; -static int __init sensors_emc6w201_init(void) -{ - return i2c_add_driver(&emc6w201_driver); -} -module_init(sensors_emc6w201_init); - -static void __exit sensors_emc6w201_exit(void) -{ - i2c_del_driver(&emc6w201_driver); -} -module_exit(sensors_emc6w201_exit); +module_i2c_driver(emc6w201_driver); -MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); +MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>"); MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver"); MODULE_LICENSE("GPL"); |
