Commit bb43cc45 authored by Guenter Roeck's avatar Guenter Roeck

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

Simplify code and reduce code size by using the new hwmon
registration API.
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 0208531d
...@@ -72,6 +72,10 @@ MODULE_DEVICE_TABLE(i2c, tmp421_id); ...@@ -72,6 +72,10 @@ MODULE_DEVICE_TABLE(i2c, tmp421_id);
struct tmp421_data { struct tmp421_data {
struct i2c_client *client; struct i2c_client *client;
struct mutex update_lock; struct mutex update_lock;
u32 temp_config[5];
struct hwmon_channel_info temp_info;
const struct hwmon_channel_info *info[2];
struct hwmon_chip_info chip;
char valid; char valid;
unsigned long last_updated; unsigned long last_updated;
int channels; int channels;
...@@ -125,85 +129,46 @@ static struct tmp421_data *tmp421_update_device(struct device *dev) ...@@ -125,85 +129,46 @@ static struct tmp421_data *tmp421_update_device(struct device *dev)
return data; return data;
} }
static ssize_t show_temp_value(struct device *dev, static int tmp421_read(struct device *dev, enum hwmon_sensor_types type,
struct device_attribute *devattr, char *buf) u32 attr, int channel, long *val)
{ {
int index = to_sensor_dev_attr(devattr)->index; struct tmp421_data *tmp421 = tmp421_update_device(dev);
struct tmp421_data *data = tmp421_update_device(dev);
int temp; switch (attr) {
case hwmon_temp_input:
mutex_lock(&data->update_lock); if (tmp421->config & TMP421_CONFIG_RANGE)
if (data->config & TMP421_CONFIG_RANGE) *val = temp_from_u16(tmp421->temp[channel]);
temp = temp_from_u16(data->temp[index]); else
else *val = temp_from_s16(tmp421->temp[channel]);
temp = temp_from_s16(data->temp[index]); return 0;
mutex_unlock(&data->update_lock); case hwmon_temp_fault:
/*
return sprintf(buf, "%d\n", temp); * The OPEN bit signals a fault. This is bit 0 of the temperature
} * register (low byte).
*/
*val = tmp421->temp[channel] & 0x01;
return 0;
default:
return -EOPNOTSUPP;
}
static ssize_t show_fault(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
struct tmp421_data *data = tmp421_update_device(dev);
/*
* The OPEN bit signals a fault. This is bit 0 of the temperature
* register (low byte).
*/
if (data->temp[index] & 0x01)
return sprintf(buf, "1\n");
else
return sprintf(buf, "0\n");
} }
static umode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a, static umode_t tmp421_is_visible(const void *data, enum hwmon_sensor_types type,
int n) u32 attr, int channel)
{ {
struct device *dev = container_of(kobj, struct device, kobj); switch (attr) {
struct tmp421_data *data = dev_get_drvdata(dev); case hwmon_temp_fault:
struct device_attribute *devattr; if (channel == 0)
unsigned int index; return 0;
return S_IRUGO;
devattr = container_of(a, struct device_attribute, attr); case hwmon_temp_input:
index = to_sensor_dev_attr(devattr)->index; return S_IRUGO;
default:
if (index < data->channels) return 0;
return a->mode; }
return 0;
} }
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
static struct attribute *tmp421_attr[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp3_input.dev_attr.attr,
&sensor_dev_attr_temp3_fault.dev_attr.attr,
&sensor_dev_attr_temp4_input.dev_attr.attr,
&sensor_dev_attr_temp4_fault.dev_attr.attr,
NULL
};
static const struct attribute_group tmp421_group = {
.attrs = tmp421_attr,
.is_visible = tmp421_is_visible,
};
static const struct attribute_group *tmp421_groups[] = {
&tmp421_group,
NULL
};
static int tmp421_init_client(struct i2c_client *client) static int tmp421_init_client(struct i2c_client *client)
{ {
int config, config_orig; int config, config_orig;
...@@ -289,13 +254,18 @@ static int tmp421_detect(struct i2c_client *client, ...@@ -289,13 +254,18 @@ static int tmp421_detect(struct i2c_client *client,
return 0; return 0;
} }
static const struct hwmon_ops tmp421_ops = {
.is_visible = tmp421_is_visible,
.read = tmp421_read,
};
static int tmp421_probe(struct i2c_client *client, static int tmp421_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct device *hwmon_dev; struct device *hwmon_dev;
struct tmp421_data *data; struct tmp421_data *data;
int err; int i, err;
data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(struct tmp421_data), GFP_KERNEL);
if (!data) if (!data)
...@@ -309,8 +279,21 @@ static int tmp421_probe(struct i2c_client *client, ...@@ -309,8 +279,21 @@ static int tmp421_probe(struct i2c_client *client,
if (err) if (err)
return err; return err;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, for (i = 0; i < data->channels; i++)
data, tmp421_groups); data->temp_config[i] = HWMON_T_INPUT | HWMON_T_FAULT;
data->chip.ops = &tmp421_ops;
data->chip.info = data->info;
data->info[0] = &data->temp_info;
data->temp_info.type = hwmon_temp;
data->temp_info.config = data->temp_config;
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
data,
&data->chip,
NULL);
return PTR_ERR_OR_ZERO(hwmon_dev); return PTR_ERR_OR_ZERO(hwmon_dev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment