aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/tmp102.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/tmp102.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/tmp102.c')
-rw-r--r--drivers/hwmon/tmp102.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index b10c3d36ccb..5bd19496880 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -26,7 +26,6 @@
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/jiffies.h>
30 29
31#define DRIVER_NAME "tmp102" 30#define DRIVER_NAME "tmp102"
32 31
@@ -56,6 +55,19 @@ struct tmp102 {
56 int temp[3]; 55 int temp[3];
57}; 56};
58 57
58/* SMBus specifies low byte first, but the TMP102 returns high byte first,
59 * so we have to swab16 the values */
60static inline int tmp102_read_reg(struct i2c_client *client, u8 reg)
61{
62 int result = i2c_smbus_read_word_data(client, reg);
63 return result < 0 ? result : swab16(result);
64}
65
66static inline int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val)
67{
68 return i2c_smbus_write_word_data(client, reg, swab16(val));
69}
70
59/* convert left adjusted 13-bit TMP102 register value to milliCelsius */ 71/* convert left adjusted 13-bit TMP102 register value to milliCelsius */
60static inline int tmp102_reg_to_mC(s16 val) 72static inline int tmp102_reg_to_mC(s16 val)
61{ 73{
@@ -82,8 +94,7 @@ static struct tmp102 *tmp102_update_device(struct i2c_client *client)
82 if (time_after(jiffies, tmp102->last_update + HZ / 3)) { 94 if (time_after(jiffies, tmp102->last_update + HZ / 3)) {
83 int i; 95 int i;
84 for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { 96 for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) {
85 int status = i2c_smbus_read_word_swapped(client, 97 int status = tmp102_read_reg(client, tmp102_reg[i]);
86 tmp102_reg[i]);
87 if (status > -1) 98 if (status > -1)
88 tmp102->temp[i] = tmp102_reg_to_mC(status); 99 tmp102->temp[i] = tmp102_reg_to_mC(status);
89 } 100 }
@@ -113,14 +124,14 @@ static ssize_t tmp102_set_temp(struct device *dev,
113 long val; 124 long val;
114 int status; 125 int status;
115 126
116 if (kstrtol(buf, 10, &val) < 0) 127 if (strict_strtol(buf, 10, &val) < 0)
117 return -EINVAL; 128 return -EINVAL;
118 val = SENSORS_LIMIT(val, -256000, 255000); 129 val = SENSORS_LIMIT(val, -256000, 255000);
119 130
120 mutex_lock(&tmp102->lock); 131 mutex_lock(&tmp102->lock);
121 tmp102->temp[sda->index] = val; 132 tmp102->temp[sda->index] = val;
122 status = i2c_smbus_write_word_swapped(client, tmp102_reg[sda->index], 133 status = tmp102_write_reg(client, tmp102_reg[sda->index],
123 tmp102_mC_to_reg(val)); 134 tmp102_mC_to_reg(val));
124 mutex_unlock(&tmp102->lock); 135 mutex_unlock(&tmp102->lock);
125 return status ? : count; 136 return status ? : count;
126} 137}
@@ -147,7 +158,7 @@ static const struct attribute_group tmp102_attr_group = {
147#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) 158#define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1)
148#define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) 159#define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL)
149 160
150static int tmp102_probe(struct i2c_client *client, 161static int __devinit tmp102_probe(struct i2c_client *client,
151 const struct i2c_device_id *id) 162 const struct i2c_device_id *id)
152{ 163{
153 struct tmp102 *tmp102; 164 struct tmp102 *tmp102;
@@ -160,25 +171,25 @@ static int tmp102_probe(struct i2c_client *client,
160 return -ENODEV; 171 return -ENODEV;
161 } 172 }
162 173
163 tmp102 = devm_kzalloc(&client->dev, sizeof(*tmp102), GFP_KERNEL); 174 tmp102 = kzalloc(sizeof(*tmp102), GFP_KERNEL);
164 if (!tmp102) 175 if (!tmp102) {
176 dev_dbg(&client->dev, "kzalloc failed\n");
165 return -ENOMEM; 177 return -ENOMEM;
166 178 }
167 i2c_set_clientdata(client, tmp102); 179 i2c_set_clientdata(client, tmp102);
168 180
169 status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); 181 status = tmp102_read_reg(client, TMP102_CONF_REG);
170 if (status < 0) { 182 if (status < 0) {
171 dev_err(&client->dev, "error reading config register\n"); 183 dev_err(&client->dev, "error reading config register\n");
172 return status; 184 goto fail_free;
173 } 185 }
174 tmp102->config_orig = status; 186 tmp102->config_orig = status;
175 status = i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, 187 status = tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG);
176 TMP102_CONFIG);
177 if (status < 0) { 188 if (status < 0) {
178 dev_err(&client->dev, "error writing config register\n"); 189 dev_err(&client->dev, "error writing config register\n");
179 goto fail_restore_config; 190 goto fail_restore_config;
180 } 191 }
181 status = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); 192 status = tmp102_read_reg(client, TMP102_CONF_REG);
182 if (status < 0) { 193 if (status < 0) {
183 dev_err(&client->dev, "error reading config register\n"); 194 dev_err(&client->dev, "error reading config register\n");
184 goto fail_restore_config; 195 goto fail_restore_config;
@@ -211,12 +222,14 @@ static int tmp102_probe(struct i2c_client *client,
211fail_remove_sysfs: 222fail_remove_sysfs:
212 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); 223 sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group);
213fail_restore_config: 224fail_restore_config:
214 i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, 225 tmp102_write_reg(client, TMP102_CONF_REG, tmp102->config_orig);
215 tmp102->config_orig); 226fail_free:
227 kfree(tmp102);
228
216 return status; 229 return status;
217} 230}
218 231
219static int tmp102_remove(struct i2c_client *client) 232static int __devexit tmp102_remove(struct i2c_client *client)
220{ 233{
221 struct tmp102 *tmp102 = i2c_get_clientdata(client); 234 struct tmp102 *tmp102 = i2c_get_clientdata(client);
222 235
@@ -227,12 +240,14 @@ static int tmp102_remove(struct i2c_client *client)
227 if (tmp102->config_orig & TMP102_CONF_SD) { 240 if (tmp102->config_orig & TMP102_CONF_SD) {
228 int config; 241 int config;
229 242
230 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); 243 config = tmp102_read_reg(client, TMP102_CONF_REG);
231 if (config >= 0) 244 if (config >= 0)
232 i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, 245 tmp102_write_reg(client, TMP102_CONF_REG,
233 config | TMP102_CONF_SD); 246 config | TMP102_CONF_SD);
234 } 247 }
235 248
249 kfree(tmp102);
250
236 return 0; 251 return 0;
237} 252}
238 253
@@ -242,12 +257,12 @@ static int tmp102_suspend(struct device *dev)
242 struct i2c_client *client = to_i2c_client(dev); 257 struct i2c_client *client = to_i2c_client(dev);
243 int config; 258 int config;
244 259
245 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); 260 config = tmp102_read_reg(client, TMP102_CONF_REG);
246 if (config < 0) 261 if (config < 0)
247 return config; 262 return config;
248 263
249 config |= TMP102_CONF_SD; 264 config |= TMP102_CONF_SD;
250 return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config); 265 return tmp102_write_reg(client, TMP102_CONF_REG, config);
251} 266}
252 267
253static int tmp102_resume(struct device *dev) 268static int tmp102_resume(struct device *dev)
@@ -255,12 +270,12 @@ static int tmp102_resume(struct device *dev)
255 struct i2c_client *client = to_i2c_client(dev); 270 struct i2c_client *client = to_i2c_client(dev);
256 int config; 271 int config;
257 272
258 config = i2c_smbus_read_word_swapped(client, TMP102_CONF_REG); 273 config = tmp102_read_reg(client, TMP102_CONF_REG);
259 if (config < 0) 274 if (config < 0)
260 return config; 275 return config;
261 276
262 config &= ~TMP102_CONF_SD; 277 config &= ~TMP102_CONF_SD;
263 return i2c_smbus_write_word_swapped(client, TMP102_CONF_REG, config); 278 return tmp102_write_reg(client, TMP102_CONF_REG, config);
264} 279}
265 280
266static const struct dev_pm_ops tmp102_dev_pm_ops = { 281static const struct dev_pm_ops tmp102_dev_pm_ops = {
@@ -283,11 +298,21 @@ static struct i2c_driver tmp102_driver = {
283 .driver.name = DRIVER_NAME, 298 .driver.name = DRIVER_NAME,
284 .driver.pm = TMP102_DEV_PM_OPS, 299 .driver.pm = TMP102_DEV_PM_OPS,
285 .probe = tmp102_probe, 300 .probe = tmp102_probe,
286 .remove = tmp102_remove, 301 .remove = __devexit_p(tmp102_remove),
287 .id_table = tmp102_id, 302 .id_table = tmp102_id,
288}; 303};
289 304
290module_i2c_driver(tmp102_driver); 305static int __init tmp102_init(void)
306{
307 return i2c_add_driver(&tmp102_driver);
308}
309module_init(tmp102_init);
310
311static void __exit tmp102_exit(void)
312{
313 i2c_del_driver(&tmp102_driver);
314}
315module_exit(tmp102_exit);
291 316
292MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); 317MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
293MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); 318MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver");