hwmon: (adm1021) dynamic sysfs callbacks conversion
This is conversion of the driver to the dynamic sysfs callbacks. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>
This commit is contained in:
parent
bba891c24a
commit
a8d6646e24
|
@ -25,6 +25,7 @@
|
|||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
|
@ -43,8 +44,8 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
|
|||
|
||||
/* The adm1021 registers */
|
||||
/* Read-only */
|
||||
#define ADM1021_REG_TEMP 0x00
|
||||
#define ADM1021_REG_REMOTE_TEMP 0x01
|
||||
/* For nr in 0-1 */
|
||||
#define ADM1021_REG_TEMP(nr) (nr)
|
||||
#define ADM1021_REG_STATUS 0x02
|
||||
/* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */
|
||||
#define ADM1021_REG_MAN_ID 0xFE
|
||||
|
@ -62,25 +63,14 @@ I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
|
|||
#define ADM1023_REG_REM_TOS_PREC 0x13
|
||||
#define ADM1023_REG_REM_THYST_PREC 0x14
|
||||
/* limits */
|
||||
#define ADM1021_REG_TOS_R 0x05
|
||||
#define ADM1021_REG_TOS_W 0x0B
|
||||
#define ADM1021_REG_REMOTE_TOS_R 0x07
|
||||
#define ADM1021_REG_REMOTE_TOS_W 0x0D
|
||||
#define ADM1021_REG_THYST_R 0x06
|
||||
#define ADM1021_REG_THYST_W 0x0C
|
||||
#define ADM1021_REG_REMOTE_THYST_R 0x08
|
||||
#define ADM1021_REG_REMOTE_THYST_W 0x0E
|
||||
/* For nr in 0-1 */
|
||||
#define ADM1021_REG_TOS_R(nr) (0x05 + 2 * (nr))
|
||||
#define ADM1021_REG_TOS_W(nr) (0x0B + 2 * (nr))
|
||||
#define ADM1021_REG_THYST_R(nr) (0x06 + 2 * (nr))
|
||||
#define ADM1021_REG_THYST_W(nr) (0x0C + 2 * (nr))
|
||||
/* write-only */
|
||||
#define ADM1021_REG_ONESHOT 0x0F
|
||||
|
||||
|
||||
/* Conversions. Rounding and limit checking is only done on the TO_REG
|
||||
variants. Note that you should be a bit careful with which arguments
|
||||
these macros are called: arguments may be evaluated more than once.
|
||||
Fixing this is just not worth it. */
|
||||
/* Conversions note: 1021 uses normal integer signed-byte format*/
|
||||
#define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -128, 127)
|
||||
|
||||
/* Initial values */
|
||||
|
||||
/* Note: Even though I left the low and high limits named os and hyst,
|
||||
|
@ -98,19 +88,16 @@ struct adm1021_data {
|
|||
char valid; /* !=0 if following fields are valid */
|
||||
unsigned long last_updated; /* In jiffies */
|
||||
|
||||
s8 temp_max; /* Register values */
|
||||
s8 temp_hyst;
|
||||
s8 temp_input;
|
||||
s8 remote_temp_max;
|
||||
s8 remote_temp_hyst;
|
||||
s8 remote_temp_input;
|
||||
u8 alarms;
|
||||
/* Special values for ADM1023 only */
|
||||
u8 remote_temp_prec;
|
||||
u8 remote_temp_os_prec;
|
||||
u8 remote_temp_hyst_prec;
|
||||
u8 remote_temp_offset;
|
||||
u8 remote_temp_offset_prec;
|
||||
s8 temp_max[2]; /* Register values */
|
||||
s8 temp_min[2];
|
||||
s8 temp[2];
|
||||
u8 alarms;
|
||||
/* Special values for ADM1023 only */
|
||||
u8 remote_temp_prec;
|
||||
u8 remote_temp_os_prec;
|
||||
u8 remote_temp_hyst_prec;
|
||||
u8 remote_temp_offset;
|
||||
u8 remote_temp_offset_prec;
|
||||
};
|
||||
|
||||
static int adm1021_attach_adapter(struct i2c_adapter *adapter);
|
||||
|
@ -133,19 +120,32 @@ static struct i2c_driver adm1021_driver = {
|
|||
.detach_client = adm1021_detach_client,
|
||||
};
|
||||
|
||||
#define show(value) \
|
||||
static ssize_t show_##value(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
struct adm1021_data *data = adm1021_update_device(dev); \
|
||||
return sprintf(buf, "%d\n", 1000 * data->value); \
|
||||
static ssize_t show_temp(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct adm1021_data *data = adm1021_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", 1000 * data->temp[index]);
|
||||
}
|
||||
|
||||
static ssize_t show_temp_max(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct adm1021_data *data = adm1021_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", 1000 * data->temp_max[index]);
|
||||
}
|
||||
|
||||
static ssize_t show_temp_min(struct device *dev,
|
||||
struct device_attribute *devattr, char *buf)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct adm1021_data *data = adm1021_update_device(dev);
|
||||
|
||||
return sprintf(buf, "%d\n", 1000 * data->temp_min[index]);
|
||||
}
|
||||
show(temp_max);
|
||||
show(temp_hyst);
|
||||
show(temp_input);
|
||||
show(remote_temp_max);
|
||||
show(remote_temp_hyst);
|
||||
show(remote_temp_input);
|
||||
|
||||
static ssize_t show_alarms(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
|
@ -155,36 +155,56 @@ static ssize_t show_alarms(struct device *dev,
|
|||
return sprintf(buf, "%u\n", data->alarms);
|
||||
}
|
||||
|
||||
#define set(value, reg) \
|
||||
static ssize_t set_##value(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
const char *buf, size_t count) \
|
||||
{ \
|
||||
struct i2c_client *client = to_i2c_client(dev); \
|
||||
struct adm1021_data *data = i2c_get_clientdata(client); \
|
||||
long temp = simple_strtol(buf, NULL, 10); \
|
||||
\
|
||||
mutex_lock(&data->update_lock); \
|
||||
data->value = TEMP_TO_REG(temp); \
|
||||
if (!read_only) \
|
||||
i2c_smbus_write_byte_data(client, reg, data->value); \
|
||||
mutex_unlock(&data->update_lock); \
|
||||
return count; \
|
||||
static ssize_t set_temp_max(struct device *dev,
|
||||
struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct adm1021_data *data = i2c_get_clientdata(client);
|
||||
long temp = simple_strtol(buf, NULL, 10) / 1000;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
|
||||
if (!read_only)
|
||||
i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
|
||||
data->temp_max[index]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
set(temp_max, ADM1021_REG_TOS_W);
|
||||
set(temp_hyst, ADM1021_REG_THYST_W);
|
||||
set(remote_temp_max, ADM1021_REG_REMOTE_TOS_W);
|
||||
set(remote_temp_hyst, ADM1021_REG_REMOTE_THYST_W);
|
||||
|
||||
static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max);
|
||||
static DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst);
|
||||
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL);
|
||||
static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_remote_temp_max, set_remote_temp_max);
|
||||
static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_remote_temp_hyst, set_remote_temp_hyst);
|
||||
static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote_temp_input, NULL);
|
||||
static ssize_t set_temp_min(struct device *dev,
|
||||
struct device_attribute *devattr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int index = to_sensor_dev_attr(devattr)->index;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct adm1021_data *data = i2c_get_clientdata(client);
|
||||
long temp = simple_strtol(buf, NULL, 10) / 1000;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
|
||||
if (!read_only)
|
||||
i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
|
||||
data->temp_min[index]);
|
||||
mutex_unlock(&data->update_lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
|
||||
set_temp_max, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
|
||||
set_temp_min, 0);
|
||||
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
|
||||
set_temp_max, 1);
|
||||
static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
|
||||
set_temp_min, 1);
|
||||
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
|
||||
|
||||
|
||||
static int adm1021_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
if (!(adapter->class & I2C_CLASS_HWMON))
|
||||
|
@ -193,12 +213,12 @@ static int adm1021_attach_adapter(struct i2c_adapter *adapter)
|
|||
}
|
||||
|
||||
static struct attribute *adm1021_attributes[] = {
|
||||
&dev_attr_temp1_max.attr,
|
||||
&dev_attr_temp1_min.attr,
|
||||
&dev_attr_temp1_input.attr,
|
||||
&dev_attr_temp2_max.attr,
|
||||
&dev_attr_temp2_min.attr,
|
||||
&dev_attr_temp2_input.attr,
|
||||
&sensor_dev_attr_temp1_max.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_min.dev_attr.attr,
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_max.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_min.dev_attr.attr,
|
||||
&sensor_dev_attr_temp2_input.dev_attr.attr,
|
||||
&dev_attr_alarms.attr,
|
||||
NULL
|
||||
};
|
||||
|
@ -370,20 +390,18 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
|
|||
|
||||
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|
||||
|| !data->valid) {
|
||||
int i;
|
||||
|
||||
dev_dbg(&client->dev, "Starting adm1021 update\n");
|
||||
|
||||
data->temp_input = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_TEMP);
|
||||
data->temp_max = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_TOS_R);
|
||||
data->temp_hyst = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_THYST_R);
|
||||
data->remote_temp_input = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_REMOTE_TEMP);
|
||||
data->remote_temp_max = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_REMOTE_TOS_R);
|
||||
data->remote_temp_hyst = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_REMOTE_THYST_R);
|
||||
for (i = 0; i < 2; i++) {
|
||||
data->temp[i] = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_TEMP(i));
|
||||
data->temp_max[i] = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_TOS_R(i));
|
||||
data->temp_min[i] = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_THYST_R(i));
|
||||
}
|
||||
data->alarms = i2c_smbus_read_byte_data(client,
|
||||
ADM1021_REG_STATUS) & 0x7c;
|
||||
if (data->type == adm1023) {
|
||||
|
|
Loading…
Reference in New Issue