1
0
Fork 0

hwmon: lm75: expose to thermal fw via DT nodes

This patch adds to lm75 temperature sensor the possibility
to expose itself as thermal zone device, registered on the
thermal framework.

The thermal zone is built only if a device tree node
describing a thermal zone for this sensor is present
inside the lm75 DT node. Otherwise, the driver behavior
will be the same.

Note: This patch has also been reviewed by Jean D. He has
requested to perform a wider inspection of possible
users of thermal and hwmon interaction API. On the other
hand, the change on this patch is acceptable on first
step of overall code change.

Cc: Jean Delvare <khali@linux-fr.org>
Cc: lm-sensors@lm-sensors.org
Cc: linux-kernel@vger.kernel.org
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
hifive-unleashed-5.1
Eduardo Valentin 2013-07-16 14:54:55 -04:00
parent 77cff5926a
commit 22e731838b
1 changed files with 30 additions and 5 deletions

View File

@ -27,6 +27,8 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/thermal.h>
#include "lm75.h"
@ -71,6 +73,7 @@ static const u8 LM75_REG_TEMP[3] = {
/* Each client has this additional data */
struct lm75_data {
struct device *hwmon_dev;
struct thermal_zone_device *tz;
struct mutex update_lock;
u8 orig_conf;
u8 resolution; /* In bits, between 9 and 12 */
@ -91,22 +94,36 @@ static struct lm75_data *lm75_update_device(struct device *dev);
/*-----------------------------------------------------------------------*/
static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
{
return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
}
/* sysfs attributes for hwmon */
static int lm75_read_temp(void *dev, long *temp)
{
struct lm75_data *data = lm75_update_device(dev);
if (IS_ERR(data))
return PTR_ERR(data);
*temp = lm75_reg_to_mc(data->temp[0], data->resolution);
return 0;
}
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm75_data *data = lm75_update_device(dev);
long temp;
if (IS_ERR(data))
return PTR_ERR(data);
temp = ((data->temp[attr->index] >> (16 - data->resolution)) * 1000)
>> (data->resolution - 8);
return sprintf(buf, "%ld\n", temp);
return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index],
data->resolution));
}
static ssize_t set_temp(struct device *dev, struct device_attribute *da,
@ -273,6 +290,13 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
goto exit_remove;
}
data->tz = thermal_zone_of_sensor_register(&client->dev,
0,
&client->dev,
lm75_read_temp, NULL);
if (IS_ERR(data->tz))
data->tz = NULL;
dev_info(&client->dev, "%s: sensor '%s'\n",
dev_name(data->hwmon_dev), client->name);
@ -287,6 +311,7 @@ static int lm75_remove(struct i2c_client *client)
{
struct lm75_data *data = i2c_get_clientdata(client);
thermal_zone_of_sensor_unregister(&client->dev, data->tz);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm75_group);
lm75_write_value(client, LM75_REG_CONF, data->orig_conf);