diff options
Diffstat (limited to 'drivers/hwmon/gl518sm.c')
| -rw-r--r-- | drivers/hwmon/gl518sm.c | 185 |
1 files changed, 95 insertions, 90 deletions
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c index 7820df45d77..1e983051304 100644 --- a/drivers/hwmon/gl518sm.c +++ b/drivers/hwmon/gl518sm.c @@ -4,7 +4,7 @@ * Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and * Kyosti Malkki <kmalkki@cc.hut.fi> * Copyright (C) 2004 Hong-Gunn Chew <hglinux@gunnet.org> and - * Jean Delvare <khali@linux-fr.org> + * 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 @@ -46,8 +46,7 @@ /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80); +enum chips { gl518sm_r00, gl518sm_r80 }; /* Many GL518 constants specified below */ @@ -84,11 +83,12 @@ I2C_CLIENT_INSMOD_2(gl518sm_r00, gl518sm_r80); #define RAW_FROM_REG(val) val -#define BOOL_FROM_REG(val) ((val)?0:1) -#define BOOL_TO_REG(val) ((val)?0:1) +#define BOOL_FROM_REG(val) ((val) ? 0 : 1) +#define BOOL_TO_REG(val) ((val) ? 0 : 1) -#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0? \ - (val)-500:(val)+500)/1000)+119),0,255)) +#define TEMP_TO_REG(val) clamp_val(((((val) < 0 ? \ + (val) - 500 : \ + (val) + 500) / 1000) + 119), 0, 255) #define TEMP_FROM_REG(val) (((val) - 119) * 1000) static inline u8 FAN_TO_REG(long rpm, int div) @@ -96,16 +96,16 @@ static inline u8 FAN_TO_REG(long rpm, int div) long rpmdiv; if (rpm == 0) return 0; - rpmdiv = SENSORS_LIMIT(rpm, 1, 960000) * div; - return SENSORS_LIMIT((480000 + rpmdiv / 2) / rpmdiv, 1, 255); + rpmdiv = clamp_val(rpm, 1, 960000) * div; + return clamp_val((480000 + rpmdiv / 2) / rpmdiv, 1, 255); } -#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val)*(div)))) +#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : (480000 / ((val) * (div)))) -#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) -#define IN_FROM_REG(val) ((val)*19) +#define IN_TO_REG(val) clamp_val((((val) + 9) / 19), 0, 255) +#define IN_FROM_REG(val) ((val) * 19) -#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) -#define VDD_FROM_REG(val) (((val)*95+2)/4) +#define VDD_TO_REG(val) clamp_val((((val) * 4 + 47) / 95), 0, 255) +#define VDD_FROM_REG(val) (((val) * 95 + 2) / 4) #define DIV_FROM_REG(val) (1 << (val)) @@ -139,8 +139,7 @@ struct gl518_data { static int gl518_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int gl518_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); +static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info); static void gl518_init_client(struct i2c_client *client); static int gl518_remove(struct i2c_client *client); static int gl518_read_value(struct i2c_client *client, u8 reg); @@ -163,7 +162,7 @@ static struct i2c_driver gl518_driver = { .remove = gl518_remove, .id_table = gl518_id, .detect = gl518_detect, - .address_data = &addr_data, + .address_list = normal_i2c, }; /* @@ -171,7 +170,8 @@ static struct i2c_driver gl518_driver = { */ #define show(type, suffix, value) \ -static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \ +static ssize_t show_##suffix(struct device *dev, \ + struct device_attribute *attr, char *buf) \ { \ struct gl518_data *data = gl518_update_device(dev); \ return sprintf(buf, "%d\n", type##_FROM_REG(data->value)); \ @@ -224,12 +224,16 @@ static ssize_t show_fan_div(struct device *dev, } #define set(type, suffix, value, reg) \ -static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_##suffix(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct gl518_data *data = i2c_get_clientdata(client); \ - long val = simple_strtol(buf, NULL, 10); \ + long val; \ + int err = kstrtol(buf, 10, &val); \ + if (err) \ + return err; \ \ mutex_lock(&data->update_lock); \ data->value = type##_TO_REG(val); \ @@ -239,13 +243,17 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c } #define set_bits(type, suffix, value, reg, mask, shift) \ -static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ - size_t count) \ +static ssize_t set_##suffix(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count) \ { \ struct i2c_client *client = to_i2c_client(dev); \ struct gl518_data *data = i2c_get_clientdata(client); \ int regvalue; \ - 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); \ regvalue = gl518_read_value(client, reg); \ @@ -282,7 +290,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; int regvalue; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; mutex_lock(&data->update_lock); regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); @@ -310,16 +323,30 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int nr = to_sensor_dev_attr(attr)->index; int regvalue; - unsigned long val = simple_strtoul(buf, NULL, 10); + unsigned long val; + int err; + + err = kstrtoul(buf, 10, &val); + if (err) + return err; switch (val) { - case 1: val = 0; break; - case 2: val = 1; break; - case 4: val = 2; break; - case 8: val = 3; break; + case 1: + val = 0; + break; + case 2: + val = 1; + break; + case 4: + val = 2; + break; + case 8: + val = 3; + break; default: - dev_err(dev, "Invalid fan clock divider %lu, choose one " - "of 1, 2, 4 or 8\n", val); + dev_err(dev, + "Invalid fan clock divider %lu, choose one of 1, 2, 4 or 8\n", + val); return -EINVAL; } @@ -397,8 +424,12 @@ static ssize_t set_beep(struct device *dev, struct device_attribute *attr, struct gl518_data *data = i2c_get_clientdata(client); int bitnr = to_sensor_dev_attr(attr)->index; unsigned long bit; + int err; + + err = kstrtoul(buf, 10, &bit); + if (err) + return err; - bit = simple_strtoul(buf, NULL, 10); if (bit & ~1) return -EINVAL; @@ -484,40 +515,24 @@ static const struct attribute_group gl518_group_r80 = { */ /* Return 0 if detection is successful, -ENODEV otherwise */ -static int gl518_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; - int i; + int rev; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA)) return -ENODEV; /* Now, we do the remaining detection. */ - - if (kind < 0) { - if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80) - || (gl518_read_value(client, GL518_REG_CONF) & 0x80)) - return -ENODEV; - } + if ((gl518_read_value(client, GL518_REG_CHIP_ID) != 0x80) + || (gl518_read_value(client, GL518_REG_CONF) & 0x80)) + return -ENODEV; /* Determine the chip type. */ - if (kind <= 0) { - i = gl518_read_value(client, GL518_REG_REVISION); - if (i == 0x00) { - kind = gl518sm_r00; - } else if (i == 0x80) { - kind = gl518sm_r80; - } else { - if (kind <= 0) - dev_info(&adapter->dev, - "Ignoring 'force' parameter for unknown " - "chip at adapter %d, address 0x%02x\n", - i2c_adapter_id(adapter), client->addr); - return -ENODEV; - } - } + rev = gl518_read_value(client, GL518_REG_REVISION); + if (rev != 0x00 && rev != 0x80) + return -ENODEV; strlcpy(info->type, "gl518sm", I2C_NAME_SIZE); @@ -530,11 +545,10 @@ static int gl518_probe(struct i2c_client *client, struct gl518_data *data; int err, revision; - data = kzalloc(sizeof(struct gl518_data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } + data = devm_kzalloc(&client->dev, sizeof(struct gl518_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; i2c_set_clientdata(client, data); revision = gl518_read_value(client, GL518_REG_REVISION); @@ -546,12 +560,14 @@ static int gl518_probe(struct i2c_client *client, gl518_init_client(client); /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &gl518_group))) - goto exit_free; - if (data->type == gl518sm_r80) - if ((err = sysfs_create_group(&client->dev.kobj, - &gl518_group_r80))) + err = sysfs_create_group(&client->dev.kobj, &gl518_group); + if (err) + return err; + if (data->type == gl518sm_r80) { + err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80); + if (err) goto exit_remove_files; + } data->hwmon_dev = hwmon_device_register(&client->dev); if (IS_ERR(data->hwmon_dev)) { @@ -565,15 +581,14 @@ exit_remove_files: sysfs_remove_group(&client->dev.kobj, &gl518_group); if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); -exit_free: - kfree(data); -exit: return err; } -/* Called when we have found a new GL518SM. - Note that we preserve D4:NoFan2 and D2:beep_enable. */ +/* + * Called when we have found a new GL518SM. + * Note that we preserve D4:NoFan2 and D2:beep_enable. + */ static void gl518_init_client(struct i2c_client *client) { /* Make sure we leave D7:Reset untouched */ @@ -599,17 +614,18 @@ static int gl518_remove(struct i2c_client *client) if (data->type == gl518sm_r80) sysfs_remove_group(&client->dev.kobj, &gl518_group_r80); - kfree(data); return 0; } -/* Registers 0x07 to 0x0c are word-sized, others are byte-sized - GL518 uses a high-byte first convention, which is exactly opposite to - the SMBus standard. */ +/* + * Registers 0x07 to 0x0c are word-sized, others are byte-sized + * GL518 uses a high-byte first convention, which is exactly opposite to + * the SMBus standard. + */ static int gl518_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) - return swab16(i2c_smbus_read_word_data(client, reg)); + return i2c_smbus_read_word_swapped(client, reg); else return i2c_smbus_read_byte_data(client, reg); } @@ -617,7 +633,7 @@ static int gl518_read_value(struct i2c_client *client, u8 reg) static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) { if ((reg >= 0x07) && (reg <= 0x0c)) - return i2c_smbus_write_word_data(client, reg, swab16(value)); + return i2c_smbus_write_word_swapped(client, reg, value); else return i2c_smbus_write_byte_data(client, reg, value); } @@ -694,21 +710,10 @@ static struct gl518_data *gl518_update_device(struct device *dev) return data; } -static int __init sensors_gl518sm_init(void) -{ - return i2c_add_driver(&gl518_driver); -} - -static void __exit sensors_gl518sm_exit(void) -{ - i2c_del_driver(&gl518_driver); -} +module_i2c_driver(gl518_driver); MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " "Kyosti Malkki <kmalkki@cc.hut.fi> and " "Hong-Gunn Chew <hglinux@gunnet.org>"); MODULE_DESCRIPTION("GL518SM driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_gl518sm_init); -module_exit(sensors_gl518sm_exit); |
