aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adm1021.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/adm1021.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/adm1021.c')
-rw-r--r--drivers/hwmon/adm1021.c117
1 files changed, 54 insertions, 63 deletions
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index fd1d1b15854..1ad0a885c5a 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -1,23 +1,23 @@
1/* 1/*
2 * adm1021.c - Part of lm_sensors, Linux kernel modules for hardware 2 adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
3 * monitoring 3 monitoring
4 * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and 4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
5 * Philip Edelbrock <phil@netroedge.com> 5 Philip Edelbrock <phil@netroedge.com>
6 * 6
7 * This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version. 10 (at your option) any later version.
11 * 11
12 * This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 GNU General Public License for more details.
16 * 16
17 * You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 20*/
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/init.h> 23#include <linux/init.h>
@@ -70,12 +70,10 @@ enum chips {
70 70
71/* Initial values */ 71/* Initial values */
72 72
73/* 73/* Note: Even though I left the low and high limits named os and hyst,
74 * Note: Even though I left the low and high limits named os and hyst, 74they don't quite work like a thermostat the way the LM75 does. I.e.,
75 * they don't quite work like a thermostat the way the LM75 does. I.e., 75a lower temp than THYST actually triggers an alarm instead of
76 * a lower temp than THYST actually triggers an alarm instead of 76clearing it. Weird, ey? --Phil */
77 * clearing it. Weird, ey? --Phil
78 */
79 77
80/* Each client has this additional data */ 78/* Each client has this additional data */
81struct adm1021_data { 79struct adm1021_data {
@@ -105,7 +103,7 @@ static int adm1021_remove(struct i2c_client *client);
105static struct adm1021_data *adm1021_update_device(struct device *dev); 103static struct adm1021_data *adm1021_update_device(struct device *dev);
106 104
107/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */ 105/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
108static bool read_only; 106static int read_only;
109 107
110 108
111static const struct i2c_device_id adm1021_id[] = { 109static const struct i2c_device_id adm1021_id[] = {
@@ -184,13 +182,7 @@ static ssize_t set_temp_max(struct device *dev,
184 int index = to_sensor_dev_attr(devattr)->index; 182 int index = to_sensor_dev_attr(devattr)->index;
185 struct i2c_client *client = to_i2c_client(dev); 183 struct i2c_client *client = to_i2c_client(dev);
186 struct adm1021_data *data = i2c_get_clientdata(client); 184 struct adm1021_data *data = i2c_get_clientdata(client);
187 long temp; 185 long temp = simple_strtol(buf, NULL, 10) / 1000;
188 int err;
189
190 err = kstrtol(buf, 10, &temp);
191 if (err)
192 return err;
193 temp /= 1000;
194 186
195 mutex_lock(&data->update_lock); 187 mutex_lock(&data->update_lock);
196 data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127); 188 data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
@@ -209,13 +201,7 @@ static ssize_t set_temp_min(struct device *dev,
209 int index = to_sensor_dev_attr(devattr)->index; 201 int index = to_sensor_dev_attr(devattr)->index;
210 struct i2c_client *client = to_i2c_client(dev); 202 struct i2c_client *client = to_i2c_client(dev);
211 struct adm1021_data *data = i2c_get_clientdata(client); 203 struct adm1021_data *data = i2c_get_clientdata(client);
212 long temp; 204 long temp = simple_strtol(buf, NULL, 10) / 1000;
213 int err;
214
215 err = kstrtol(buf, 10, &temp);
216 if (err)
217 return err;
218 temp /= 1000;
219 205
220 mutex_lock(&data->update_lock); 206 mutex_lock(&data->update_lock);
221 data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127); 207 data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
@@ -240,14 +226,7 @@ static ssize_t set_low_power(struct device *dev,
240{ 226{
241 struct i2c_client *client = to_i2c_client(dev); 227 struct i2c_client *client = to_i2c_client(dev);
242 struct adm1021_data *data = i2c_get_clientdata(client); 228 struct adm1021_data *data = i2c_get_clientdata(client);
243 char low_power; 229 int low_power = simple_strtol(buf, NULL, 10) != 0;
244 unsigned long val;
245 int err;
246
247 err = kstrtoul(buf, 10, &val);
248 if (err)
249 return err;
250 low_power = val != 0;
251 230
252 mutex_lock(&data->update_lock); 231 mutex_lock(&data->update_lock);
253 if (low_power != data->low_power) { 232 if (low_power != data->low_power) {
@@ -366,11 +345,11 @@ static int adm1021_probe(struct i2c_client *client,
366 struct adm1021_data *data; 345 struct adm1021_data *data;
367 int err; 346 int err;
368 347
369 data = devm_kzalloc(&client->dev, sizeof(struct adm1021_data), 348 data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL);
370 GFP_KERNEL);
371 if (!data) { 349 if (!data) {
372 pr_debug("adm1021: detect failed, devm_kzalloc failed!\n"); 350 pr_debug("adm1021: detect failed, kzalloc failed!\n");
373 return -ENOMEM; 351 err = -ENOMEM;
352 goto error0;
374 } 353 }
375 354
376 i2c_set_clientdata(client, data); 355 i2c_set_clientdata(client, data);
@@ -382,20 +361,22 @@ static int adm1021_probe(struct i2c_client *client,
382 adm1021_init_client(client); 361 adm1021_init_client(client);
383 362
384 /* Register sysfs hooks */ 363 /* Register sysfs hooks */
385 err = sysfs_create_group(&client->dev.kobj, &adm1021_group); 364 if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
386 if (err) 365 goto error1;
387 return err;
388 366
389 data->hwmon_dev = hwmon_device_register(&client->dev); 367 data->hwmon_dev = hwmon_device_register(&client->dev);
390 if (IS_ERR(data->hwmon_dev)) { 368 if (IS_ERR(data->hwmon_dev)) {
391 err = PTR_ERR(data->hwmon_dev); 369 err = PTR_ERR(data->hwmon_dev);
392 goto error; 370 goto error3;
393 } 371 }
394 372
395 return 0; 373 return 0;
396 374
397error: 375error3:
398 sysfs_remove_group(&client->dev.kobj, &adm1021_group); 376 sysfs_remove_group(&client->dev.kobj, &adm1021_group);
377error1:
378 kfree(data);
379error0:
399 return err; 380 return err;
400} 381}
401 382
@@ -415,6 +396,7 @@ static int adm1021_remove(struct i2c_client *client)
415 hwmon_device_unregister(data->hwmon_dev); 396 hwmon_device_unregister(data->hwmon_dev);
416 sysfs_remove_group(&client->dev.kobj, &adm1021_group); 397 sysfs_remove_group(&client->dev.kobj, &adm1021_group);
417 398
399 kfree(data);
418 return 0; 400 return 0;
419} 401}
420 402
@@ -445,10 +427,8 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
445 data->alarms = i2c_smbus_read_byte_data(client, 427 data->alarms = i2c_smbus_read_byte_data(client,
446 ADM1021_REG_STATUS) & 0x7c; 428 ADM1021_REG_STATUS) & 0x7c;
447 if (data->type == adm1023) { 429 if (data->type == adm1023) {
448 /* 430 /* The ADM1023 provides 3 extra bits of precision for
449 * The ADM1023 provides 3 extra bits of precision for 431 * the remote sensor in extra registers. */
450 * the remote sensor in extra registers.
451 */
452 data->temp[1] += 125 * (i2c_smbus_read_byte_data( 432 data->temp[1] += 125 * (i2c_smbus_read_byte_data(
453 client, ADM1023_REG_REM_TEMP_PREC) >> 5); 433 client, ADM1023_REG_REM_TEMP_PREC) >> 5);
454 data->temp_max[1] += 125 * (i2c_smbus_read_byte_data( 434 data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
@@ -471,12 +451,23 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
471 return data; 451 return data;
472} 452}
473 453
474module_i2c_driver(adm1021_driver); 454static int __init sensors_adm1021_init(void)
455{
456 return i2c_add_driver(&adm1021_driver);
457}
458
459static void __exit sensors_adm1021_exit(void)
460{
461 i2c_del_driver(&adm1021_driver);
462}
475 463
476MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and " 464MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and "
477 "Philip Edelbrock <phil@netroedge.com>"); 465 "Philip Edelbrock <phil@netroedge.com>");
478MODULE_DESCRIPTION("adm1021 driver"); 466MODULE_DESCRIPTION("adm1021 driver");
479MODULE_LICENSE("GPL"); 467MODULE_LICENSE("GPL");
480 468
481module_param(read_only, bool, 0); 469module_param(read_only, bool, 0);
482MODULE_PARM_DESC(read_only, "Don't set any values, read only mode"); 470MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
471
472module_init(sensors_adm1021_init)
473module_exit(sensors_adm1021_exit)