forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Cc: Steven King <[email protected]>
- Loading branch information
Jean Delvare
committed
May 27, 2010
1 parent
beb1b6b
commit cff37c9
Showing
3 changed files
with
39 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
/* Texas Instruments TMP102 SMBUS temperature sensor driver | ||
/* Texas Instruments TMP102 SMBus temperature sensor driver | ||
* | ||
* Copyright 2010 Steven King <[email protected]> | ||
* Copyright (C) 2010 Steven King <[email protected]> | ||
* | ||
* 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 | ||
|
@@ -17,8 +17,6 @@ | |
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
|
||
|
||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/slab.h> | ||
|
@@ -27,7 +25,7 @@ | |
#include <linux/hwmon-sysfs.h> | ||
#include <linux/err.h> | ||
#include <linux/mutex.h> | ||
#include <linux/delay.h> | ||
#include <linux/device.h> | ||
|
||
#define DRIVER_NAME "tmp102" | ||
|
||
|
@@ -56,26 +54,27 @@ struct tmp102 { | |
int temp[3]; | ||
}; | ||
|
||
/* the TMP102 registers are big endian so we have to swab16 the values */ | ||
static int tmp102_read_reg(struct i2c_client *client, u8 reg) | ||
/* SMBus specifies low byte first, but the TMP102 returns high byte first, | ||
* so we have to swab16 the values */ | ||
static inline int tmp102_read_reg(struct i2c_client *client, u8 reg) | ||
{ | ||
int result = i2c_smbus_read_word_data(client, reg); | ||
return result < 0 ? result : swab16(result); | ||
} | ||
|
||
static int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) | ||
static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) | ||
{ | ||
return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
} | ||
|
||
/* convert left adjusted 13bit TMP102 register value to miliCelsius */ | ||
static int tmp102_reg_to_mC(s16 val) | ||
/* convert left adjusted 13-bit TMP102 register value to milliCelsius */ | ||
static inline int tmp102_reg_to_mC(s16 val) | ||
{ | ||
return (val * 1000) / 128; | ||
return ((val & ~0x01) * 1000) / 128; | ||
} | ||
|
||
/* convert miliCelsius to left adjusted 13bit TMP102 register value */ | ||
static u16 tmp102_mC_to_reg(int val) | ||
/* convert milliCelsius to left adjusted 13-bit TMP102 register value */ | ||
static inline u16 tmp102_mC_to_reg(int val) | ||
{ | ||
return (val * 128) / 1000; | ||
} | ||
|
@@ -91,7 +90,7 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client) | |
struct tmp102 *tmp102 = i2c_get_clientdata(client); | ||
|
||
mutex_lock(&tmp102->lock); | ||
if (time_after(jiffies, tmp102->last_update + HZ / 4)) { | ||
if (time_after(jiffies, tmp102->last_update + HZ / 3)) { | ||
int i; | ||
for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { | ||
int status = tmp102_read_reg(client, tmp102_reg[i]); | ||
|
@@ -122,16 +121,16 @@ static ssize_t tmp102_set_temp(struct device *dev, | |
struct i2c_client *client = to_i2c_client(dev); | ||
struct tmp102 *tmp102 = i2c_get_clientdata(client); | ||
long val; | ||
int status = 0; | ||
int status; | ||
|
||
if ((strict_strtol(buf, 10, &val) < 0) || (abs(val) > 150000)) | ||
if (strict_strtol(buf, 10, &val) < 0) | ||
return -EINVAL; | ||
val = SENSORS_LIMIT(val, -256000, 255000); | ||
|
||
mutex_lock(&tmp102->lock); | ||
if (tmp102->temp[sda->index] != val) { | ||
tmp102->temp[sda->index] = val; | ||
status = tmp102_write_reg(client, tmp102_reg[sda->index], | ||
tmp102_mC_to_reg(val)); | ||
} | ||
tmp102->temp[sda->index] = val; | ||
status = tmp102_write_reg(client, tmp102_reg[sda->index], | ||
tmp102_mC_to_reg(val)); | ||
mutex_unlock(&tmp102->lock); | ||
return status ? : count; | ||
} | ||
|
@@ -164,9 +163,10 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |
struct tmp102 *tmp102; | ||
int status; | ||
|
||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | | ||
if (!i2c_check_functionality(client->adapter, | ||
I2C_FUNC_SMBUS_WORD_DATA)) { | ||
dev_dbg(&client->dev, "adapter doesnt support SMBUS\n"); | ||
dev_err(&client->dev, "adapter doesnt support SMBus word " | ||
"transactions\n"); | ||
return -ENODEV; | ||
} | ||
|
||
|
@@ -177,16 +177,20 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |
} | ||
i2c_set_clientdata(client, tmp102); | ||
|
||
tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); | ||
status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); | ||
if (status < 0) { | ||
dev_err(&client->dev, "error writing config register\n"); | ||
goto fail0; | ||
} | ||
status = tmp102_read_reg(client, TMP102_CONF_REG); | ||
if (status < 0) { | ||
dev_dbg(&client->dev, "error reading config register\n"); | ||
dev_err(&client->dev, "error reading config register\n"); | ||
goto fail0; | ||
} | ||
status &= ~TMP102_CONFIG_RD_ONLY; | ||
if (status != TMP102_CONFIG) { | ||
dev_dbg(&client->dev, "could not verify config settings\n"); | ||
status = -EIO; | ||
dev_err(&client->dev, "config settings did not stick\n"); | ||
status = -ENODEV; | ||
goto fail0; | ||
} | ||
tmp102->last_update = jiffies - HZ; | ||
|
@@ -213,7 +217,7 @@ static int __devinit tmp102_probe(struct i2c_client *client, | |
i2c_set_clientdata(client, NULL); | ||
kfree(tmp102); | ||
|
||
return 0; | ||
return status; | ||
} | ||
|
||
static int __devexit tmp102_remove(struct i2c_client *client) | ||
|
@@ -260,23 +264,18 @@ static const struct dev_pm_ops tmp102_dev_pm_ops = { | |
#define TMP102_DEV_PM_OPS NULL | ||
#endif /* CONFIG_PM */ | ||
|
||
static const unsigned short normal_i2c[] = { | ||
0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END | ||
}; | ||
|
||
static const struct i2c_device_id tmp102_id[] = { | ||
{ DRIVER_NAME, 0 }, | ||
{ "tmp102", 0 }, | ||
{ } | ||
}; | ||
MODULE_DEVICE_TABLE(i2c, tmp102_id); | ||
|
||
static struct i2c_driver tmp102_driver = { | ||
.driver.name = DRIVER_NAME, | ||
.driver.pm = TMP102_DEV_PM_OPS, | ||
.class = I2C_CLASS_HWMON, | ||
.probe = tmp102_probe, | ||
.remove = __devexit_p(tmp102_remove), | ||
.id_table = tmp102_id, | ||
.address_list = normal_i2c, | ||
}; | ||
|
||
static int __init tmp102_init(void) | ||
|
@@ -291,7 +290,6 @@ static void __exit tmp102_exit(void) | |
} | ||
module_exit(tmp102_exit); | ||
|
||
|
||
MODULE_AUTHOR("Steven King <[email protected]>"); | ||
MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); | ||
MODULE_LICENSE("GPL"); |