hwmon: (lm75) Convert to use new hwmon registration API

Simplify code and reduce code size by using the new hwmon
registration API.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Guenter Roeck 2016-06-19 19:15:05 -07:00
parent 2ca492e22c
commit 08b0243381
2 changed files with 118 additions and 72 deletions

View File

@ -969,7 +969,6 @@ config SENSORS_LM73
config SENSORS_LM75 config SENSORS_LM75
tristate "National Semiconductor LM75 and compatibles" tristate "National Semiconductor LM75 and compatibles"
depends on I2C depends on I2C
depends on THERMAL || !THERMAL_OF
select REGMAP_I2C select REGMAP_I2C
help help
If you say yes here you get support for one common type of If you say yes here you get support for one common type of

View File

@ -28,7 +28,6 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/thermal.h>
#include "lm75.h" #include "lm75.h"
@ -88,56 +87,75 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
} }
/* sysfs attributes for hwmon */ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val)
static int lm75_read_temp(void *dev, int *temp)
{ {
struct lm75_data *data = dev_get_drvdata(dev); struct lm75_data *data = dev_get_drvdata(dev);
unsigned int _temp; unsigned int regval;
int err; int err, reg;
err = regmap_read(data->regmap, LM75_REG_TEMP, &_temp); switch (type) {
if (err < 0) case hwmon_chip:
return err; switch (attr) {
case hwmon_chip_update_interval:
*temp = lm75_reg_to_mc(_temp, data->resolution); *val = data->sample_time;
break;;
default:
return -EINVAL;
}
break;
case hwmon_temp:
switch (attr) {
case hwmon_temp_input:
reg = LM75_REG_TEMP;
break;
case hwmon_temp_max:
reg = LM75_REG_MAX;
break;
case hwmon_temp_max_hyst:
reg = LM75_REG_HYST;
break;
default:
return -EINVAL;
}
err = regmap_read(data->regmap, reg, &regval);
if (err < 0)
return err;
*val = lm75_reg_to_mc(regval, data->resolution);
break;
default:
return -EINVAL;
}
return 0; return 0;
} }
static ssize_t show_temp(struct device *dev, struct device_attribute *da, static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
char *buf) u32 attr, int channel, long temp)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm75_data *data = dev_get_drvdata(dev); struct lm75_data *data = dev_get_drvdata(dev);
unsigned int temp = 0;
int err;
err = regmap_read(data->regmap, attr->index, &temp);
if (err < 0)
return err;
return sprintf(buf, "%ld\n", lm75_reg_to_mc(temp, data->resolution));
}
static ssize_t set_temp(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct lm75_data *data = dev_get_drvdata(dev);
long temp;
int error;
u8 resolution; u8 resolution;
int reg;
error = kstrtol(buf, 10, &temp); if (type != hwmon_temp)
if (error) return -EINVAL;
return error;
switch (attr) {
case hwmon_temp_max:
reg = LM75_REG_MAX;
break;
case hwmon_temp_max_hyst:
reg = LM75_REG_HYST;
break;
default:
return -EINVAL;
}
/* /*
* Resolution of limit registers is assumed to be the same as the * Resolution of limit registers is assumed to be the same as the
* temperature input register resolution unless given explicitly. * temperature input register resolution unless given explicitly.
*/ */
if (attr->index && data->resolution_limits) if (data->resolution_limits)
resolution = data->resolution_limits; resolution = data->resolution_limits;
else else
resolution = data->resolution; resolution = data->resolution;
@ -145,46 +163,78 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
temp = DIV_ROUND_CLOSEST(temp << (resolution - 8), temp = DIV_ROUND_CLOSEST(temp << (resolution - 8),
1000) << (16 - resolution); 1000) << (16 - resolution);
error = regmap_write(data->regmap, attr->index, temp);
if (error < 0)
return error;
return count; return regmap_write(data->regmap, reg, temp);
} }
static ssize_t show_update_interval(struct device *dev, static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type,
struct device_attribute *da, char *buf) u32 attr, int channel)
{ {
struct lm75_data *data = dev_get_drvdata(dev); switch (type) {
case hwmon_chip:
return sprintf(buf, "%u\n", data->sample_time); switch (attr) {
case hwmon_chip_update_interval:
return S_IRUGO;
}
break;
case hwmon_temp:
switch (attr) {
case hwmon_temp_input:
return S_IRUGO;
case hwmon_temp_max:
case hwmon_temp_max_hyst:
return S_IRUGO | S_IWUSR;
}
break;
default:
break;
}
return 0;
} }
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
show_temp, set_temp, LM75_REG_MAX);
static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
show_temp, set_temp, LM75_REG_HYST);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, LM75_REG_TEMP);
static DEVICE_ATTR(update_interval, S_IRUGO, show_update_interval, NULL);
static struct attribute *lm75_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&dev_attr_update_interval.attr,
NULL
};
ATTRIBUTE_GROUPS(lm75);
static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
.get_temp = lm75_read_temp,
};
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* device probe and removal */ /* device probe and removal */
/* chip configuration */
static const u32 lm75_chip_config[] = {
HWMON_C_REGISTER_TZ | HWMON_C_UPDATE_INTERVAL,
0
};
static const struct hwmon_channel_info lm75_chip = {
.type = hwmon_chip,
.config = lm75_chip_config,
};
static const u32 lm75_temp_config[] = {
HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST,
0
};
static const struct hwmon_channel_info lm75_temp = {
.type = hwmon_temp,
.config = lm75_temp_config,
};
static const struct hwmon_channel_info *lm75_info[] = {
&lm75_chip,
&lm75_temp,
NULL
};
static const struct hwmon_ops lm75_hwmon_ops = {
.is_visible = lm75_is_visible,
.read = lm75_read,
.write = lm75_write,
};
static const struct hwmon_chip_info lm75_chip_info = {
.ops = &lm75_hwmon_ops,
.info = lm75_info,
};
static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg) static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg)
{ {
return reg != LM75_REG_TEMP; return reg != LM75_REG_TEMP;
@ -337,15 +387,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_dbg(dev, "Config %02x\n", new); dev_dbg(dev, "Config %02x\n", new);
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
data, lm75_groups); data, &lm75_chip_info,
NULL);
if (IS_ERR(hwmon_dev)) if (IS_ERR(hwmon_dev))
return PTR_ERR(hwmon_dev); return PTR_ERR(hwmon_dev);
devm_thermal_zone_of_sensor_register(hwmon_dev, 0,
hwmon_dev,
&lm75_of_thermal_ops);
dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name); dev_info(dev, "%s: sensor '%s'\n", dev_name(hwmon_dev), client->name);
return 0; return 0;