Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (tmp102) Various fixes

Fixes from my driver review:
http://lists.lm-sensors.org/pipermail/lm-sensors/2010-March/028051.html

Only the small changes are in there, more important changes will come
later separately as time permits.

* Drop the remnants of the now gone detect function
* The TMP102 has no known compatible chip
* Include the right header files
* Clarify why byte swapping of register values is needed
* Strip resolution info bit from temperature register value
* Set cache lifetime to 1/3 second
* Don't arbitrarily reject limit values; clamp as needed
* Make limit writing unconditional
* Don't check for transaction types the driver doesn't use
* Properly check for error when setting configuration
* Report error on failed probe
* Make the driver load automatically where needed
* Various other minor fixes

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Cc: Steven King <sfking@fdwdc.com>

+39 -42
+4 -5
Documentation/hwmon/tmp102
··· 4 4 Supported chips: 5 5 * Texas Instruments TMP102 6 6 Prefix: 'tmp102' 7 - Addresses scanned: I2C 0x48 0x49 0x4a 0x4b 7 + Addresses scanned: none 8 8 Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp102.html 9 9 10 10 Author: ··· 15 15 16 16 The Texas Instruments TMP102 implements one temperature sensor. Limits can be 17 17 set through the Overtemperature Shutdown register and Hysteresis register. The 18 - sensor is accurate to 0.5 degrees over the range of -25 to +85 C, and to 1.0 19 - degrees from -40 to +125 C. Resolution of the sensor is 0.0625 degree. The 18 + sensor is accurate to 0.5 degree over the range of -25 to +85 C, and to 1.0 19 + degree from -40 to +125 C. Resolution of the sensor is 0.0625 degree. The 20 20 operating temperature has a minimum of -55 C and a maximum of +150 C. 21 21 22 22 The TMP102 has a programmable update rate that can select between 8, 4, 1, and 23 23 0.5 Hz. (Currently the driver only supports the default of 4 Hz). 24 24 25 25 The driver provides the common sysfs-interface for temperatures (see 26 - /Documentation/hwmon/sysfs-interface under Temperatures). 27 - 26 + Documentation/hwmon/sysfs-interface under Temperatures).
+1 -1
drivers/hwmon/Kconfig
··· 843 843 will be called thmc50. 844 844 845 845 config SENSORS_TMP102 846 - tristate "Texas Instruments TMP102 and compatibles" 846 + tristate "Texas Instruments TMP102" 847 847 depends on I2C && EXPERIMENTAL 848 848 help 849 849 If you say yes here you get support for Texas Instruments TMP102
+34 -36
drivers/hwmon/tmp102.c
··· 1 - /* Texas Instruments TMP102 SMBUS temperature sensor driver 1 + /* Texas Instruments TMP102 SMBus temperature sensor driver 2 2 * 3 - * Copyright 2010 Steven King <sfking@fdwdc.com> 3 + * Copyright (C) 2010 Steven King <sfking@fdwdc.com> 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify 6 6 * it under the terms of the GNU General Public License as published by ··· 17 17 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA 18 18 */ 19 19 20 - 21 - 22 20 #include <linux/module.h> 23 21 #include <linux/init.h> 24 22 #include <linux/slab.h> ··· 25 27 #include <linux/hwmon-sysfs.h> 26 28 #include <linux/err.h> 27 29 #include <linux/mutex.h> 28 - #include <linux/delay.h> 30 + #include <linux/device.h> 29 31 30 32 #define DRIVER_NAME "tmp102" 31 33 ··· 54 56 int temp[3]; 55 57 }; 56 58 57 - /* the TMP102 registers are big endian so we have to swab16 the values */ 58 - static int tmp102_read_reg(struct i2c_client *client, u8 reg) 59 + /* SMBus specifies low byte first, but the TMP102 returns high byte first, 60 + * so we have to swab16 the values */ 61 + static inline int tmp102_read_reg(struct i2c_client *client, u8 reg) 59 62 { 60 63 int result = i2c_smbus_read_word_data(client, reg); 61 64 return result < 0 ? result : swab16(result); 62 65 } 63 66 64 - static int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) 67 + static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) 65 68 { 66 69 return i2c_smbus_write_word_data(client, reg, swab16(val)); 67 70 } 68 71 69 - /* convert left adjusted 13bit TMP102 register value to miliCelsius */ 70 - static int tmp102_reg_to_mC(s16 val) 72 + /* convert left adjusted 13-bit TMP102 register value to milliCelsius */ 73 + static inline int tmp102_reg_to_mC(s16 val) 71 74 { 72 - return (val * 1000) / 128; 75 + return ((val & ~0x01) * 1000) / 128; 73 76 } 74 77 75 - /* convert miliCelsius to left adjusted 13bit TMP102 register value */ 76 - static u16 tmp102_mC_to_reg(int val) 78 + /* convert milliCelsius to left adjusted 13-bit TMP102 register value */ 79 + static inline u16 tmp102_mC_to_reg(int val) 77 80 { 78 81 return (val * 128) / 1000; 79 82 } ··· 90 91 struct tmp102 *tmp102 = i2c_get_clientdata(client); 91 92 92 93 mutex_lock(&tmp102->lock); 93 - if (time_after(jiffies, tmp102->last_update + HZ / 4)) { 94 + if (time_after(jiffies, tmp102->last_update + HZ / 3)) { 94 95 int i; 95 96 for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { 96 97 int status = tmp102_read_reg(client, tmp102_reg[i]); ··· 121 122 struct i2c_client *client = to_i2c_client(dev); 122 123 struct tmp102 *tmp102 = i2c_get_clientdata(client); 123 124 long val; 124 - int status = 0; 125 + int status; 125 126 126 - if ((strict_strtol(buf, 10, &val) < 0) || (abs(val) > 150000)) 127 + if (strict_strtol(buf, 10, &val) < 0) 127 128 return -EINVAL; 129 + val = SENSORS_LIMIT(val, -256000, 255000); 130 + 128 131 mutex_lock(&tmp102->lock); 129 - if (tmp102->temp[sda->index] != val) { 130 - tmp102->temp[sda->index] = val; 131 - status = tmp102_write_reg(client, tmp102_reg[sda->index], 132 - tmp102_mC_to_reg(val)); 133 - } 132 + tmp102->temp[sda->index] = val; 133 + status = tmp102_write_reg(client, tmp102_reg[sda->index], 134 + tmp102_mC_to_reg(val)); 134 135 mutex_unlock(&tmp102->lock); 135 136 return status ? : count; 136 137 } ··· 163 164 struct tmp102 *tmp102; 164 165 int status; 165 166 166 - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | 167 + if (!i2c_check_functionality(client->adapter, 167 168 I2C_FUNC_SMBUS_WORD_DATA)) { 168 - dev_dbg(&client->dev, "adapter doesnt support SMBUS\n"); 169 + dev_err(&client->dev, "adapter doesnt support SMBus word " 170 + "transactions\n"); 169 171 return -ENODEV; 170 172 } 171 173 ··· 177 177 } 178 178 i2c_set_clientdata(client, tmp102); 179 179 180 - tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); 180 + status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); 181 + if (status < 0) { 182 + dev_err(&client->dev, "error writing config register\n"); 183 + goto fail0; 184 + } 181 185 status = tmp102_read_reg(client, TMP102_CONF_REG); 182 186 if (status < 0) { 183 - dev_dbg(&client->dev, "error reading config register\n"); 187 + dev_err(&client->dev, "error reading config register\n"); 184 188 goto fail0; 185 189 } 186 190 status &= ~TMP102_CONFIG_RD_ONLY; 187 191 if (status != TMP102_CONFIG) { 188 - dev_dbg(&client->dev, "could not verify config settings\n"); 189 - status = -EIO; 192 + dev_err(&client->dev, "config settings did not stick\n"); 193 + status = -ENODEV; 190 194 goto fail0; 191 195 } 192 196 tmp102->last_update = jiffies - HZ; ··· 217 213 i2c_set_clientdata(client, NULL); 218 214 kfree(tmp102); 219 215 220 - return 0; 216 + return status; 221 217 } 222 218 223 219 static int __devexit tmp102_remove(struct i2c_client *client) ··· 264 260 #define TMP102_DEV_PM_OPS NULL 265 261 #endif /* CONFIG_PM */ 266 262 267 - static const unsigned short normal_i2c[] = { 268 - 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END 269 - }; 270 - 271 263 static const struct i2c_device_id tmp102_id[] = { 272 - { DRIVER_NAME, 0 }, 264 + { "tmp102", 0 }, 273 265 { } 274 266 }; 267 + MODULE_DEVICE_TABLE(i2c, tmp102_id); 275 268 276 269 static struct i2c_driver tmp102_driver = { 277 270 .driver.name = DRIVER_NAME, 278 271 .driver.pm = TMP102_DEV_PM_OPS, 279 - .class = I2C_CLASS_HWMON, 280 272 .probe = tmp102_probe, 281 273 .remove = __devexit_p(tmp102_remove), 282 274 .id_table = tmp102_id, 283 - .address_list = normal_i2c, 284 275 }; 285 276 286 277 static int __init tmp102_init(void) ··· 289 290 i2c_del_driver(&tmp102_driver); 290 291 } 291 292 module_exit(tmp102_exit); 292 - 293 293 294 294 MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); 295 295 MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver");