aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/emc2103.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/emc2103.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/emc2103.c')
-rw-r--r--drivers/hwmon/emc2103.c99
1 files changed, 52 insertions, 47 deletions
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
index 77f434c5823..af914ad93ec 100644
--- a/drivers/hwmon/emc2103.c
+++ b/drivers/hwmon/emc2103.c
@@ -1,21 +1,21 @@
1/* 1/*
2 * emc2103.c - Support for SMSC EMC2103 2 emc2103.c - Support for SMSC EMC2103
3 * Copyright (c) 2010 SMSC 3 Copyright (c) 2010 SMSC
4 * 4
5 * This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. 8 (at your option) any later version.
9 * 9
10 * This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 GNU General Public License for more details.
14 * 14
15 * You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */ 18*/
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
@@ -48,16 +48,14 @@ static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 };
48/* equation 4 from datasheet: rpm = (3932160 * multipler) / count */ 48/* equation 4 from datasheet: rpm = (3932160 * multipler) / count */
49#define FAN_RPM_FACTOR 3932160 49#define FAN_RPM_FACTOR 3932160
50 50
51/* 51/* 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
52 * 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
53 * in anti-parallel mode, and in this configuration both can be read 52 * in anti-parallel mode, and in this configuration both can be read
54 * independently (so we have 4 temperature inputs). The device can't 53 * independently (so we have 4 temperature inputs). The device can't
55 * detect if it's connected in this mode, so we have to manually enable 54 * detect if it's connected in this mode, so we have to manually enable
56 * it. Default is to leave the device in the state it's already in (-1). 55 * it. Default is to leave the device in the state it's already in (-1).
57 * This parameter allows APD mode to be optionally forced on or off 56 * This parameter allows APD mode to be optionally forced on or off */
58 */
59static int apd = -1; 57static int apd = -1;
60module_param(apd, bint, 0); 58module_param(apd, bool, 0);
61MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode"); 59MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode");
62 60
63struct temperature { 61struct temperature {
@@ -246,7 +244,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *da,
246 struct emc2103_data *data = i2c_get_clientdata(client); 244 struct emc2103_data *data = i2c_get_clientdata(client);
247 long val; 245 long val;
248 246
249 int result = kstrtol(buf, 10, &val); 247 int result = strict_strtol(buf, 10, &val);
250 if (result < 0) 248 if (result < 0)
251 return -EINVAL; 249 return -EINVAL;
252 250
@@ -270,7 +268,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *da,
270 struct emc2103_data *data = i2c_get_clientdata(client); 268 struct emc2103_data *data = i2c_get_clientdata(client);
271 long val; 269 long val;
272 270
273 int result = kstrtol(buf, 10, &val); 271 int result = strict_strtol(buf, 10, &val);
274 if (result < 0) 272 if (result < 0)
275 return -EINVAL; 273 return -EINVAL;
276 274
@@ -304,12 +302,10 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
304 return sprintf(buf, "%d\n", fan_div); 302 return sprintf(buf, "%d\n", fan_div);
305} 303}
306 304
307/* 305/* Note: we also update the fan target here, because its value is
308 * Note: we also update the fan target here, because its value is 306 determined in part by the fan clock divider. This follows the principle
309 * determined in part by the fan clock divider. This follows the principle 307 of least surprise; the user doesn't expect the fan target to change just
310 * of least surprise; the user doesn't expect the fan target to change just 308 because the divider changed. */
311 * because the divider changed.
312 */
313static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, 309static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
314 const char *buf, size_t count) 310 const char *buf, size_t count)
315{ 311{
@@ -318,7 +314,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
318 int new_range_bits, old_div = 8 / data->fan_multiplier; 314 int new_range_bits, old_div = 8 / data->fan_multiplier;
319 long new_div; 315 long new_div;
320 316
321 int status = kstrtol(buf, 10, &new_div); 317 int status = strict_strtol(buf, 10, &new_div);
322 if (status < 0) 318 if (status < 0)
323 return -EINVAL; 319 return -EINVAL;
324 320
@@ -392,7 +388,7 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
392 struct i2c_client *client = to_i2c_client(dev); 388 struct i2c_client *client = to_i2c_client(dev);
393 long rpm_target; 389 long rpm_target;
394 390
395 int result = kstrtol(buf, 10, &rpm_target); 391 int result = strict_strtol(buf, 10, &rpm_target);
396 if (result < 0) 392 if (result < 0)
397 return -EINVAL; 393 return -EINVAL;
398 394
@@ -438,7 +434,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
438 long new_value; 434 long new_value;
439 u8 conf_reg; 435 u8 conf_reg;
440 436
441 int result = kstrtol(buf, 10, &new_value); 437 int result = strict_strtol(buf, 10, &new_value);
442 if (result < 0) 438 if (result < 0)
443 return -EINVAL; 439 return -EINVAL;
444 440
@@ -451,15 +447,11 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
451 data->fan_rpm_control = true; 447 data->fan_rpm_control = true;
452 break; 448 break;
453 default: 449 default:
454 count = -EINVAL; 450 mutex_unlock(&data->update_lock);
455 goto err; 451 return -EINVAL;
456 } 452 }
457 453
458 result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); 454 read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg);
459 if (result) {
460 count = result;
461 goto err;
462 }
463 455
464 if (data->fan_rpm_control) 456 if (data->fan_rpm_control)
465 conf_reg |= 0x80; 457 conf_reg |= 0x80;
@@ -467,7 +459,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
467 conf_reg &= ~0x80; 459 conf_reg &= ~0x80;
468 460
469 i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); 461 i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg);
470err: 462
471 mutex_unlock(&data->update_lock); 463 mutex_unlock(&data->update_lock);
472 return count; 464 return count;
473} 465}
@@ -590,8 +582,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
590 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 582 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
591 return -EIO; 583 return -EIO;
592 584
593 data = devm_kzalloc(&client->dev, sizeof(struct emc2103_data), 585 data = kzalloc(sizeof(struct emc2103_data), GFP_KERNEL);
594 GFP_KERNEL);
595 if (!data) 586 if (!data)
596 return -ENOMEM; 587 return -ENOMEM;
597 588
@@ -609,7 +600,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
609 if (status < 0) { 600 if (status < 0) {
610 dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1, 601 dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1,
611 status); 602 status);
612 return status; 603 goto exit_free;
613 } 604 }
614 605
615 /* detect current state of hardware */ 606 /* detect current state of hardware */
@@ -632,7 +623,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
632 /* Register sysfs hooks */ 623 /* Register sysfs hooks */
633 status = sysfs_create_group(&client->dev.kobj, &emc2103_group); 624 status = sysfs_create_group(&client->dev.kobj, &emc2103_group);
634 if (status) 625 if (status)
635 return status; 626 goto exit_free;
636 627
637 if (data->temp_count >= 3) { 628 if (data->temp_count >= 3) {
638 status = sysfs_create_group(&client->dev.kobj, 629 status = sysfs_create_group(&client->dev.kobj,
@@ -667,6 +658,8 @@ exit_remove_temp3:
667 sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group); 658 sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
668exit_remove: 659exit_remove:
669 sysfs_remove_group(&client->dev.kobj, &emc2103_group); 660 sysfs_remove_group(&client->dev.kobj, &emc2103_group);
661exit_free:
662 kfree(data);
670 return status; 663 return status;
671} 664}
672 665
@@ -684,6 +677,7 @@ static int emc2103_remove(struct i2c_client *client)
684 677
685 sysfs_remove_group(&client->dev.kobj, &emc2103_group); 678 sysfs_remove_group(&client->dev.kobj, &emc2103_group);
686 679
680 kfree(data);
687 return 0; 681 return 0;
688} 682}
689 683
@@ -728,8 +722,19 @@ static struct i2c_driver emc2103_driver = {
728 .address_list = normal_i2c, 722 .address_list = normal_i2c,
729}; 723};
730 724
731module_i2c_driver(emc2103_driver); 725static int __init sensors_emc2103_init(void)
726{
727 return i2c_add_driver(&emc2103_driver);
728}
732 729
733MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>"); 730static void __exit sensors_emc2103_exit(void)
731{
732 i2c_del_driver(&emc2103_driver);
733}
734
735MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
734MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver"); 736MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver");
735MODULE_LICENSE("GPL"); 737MODULE_LICENSE("GPL");
738
739module_init(sensors_emc2103_init);
740module_exit(sensors_emc2103_exit);