[lm-sensors] [PATCH] adt746x compatibile with lm_sensors
DaNiMoTh
jjdanimoth at gmail.com
Thu Apr 9 14:50:26 CEST 2009
Hello to all,
After the first attempt to make a better driver for adt746x, I follow
what Jean said to me.
So, there is a patch for the actual adt746x driver that move the sysfs
attributes from /sys/devices/temperature to /sys/class/hwmon/ and also
it renames the old attributes (ex. from sensor1_temperature to
temp1_input).
As result, now I'm able to see two temperatures and two fan speed from
lm_sensors.
I tested it on adt7467 chip, I have only a compile warning about the
deprecation of attach and detach method. I've tried to use the new
style, but I've some trouble on detecting and probing device ( more
specifically, i2c-core compares the name of only 2 things - "tas audio
codec" and "ams" - and not the "uni-n 1", and also don't scan any
address, because in the comparison of the class of driver, adt746x
have 1 ( I2c_CLASS_HWMON ), but the driver in the kernel have 0. This
could be a things related to powerpc, and I'm searching a man that
knows in what direction I need to move )
This driver has all of the old limitations ( like it is impossible to
set device parameters at runtime, except the fan speed, doesn't
control the pwm, etc. ).
Thanks
----
Moved the sysfs attribute to the standard location (/sys/class/hwmon/..)
and renamed accordingly to new sysfs standard names,
to make the temperature and fan speed visible from lm_sensors.
Signed-off-by: Natale Patriciello <jjdanimoth at gmail.com>
---
drivers/macintosh/therm_adt746x.c | 150 ++++++++++++++++++++----------------
1 files changed, 83 insertions(+), 67 deletions(-)
diff --git a/drivers/macintosh/therm_adt746x.c
b/drivers/macintosh/therm_adt746x.c
index 82607ad..63c23ad 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -3,6 +3,10 @@
*
* Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
*
+ * 2009-04-09 Natale Patriciello <jjdanimoth at gmail.com>:
+ * - Added new hwmon sysfs attribute's schema
+ * - Removed the old schema
+ *
* Documentation from
* http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf
* http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf
@@ -25,6 +29,8 @@
#include <linux/moduleparam.h>
#include <linux/freezer.h>
#include <linux/of_platform.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
#include <asm/prom.h>
#include <asm/machdep.h>
@@ -72,6 +78,8 @@ MODULE_PARM_DESC(verbose,"Verbose log operations "
struct thermostat {
struct i2c_client clt;
+ struct device *hwmon_dev;
+ struct attribute_group attrs;
u8 temps[3];
u8 cached_temp[3];
u8 initial_limits[3];
@@ -85,6 +93,7 @@ static int therm_bus, therm_address;
static struct of_device * of_dev;
static struct thermostat* thermostat;
static struct task_struct *thread_therm = NULL;
+static struct attribute *adt746x_attr[];
static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
int busno);
@@ -165,6 +174,9 @@ detach_thermostat(struct i2c_adapter *adapter)
write_both_fan_speed(th, -1);
+ hwmon_device_unregister(thermostat->hwmon_dev);
+ sysfs_remove_group(&thermostat->clt.dev.kobj, &thermostat->attrs);
+
i2c_detach_client(&th->clt);
thermostat = NULL;
@@ -374,7 +386,7 @@ static int attach_one_thermostat(struct
i2c_adapter *adapter, int addr,
{
struct thermostat* th;
int rc;
- int i;
+ int i, err;
if (thermostat)
return 0;
@@ -393,8 +405,8 @@ static int attach_one_thermostat(struct
i2c_adapter *adapter, int addr,
printk(KERN_ERR "adt746x: Thermostat failed to read config "
"from bus %d !\n",
busno);
- kfree(th);
- return -ENODEV;
+ err = -ENODEV;
+ goto error_kfree;
}
/* force manual control to start the fan quieter */
@@ -424,9 +436,8 @@ static int attach_one_thermostat(struct
i2c_adapter *adapter, int addr,
if (i2c_attach_client(&th->clt)) {
printk(KERN_INFO "adt746x: Thermostat failed to attach "
"client !\n");
- thermostat = NULL;
- kfree(th);
- return -ENODEV;
+ err = -ENODEV;
+ goto error_kfree;
}
/* be sure to really write fan speed the first time */
@@ -447,11 +458,33 @@ static int attach_one_thermostat(struct
i2c_adapter *adapter, int addr,
if (thread_therm == ERR_PTR(-ENOMEM)) {
printk(KERN_INFO "adt746x: Kthread creation failed\n");
- thread_therm = NULL;
- return -ENOMEM;
+ err = -ENOMEM;
+ goto error_ktherm;
+ }
+
+ /* Register sysfs hooks */
+ thermostat->attrs.attrs = adt746x_attr;
+ if (sysfs_create_group(&thermostat->clt.dev.kobj, &thermostat->attrs))
+ printk(KERN_WARNING
+ "Failed to create tempertaure attribute file(s).\n");
+
+ thermostat->hwmon_dev = hwmon_device_register(&thermostat->clt.dev);
+ if (IS_ERR(thermostat->hwmon_dev)) {
+ err = PTR_ERR(thermostat->hwmon_dev);
+ goto error_hwmon;
}
return 0;
+
+error_hwmon:
+ kthread_stop(thread_therm);
+error_ktherm:
+ thread_therm = NULL;
+ i2c_detach_client(&th->clt);
+error_kfree:
+ kfree(th);
+ thermostat = NULL;
+ return err;
}
/*
@@ -464,7 +497,7 @@ static int attach_one_thermostat(struct
i2c_adapter *adapter, int addr,
#define BUILD_SHOW_FUNC_INT(name, data) \
static ssize_t show_##name(struct device *dev, struct
device_attribute *attr, char *buf) \
{ \
- return sprintf(buf, "%d\n", data); \
+ return sprintf(buf, "%d\n", 1000 * data); \
}
#define BUILD_SHOW_FUNC_STR(name, data) \
@@ -476,8 +509,7 @@ static ssize_t show_##name(struct device *dev,
struct device_attribute *attr, ch
#define BUILD_SHOW_FUNC_FAN(name, data) \
static ssize_t show_##name(struct device *dev, struct
device_attribute *attr, char *buf) \
{ \
- return sprintf(buf, "%d (%d rpm)\n", \
- thermostat->last_speed[data], \
+ return sprintf(buf, "%d\n", \
read_fan_speed(thermostat, FAN_SPEED[data]) \
); \
}
@@ -507,45 +539,59 @@ static ssize_t store_##name(struct device *dev,
struct device_attribute *attr, c
return n; \
}
-BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(thermostat, TEMP_REG[1])))
-BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(thermostat, TEMP_REG[2])))
-BUILD_SHOW_FUNC_INT(sensor1_limit, thermostat->limits[1])
-BUILD_SHOW_FUNC_INT(sensor2_limit, thermostat->limits[2])
-BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1])
-BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2])
+BUILD_SHOW_FUNC_INT(temp1_input, (read_reg(thermostat, TEMP_REG[1])))
+BUILD_SHOW_FUNC_INT(temp2_input, (read_reg(thermostat, TEMP_REG[2])))
+BUILD_SHOW_FUNC_INT(temp1_max, thermostat->limits[1])
+BUILD_SHOW_FUNC_INT(temp2_max, thermostat->limits[2])
+BUILD_SHOW_FUNC_STR(temp1_label, sensor_location[1])
+BUILD_SHOW_FUNC_STR(temp2_label, sensor_location[2])
BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed)
-BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0)
-BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1)
+BUILD_SHOW_FUNC_FAN(fan1_input, 0)
+BUILD_SHOW_FUNC_FAN(fan2_input, 1)
BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust)
BUILD_STORE_FUNC_DEG(limit_adjust, thermostat)
-static DEVICE_ATTR(sensor1_temperature, S_IRUGO,
- show_sensor1_temperature,NULL);
-static DEVICE_ATTR(sensor2_temperature, S_IRUGO,
- show_sensor2_temperature,NULL);
-static DEVICE_ATTR(sensor1_limit, S_IRUGO,
- show_sensor1_limit, NULL);
-static DEVICE_ATTR(sensor2_limit, S_IRUGO,
- show_sensor2_limit, NULL);
-static DEVICE_ATTR(sensor1_location, S_IRUGO,
- show_sensor1_location, NULL);
-static DEVICE_ATTR(sensor2_location, S_IRUGO,
- show_sensor2_location, NULL);
+static DEVICE_ATTR(temp1_input, S_IRUGO,
+ show_temp1_input,NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO,
+ show_temp2_input,NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO,
+ show_temp1_max, NULL);
+static DEVICE_ATTR(temp2_max, S_IRUGO,
+ show_temp2_max, NULL);
+static DEVICE_ATTR(temp1_label, S_IRUGO,
+ show_temp1_label, NULL);
+static DEVICE_ATTR(temp2_label, S_IRUGO,
+ show_temp2_label, NULL);
static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
show_specified_fan_speed,store_specified_fan_speed);
-static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO,
- show_sensor1_fan_speed, NULL);
-static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO,
- show_sensor2_fan_speed, NULL);
+static DEVICE_ATTR(fan1_input, S_IRUGO,
+ show_fan1_input, NULL);
+static DEVICE_ATTR(fan2_input, S_IRUGO,
+ show_fan2_input, NULL);
static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
show_limit_adjust, store_limit_adjust);
+static struct attribute *adt746x_attr[] =
+{
+ &dev_attr_temp1_input.attr,
+ &dev_attr_temp2_input.attr,
+ &dev_attr_temp1_max.attr,
+ &dev_attr_temp2_max.attr,
+ &dev_attr_temp1_label.attr,
+ &dev_attr_temp2_label.attr,
+ &dev_attr_specified_fan_speed.attr,
+ &dev_attr_fan1_input.attr,
+ &dev_attr_fan2_input.attr,
+ &dev_attr_limit_adjust.attr,
+ NULL
+};
static int __init
thermostat_init(void)
@@ -553,7 +599,6 @@ thermostat_init(void)
struct device_node* np;
const u32 *prop;
int i = 0, offset = 0;
- int err;
np = of_find_node_by_name(NULL, "fan");
if (!np)
@@ -620,21 +665,6 @@ thermostat_init(void)
return -ENODEV;
}
- err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
- err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
- err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
- if(therm_type == ADT7460)
- err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
- if (err)
- printk(KERN_WARNING
- "Failed to create tempertaure attribute file(s).\n");
-
#ifndef CONFIG_I2C_POWERMAC
request_module("i2c-powermac");
#endif
@@ -645,23 +675,9 @@ thermostat_init(void)
static void __exit
thermostat_exit(void)
{
- if (of_dev) {
- device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature);
- device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature);
- device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit);
- device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit);
- device_remove_file(&of_dev->dev, &dev_attr_sensor1_location);
- device_remove_file(&of_dev->dev, &dev_attr_sensor2_location);
- device_remove_file(&of_dev->dev, &dev_attr_limit_adjust);
- device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed);
- device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
-
- if(therm_type == ADT7460)
- device_remove_file(&of_dev->dev,
- &dev_attr_sensor2_fan_speed);
-
+ if (of_dev)
of_device_unregister(of_dev);
- }
+
i2c_del_driver(&thermostat_driver);
}
--
1.6.1.3
More information about the lm-sensors
mailing list