Commit 963f9bc9 authored by Guenter Roeck's avatar Guenter Roeck

hwmon: (lm95234) Convert to use regmap

Use regmap to replace local caching and to be able to use regmap API
functions.

No functional change.
Reviewed-by: default avatarTzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent e38b05f0
...@@ -1532,6 +1532,7 @@ config SENSORS_LM93 ...@@ -1532,6 +1532,7 @@ config SENSORS_LM93
config SENSORS_LM95234 config SENSORS_LM95234
tristate "National Semiconductor LM95234 and compatibles" tristate "National Semiconductor LM95234 and compatibles"
depends on I2C depends on I2C
select REGMAP_I2C
help help
If you say yes here you get support for the LM95233 and LM95234 If you say yes here you get support for the LM95233 and LM95234
temperature sensor chips. temperature sensor chips.
......
...@@ -13,10 +13,10 @@ ...@@ -13,10 +13,10 @@
#include <linux/hwmon-sysfs.h> #include <linux/hwmon-sysfs.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/util_macros.h> #include <linux/util_macros.h>
...@@ -33,6 +33,8 @@ static const unsigned short normal_i2c[] = { ...@@ -33,6 +33,8 @@ static const unsigned short normal_i2c[] = {
#define LM95234_REG_STATUS 0x02 #define LM95234_REG_STATUS 0x02
#define LM95234_REG_CONFIG 0x03 #define LM95234_REG_CONFIG 0x03
#define LM95234_REG_CONVRATE 0x04 #define LM95234_REG_CONVRATE 0x04
#define LM95234_REG_ENABLE 0x05
#define LM95234_REG_FILTER 0x06
#define LM95234_REG_STS_FAULT 0x07 #define LM95234_REG_STS_FAULT 0x07
#define LM95234_REG_STS_TCRIT1 0x08 #define LM95234_REG_STS_TCRIT1 0x08
#define LM95234_REG_STS_TCRIT2 0x09 #define LM95234_REG_STS_TCRIT2 0x09
...@@ -53,181 +55,72 @@ static const unsigned short normal_i2c[] = { ...@@ -53,181 +55,72 @@ static const unsigned short normal_i2c[] = {
/* Client data (each client gets its own) */ /* Client data (each client gets its own) */
struct lm95234_data { struct lm95234_data {
struct i2c_client *client; struct regmap *regmap;
const struct attribute_group *groups[3]; const struct attribute_group *groups[3];
struct mutex update_lock; struct mutex update_lock;
unsigned long last_updated, interval; /* in jiffies */
bool valid; /* false until following fields are valid */
/* registers values */
int temp[5]; /* temperature (signed) */
u32 status; /* fault/alarm status */
u8 tcrit1[5]; /* critical temperature limit */
u8 tcrit2[2]; /* high temperature limit */
s8 toffset[4]; /* remote temperature offset */
u8 thyst; /* common hysteresis */
u8 sensor_type; /* temperature sensor type */
}; };
static int lm95234_read_temp(struct i2c_client *client, int index, int *t) static int lm95234_read_temp(struct regmap *regmap, int index, int *t)
{ {
int val; int temp = 0, ret;
u16 temp = 0; u32 val;
if (index) { if (index) {
val = i2c_smbus_read_byte_data(client, ret = regmap_read(regmap, LM95234_REG_UTEMPH(index - 1), &val);
LM95234_REG_UTEMPH(index - 1)); if (ret)
if (val < 0) return ret;
return val;
temp = val << 8; temp = val << 8;
val = i2c_smbus_read_byte_data(client, ret = regmap_read(regmap, LM95234_REG_UTEMPL(index - 1), &val);
LM95234_REG_UTEMPL(index - 1)); if (ret)
if (val < 0) return ret;
return val;
temp |= val; temp |= val;
*t = temp;
} }
/* /*
* Read signed temperature if unsigned temperature is 0, * Read signed temperature if unsigned temperature is 0,
* or if this is the local sensor. * or if this is the local sensor.
*/ */
if (!temp) { if (!temp) {
val = i2c_smbus_read_byte_data(client, ret = regmap_read(regmap, LM95234_REG_TEMPH(index), &val);
LM95234_REG_TEMPH(index)); if (ret)
if (val < 0)
return val;
temp = val << 8;
val = i2c_smbus_read_byte_data(client,
LM95234_REG_TEMPL(index));
if (val < 0)
return val;
temp |= val;
*t = (s16)temp;
}
return 0;
}
static u16 update_intervals[] = { 143, 364, 1000, 2500 };
/* Fill value cache. Must be called with update lock held. */
static int lm95234_fill_cache(struct lm95234_data *data,
struct i2c_client *client)
{
int i, ret;
ret = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE);
if (ret < 0)
return ret;
data->interval = msecs_to_jiffies(update_intervals[ret & 0x03]);
for (i = 0; i < ARRAY_SIZE(data->tcrit1); i++) {
ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT1(i));
if (ret < 0)
return ret;
data->tcrit1[i] = ret;
}
for (i = 0; i < ARRAY_SIZE(data->tcrit2); i++) {
ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT2(i));
if (ret < 0)
return ret; return ret;
data->tcrit2[i] = ret; temp = val << 8;
} ret = regmap_read(regmap, LM95234_REG_TEMPL(index), &val);
for (i = 0; i < ARRAY_SIZE(data->toffset); i++) { if (ret)
ret = i2c_smbus_read_byte_data(client, LM95234_REG_OFFSET(i));
if (ret < 0)
return ret; return ret;
data->toffset[i] = ret; temp = sign_extend32(temp | val, 15);
} }
*t = DIV_ROUND_CLOSEST(temp * 125, 32);
ret = i2c_smbus_read_byte_data(client, LM95234_REG_TCRIT_HYST);
if (ret < 0)
return ret;
data->thyst = ret;
ret = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL);
if (ret < 0)
return ret;
data->sensor_type = ret;
return 0; return 0;
} }
static int lm95234_update_device(struct lm95234_data *data)
{
struct i2c_client *client = data->client;
int ret;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + data->interval) ||
!data->valid) {
int i;
if (!data->valid) {
ret = lm95234_fill_cache(data, client);
if (ret < 0)
goto abort;
}
data->valid = false;
for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
ret = lm95234_read_temp(client, i, &data->temp[i]);
if (ret < 0)
goto abort;
}
ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_FAULT);
if (ret < 0)
goto abort;
data->status = ret;
ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT1);
if (ret < 0)
goto abort;
data->status |= ret << 8;
ret = i2c_smbus_read_byte_data(client, LM95234_REG_STS_TCRIT2);
if (ret < 0)
goto abort;
data->status |= ret << 16;
data->last_updated = jiffies;
data->valid = true;
}
ret = 0;
abort:
mutex_unlock(&data->update_lock);
return ret;
}
static ssize_t temp_show(struct device *dev, struct device_attribute *attr, static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); int ret, temp;
ret = lm95234_read_temp(data->regmap, index, &temp);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%d\n", return sysfs_emit(buf, "%d\n", temp);
DIV_ROUND_CLOSEST(data->temp[index] * 125, 32));
} }
static ssize_t alarm_show(struct device *dev, struct device_attribute *attr, static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
u32 mask = to_sensor_dev_attr(attr)->index; u8 mask = to_sensor_dev_attr_2(attr)->index;
int ret = lm95234_update_device(data); u8 reg = to_sensor_dev_attr_2(attr)->nr;
int ret;
u32 val;
ret = regmap_read(data->regmap, reg, &val);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%u", !!(data->status & mask)); return sysfs_emit(buf, "%u\n", !!(val & mask));
} }
static ssize_t type_show(struct device *dev, struct device_attribute *attr, static ssize_t type_show(struct device *dev, struct device_attribute *attr,
...@@ -235,24 +128,23 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr, ...@@ -235,24 +128,23 @@ static ssize_t type_show(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
u8 mask = to_sensor_dev_attr(attr)->index; u8 mask = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); u32 val;
int ret;
ret = regmap_read(data->regmap, LM95234_REG_REM_MODEL, &val);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, data->sensor_type & mask ? "1\n" : "2\n"); return sysfs_emit(buf, "%s\n", val & mask ? "1" : "2");
} }
static ssize_t type_store(struct device *dev, struct device_attribute *attr, static ssize_t type_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
unsigned long val;
u8 mask = to_sensor_dev_attr(attr)->index; u8 mask = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); unsigned long val;
int ret;
if (ret)
return ret;
ret = kstrtoul(buf, 10, &val); ret = kstrtoul(buf, 10, &val);
if (ret < 0) if (ret < 0)
...@@ -261,16 +153,10 @@ static ssize_t type_store(struct device *dev, struct device_attribute *attr, ...@@ -261,16 +153,10 @@ static ssize_t type_store(struct device *dev, struct device_attribute *attr,
if (val != 1 && val != 2) if (val != 1 && val != 2)
return -EINVAL; return -EINVAL;
mutex_lock(&data->update_lock); ret = regmap_update_bits(data->regmap, LM95234_REG_REM_MODEL,
if (val == 1) mask, val == 1 ? mask : 0);
data->sensor_type |= mask; if (ret)
else return ret;
data->sensor_type &= ~mask;
data->valid = false;
i2c_smbus_write_byte_data(data->client, LM95234_REG_REM_MODEL,
data->sensor_type);
mutex_unlock(&data->update_lock);
return count; return count;
} }
...@@ -279,12 +165,14 @@ static ssize_t tcrit2_show(struct device *dev, struct device_attribute *attr, ...@@ -279,12 +165,14 @@ static ssize_t tcrit2_show(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); int ret;
u32 tcrit2;
ret = regmap_read(data->regmap, LM95234_REG_TCRIT2(index), &tcrit2);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%u", data->tcrit2[index] * 1000); return sysfs_emit(buf, "%u\n", tcrit2 * 1000);
} }
static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr, static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr,
...@@ -293,10 +181,7 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr, ...@@ -293,10 +181,7 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr,
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
long val; long val;
int ret = lm95234_update_device(data); int ret;
if (ret)
return ret;
ret = kstrtol(buf, 10, &val); ret = kstrtol(buf, 10, &val);
if (ret < 0) if (ret < 0)
...@@ -305,12 +190,29 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr, ...@@ -305,12 +190,29 @@ static ssize_t tcrit2_store(struct device *dev, struct device_attribute *attr,
val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000), val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000),
1000); 1000);
ret = regmap_write(data->regmap, LM95234_REG_TCRIT2(index), val);
if (ret)
return ret;
return count;
}
static ssize_t tcrit_hyst_show(struct lm95234_data *data, char *buf, int reg)
{
u32 thyst, tcrit;
int ret;
mutex_lock(&data->update_lock); mutex_lock(&data->update_lock);
data->tcrit2[index] = val; ret = regmap_read(data->regmap, reg, &tcrit);
i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT2(index), val); if (ret)
goto unlock;
ret = regmap_read(data->regmap, LM95234_REG_TCRIT_HYST, &thyst);
unlock:
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
if (ret)
return ret;
return count; /* Result can be negative, so be careful with unsigned operands */
return sysfs_emit(buf, "%d\n", ((int)tcrit - (int)thyst) * 1000);
} }
static ssize_t tcrit2_hyst_show(struct device *dev, static ssize_t tcrit2_hyst_show(struct device *dev,
...@@ -318,14 +220,8 @@ static ssize_t tcrit2_hyst_show(struct device *dev, ...@@ -318,14 +220,8 @@ static ssize_t tcrit2_hyst_show(struct device *dev,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data);
if (ret)
return ret;
/* Result can be negative, so be careful with unsigned operands */ return tcrit_hyst_show(data, buf, LM95234_REG_TCRIT2(index));
return sprintf(buf, "%d",
((int)data->tcrit2[index] - (int)data->thyst) * 1000);
} }
static ssize_t tcrit1_show(struct device *dev, struct device_attribute *attr, static ssize_t tcrit1_show(struct device *dev, struct device_attribute *attr,
...@@ -333,8 +229,14 @@ static ssize_t tcrit1_show(struct device *dev, struct device_attribute *attr, ...@@ -333,8 +229,14 @@ static ssize_t tcrit1_show(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret;
u32 val;
ret = regmap_read(data->regmap, LM95234_REG_TCRIT1(index), &val);
if (ret)
return ret;
return sprintf(buf, "%u", data->tcrit1[index] * 1000); return sysfs_emit(buf, "%u\n", val * 1000);
} }
static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr, static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr,
...@@ -342,11 +244,8 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr, ...@@ -342,11 +244,8 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data);
long val; long val;
int ret;
if (ret)
return ret;
ret = kstrtol(buf, 10, &val); ret = kstrtol(buf, 10, &val);
if (ret < 0) if (ret < 0)
...@@ -354,10 +253,9 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr, ...@@ -354,10 +253,9 @@ static ssize_t tcrit1_store(struct device *dev, struct device_attribute *attr,
val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000); val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000);
mutex_lock(&data->update_lock); ret = regmap_write(data->regmap, LM95234_REG_TCRIT1(index), val);
data->tcrit1[index] = val; if (ret)
i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT1(index), val); return ret;
mutex_unlock(&data->update_lock);
return count; return count;
} }
...@@ -367,14 +265,8 @@ static ssize_t tcrit1_hyst_show(struct device *dev, ...@@ -367,14 +265,8 @@ static ssize_t tcrit1_hyst_show(struct device *dev,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data);
if (ret) return tcrit_hyst_show(data, buf, LM95234_REG_TCRIT1(index));
return ret;
/* Result can be negative, so be careful with unsigned operands */
return sprintf(buf, "%d",
((int)data->tcrit1[index] - (int)data->thyst) * 1000);
} }
static ssize_t tcrit1_hyst_store(struct device *dev, static ssize_t tcrit1_hyst_store(struct device *dev,
...@@ -383,23 +275,28 @@ static ssize_t tcrit1_hyst_store(struct device *dev, ...@@ -383,23 +275,28 @@ static ssize_t tcrit1_hyst_store(struct device *dev,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); u32 tcrit;
long val; long val;
int ret;
if (ret)
return ret;
ret = kstrtol(buf, 10, &val); ret = kstrtol(buf, 10, &val);
if (ret < 0) if (ret < 0)
return ret; return ret;
mutex_lock(&data->update_lock);
ret = regmap_read(data->regmap, LM95234_REG_TCRIT1(index), &tcrit);
if (ret)
goto unlock;
val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000); val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000);
val = clamp_val((int)data->tcrit1[index] - val, 0, 31); val = clamp_val((int)tcrit - val, 0, 31);
mutex_lock(&data->update_lock); ret = regmap_write(data->regmap, LM95234_REG_TCRIT_HYST, val);
data->thyst = val; unlock:
i2c_smbus_write_byte_data(data->client, LM95234_REG_TCRIT_HYST, val);
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
if (ret)
return ret;
return count; return count;
} }
...@@ -409,12 +306,14 @@ static ssize_t offset_show(struct device *dev, struct device_attribute *attr, ...@@ -409,12 +306,14 @@ static ssize_t offset_show(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data); u32 offset;
int ret;
ret = regmap_read(data->regmap, LM95234_REG_OFFSET(index), &offset);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%d", data->toffset[index] * 500); return sysfs_emit(buf, "%d\n", sign_extend32(offset, 7) * 500);
} }
static ssize_t offset_store(struct device *dev, struct device_attribute *attr, static ssize_t offset_store(struct device *dev, struct device_attribute *attr,
...@@ -422,11 +321,8 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr, ...@@ -422,11 +321,8 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr,
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index; int index = to_sensor_dev_attr(attr)->index;
int ret = lm95234_update_device(data);
long val; long val;
int ret;
if (ret)
return ret;
ret = kstrtol(buf, 10, &val); ret = kstrtol(buf, 10, &val);
if (ret < 0) if (ret < 0)
...@@ -435,25 +331,27 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr, ...@@ -435,25 +331,27 @@ static ssize_t offset_store(struct device *dev, struct device_attribute *attr,
/* Accuracy is 1/2 degrees C */ /* Accuracy is 1/2 degrees C */
val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500); val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500);
mutex_lock(&data->update_lock); ret = regmap_write(data->regmap, LM95234_REG_OFFSET(index), val);
data->toffset[index] = val; if (ret < 0)
i2c_smbus_write_byte_data(data->client, LM95234_REG_OFFSET(index), val); return ret;
mutex_unlock(&data->update_lock);
return count; return count;
} }
static u16 update_intervals[] = { 143, 364, 1000, 2500 };
static ssize_t update_interval_show(struct device *dev, static ssize_t update_interval_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int ret = lm95234_update_device(data); u32 convrate;
int ret;
ret = regmap_read(data->regmap, LM95234_REG_CONVRATE, &convrate);
if (ret) if (ret)
return ret; return ret;
return sprintf(buf, "%lu\n", return sysfs_emit(buf, "%u\n", update_intervals[convrate & 0x03]);
DIV_ROUND_CLOSEST(data->interval * 1000, HZ));
} }
static ssize_t update_interval_store(struct device *dev, static ssize_t update_interval_store(struct device *dev,
...@@ -461,23 +359,17 @@ static ssize_t update_interval_store(struct device *dev, ...@@ -461,23 +359,17 @@ static ssize_t update_interval_store(struct device *dev,
const char *buf, size_t count) const char *buf, size_t count)
{ {
struct lm95234_data *data = dev_get_drvdata(dev); struct lm95234_data *data = dev_get_drvdata(dev);
int ret = lm95234_update_device(data);
unsigned long val; unsigned long val;
u8 regval; int ret;
if (ret)
return ret;
ret = kstrtoul(buf, 10, &val); ret = kstrtoul(buf, 10, &val);
if (ret < 0) if (ret < 0)
return ret; return ret;
regval = find_closest(val, update_intervals, ARRAY_SIZE(update_intervals)); val = find_closest(val, update_intervals, ARRAY_SIZE(update_intervals));
ret = regmap_write(data->regmap, LM95234_REG_CONVRATE, val);
mutex_lock(&data->update_lock); if (ret)
data->interval = msecs_to_jiffies(update_intervals[regval]); return ret;
i2c_smbus_write_byte_data(data->client, LM95234_REG_CONVRATE, regval);
mutex_unlock(&data->update_lock);
return count; return count;
} }
...@@ -488,10 +380,10 @@ static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2); ...@@ -488,10 +380,10 @@ static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3); static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3);
static SENSOR_DEVICE_ATTR_RO(temp5_input, temp, 4); static SENSOR_DEVICE_ATTR_RO(temp5_input, temp, 4);
static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, BIT(0) | BIT(1)); static SENSOR_DEVICE_ATTR_2_RO(temp2_fault, alarm, LM95234_REG_STS_FAULT, BIT(0) | BIT(1));
static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, BIT(2) | BIT(3)); static SENSOR_DEVICE_ATTR_2_RO(temp3_fault, alarm, LM95234_REG_STS_FAULT, BIT(2) | BIT(3));
static SENSOR_DEVICE_ATTR_RO(temp4_fault, alarm, BIT(4) | BIT(5)); static SENSOR_DEVICE_ATTR_2_RO(temp4_fault, alarm, LM95234_REG_STS_FAULT, BIT(4) | BIT(5));
static SENSOR_DEVICE_ATTR_RO(temp5_fault, alarm, BIT(6) | BIT(7)); static SENSOR_DEVICE_ATTR_2_RO(temp5_fault, alarm, LM95234_REG_STS_FAULT, BIT(6) | BIT(7));
static SENSOR_DEVICE_ATTR_RW(temp2_type, type, BIT(1)); static SENSOR_DEVICE_ATTR_RW(temp2_type, type, BIT(1));
static SENSOR_DEVICE_ATTR_RW(temp3_type, type, BIT(2)); static SENSOR_DEVICE_ATTR_RW(temp3_type, type, BIT(2));
...@@ -510,11 +402,11 @@ static SENSOR_DEVICE_ATTR_RO(temp3_max_hyst, tcrit2_hyst, 1); ...@@ -510,11 +402,11 @@ static SENSOR_DEVICE_ATTR_RO(temp3_max_hyst, tcrit2_hyst, 1);
static SENSOR_DEVICE_ATTR_RO(temp4_max_hyst, tcrit1_hyst, 3); static SENSOR_DEVICE_ATTR_RO(temp4_max_hyst, tcrit1_hyst, 3);
static SENSOR_DEVICE_ATTR_RO(temp5_max_hyst, tcrit1_hyst, 4); static SENSOR_DEVICE_ATTR_RO(temp5_max_hyst, tcrit1_hyst, 4);
static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, alarm, BIT(0 + 8)); static SENSOR_DEVICE_ATTR_2_RO(temp1_max_alarm, alarm, LM95234_REG_STS_TCRIT1, BIT(0));
static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, alarm, BIT(1 + 16)); static SENSOR_DEVICE_ATTR_2_RO(temp2_max_alarm, alarm, LM95234_REG_STS_TCRIT2, BIT(1));
static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, alarm, BIT(2 + 16)); static SENSOR_DEVICE_ATTR_2_RO(temp3_max_alarm, alarm, LM95234_REG_STS_TCRIT2, BIT(2));
static SENSOR_DEVICE_ATTR_RO(temp4_max_alarm, alarm, BIT(3 + 8)); static SENSOR_DEVICE_ATTR_2_RO(temp4_max_alarm, alarm, LM95234_REG_STS_TCRIT1, BIT(3));
static SENSOR_DEVICE_ATTR_RO(temp5_max_alarm, alarm, BIT(4 + 8)); static SENSOR_DEVICE_ATTR_2_RO(temp5_max_alarm, alarm, LM95234_REG_STS_TCRIT1, BIT(4));
static SENSOR_DEVICE_ATTR_RW(temp2_crit, tcrit1, 1); static SENSOR_DEVICE_ATTR_RW(temp2_crit, tcrit1, 1);
static SENSOR_DEVICE_ATTR_RW(temp3_crit, tcrit1, 2); static SENSOR_DEVICE_ATTR_RW(temp3_crit, tcrit1, 2);
...@@ -522,8 +414,8 @@ static SENSOR_DEVICE_ATTR_RW(temp3_crit, tcrit1, 2); ...@@ -522,8 +414,8 @@ static SENSOR_DEVICE_ATTR_RW(temp3_crit, tcrit1, 2);
static SENSOR_DEVICE_ATTR_RO(temp2_crit_hyst, tcrit1_hyst, 1); static SENSOR_DEVICE_ATTR_RO(temp2_crit_hyst, tcrit1_hyst, 1);
static SENSOR_DEVICE_ATTR_RO(temp3_crit_hyst, tcrit1_hyst, 2); static SENSOR_DEVICE_ATTR_RO(temp3_crit_hyst, tcrit1_hyst, 2);
static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, BIT(1 + 8)); static SENSOR_DEVICE_ATTR_2_RO(temp2_crit_alarm, alarm, LM95234_REG_STS_TCRIT1, BIT(1));
static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, BIT(2 + 8)); static SENSOR_DEVICE_ATTR_2_RO(temp3_crit_alarm, alarm, LM95234_REG_STS_TCRIT1, BIT(2));
static SENSOR_DEVICE_ATTR_RW(temp2_offset, offset, 0); static SENSOR_DEVICE_ATTR_RW(temp2_offset, offset, 0);
static SENSOR_DEVICE_ATTR_RW(temp3_offset, offset, 1); static SENSOR_DEVICE_ATTR_RW(temp3_offset, offset, 1);
...@@ -587,6 +479,45 @@ static const struct attribute_group lm95234_group = { ...@@ -587,6 +479,45 @@ static const struct attribute_group lm95234_group = {
.attrs = lm95234_attrs, .attrs = lm95234_attrs,
}; };
static bool lm95234_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case LM95234_REG_TEMPH(0) ... LM95234_REG_TEMPH(4):
case LM95234_REG_TEMPL(0) ... LM95234_REG_TEMPL(4):
case LM95234_REG_UTEMPH(0) ... LM95234_REG_UTEMPH(3):
case LM95234_REG_UTEMPL(0) ... LM95234_REG_UTEMPL(3):
case LM95234_REG_STS_FAULT:
case LM95234_REG_STS_TCRIT1:
case LM95234_REG_STS_TCRIT2:
case LM95234_REG_REM_MODEL_STS:
return true;
default:
return false;
}
}
static bool lm95234_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case LM95234_REG_CONFIG ... LM95234_REG_FILTER:
case LM95234_REG_REM_MODEL ... LM95234_REG_OFFSET(3):
case LM95234_REG_TCRIT1(0) ... LM95234_REG_TCRIT1(4):
case LM95234_REG_TCRIT2(0) ... LM95234_REG_TCRIT2(1):
case LM95234_REG_TCRIT_HYST:
return true;
default:
return false;
}
}
static const struct regmap_config lm95234_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.writeable_reg = lm95234_writeable_reg,
.volatile_reg = lm95234_volatile_reg,
.cache_type = REGCACHE_MAPLE,
};
static int lm95234_detect(struct i2c_client *client, static int lm95234_detect(struct i2c_client *client,
struct i2c_board_info *info) struct i2c_board_info *info)
{ {
...@@ -647,33 +578,30 @@ static int lm95234_detect(struct i2c_client *client, ...@@ -647,33 +578,30 @@ static int lm95234_detect(struct i2c_client *client,
return 0; return 0;
} }
static int lm95234_init_client(struct i2c_client *client) static int lm95234_init_client(struct device *dev, struct regmap *regmap)
{ {
int val, model; u32 val, model;
int ret;
/* start conversion if necessary */ /* start conversion if necessary */
val = i2c_smbus_read_byte_data(client, LM95234_REG_CONFIG); ret = regmap_clear_bits(regmap, LM95234_REG_CONFIG, 0x40);
if (val < 0) if (ret)
return val; return ret;
if (val & 0x40)
i2c_smbus_write_byte_data(client, LM95234_REG_CONFIG,
val & ~0x40);
/* If diode type status reports an error, try to fix it */ /* If diode type status reports an error, try to fix it */
val = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL_STS); ret = regmap_read(regmap, LM95234_REG_REM_MODEL_STS, &val);
if (val < 0) if (ret < 0)
return val; return ret;
model = i2c_smbus_read_byte_data(client, LM95234_REG_REM_MODEL); ret = regmap_read(regmap, LM95234_REG_REM_MODEL, &model);
if (model < 0) if (ret < 0)
return model; return ret;
if (model & val) { if (model & val) {
dev_notice(&client->dev, dev_notice(dev,
"Fixing remote diode type misconfiguration (0x%x)\n", "Fixing remote diode type misconfiguration (0x%x)\n",
val); val);
i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL, ret = regmap_write(regmap, LM95234_REG_REM_MODEL, model & ~val);
model & ~val);
} }
return 0; return ret;
} }
static int lm95234_probe(struct i2c_client *client) static int lm95234_probe(struct i2c_client *client)
...@@ -682,17 +610,22 @@ static int lm95234_probe(struct i2c_client *client) ...@@ -682,17 +610,22 @@ static int lm95234_probe(struct i2c_client *client)
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct lm95234_data *data; struct lm95234_data *data;
struct device *hwmon_dev; struct device *hwmon_dev;
struct regmap *regmap;
int err; int err;
data = devm_kzalloc(dev, sizeof(struct lm95234_data), GFP_KERNEL); data = devm_kzalloc(dev, sizeof(struct lm95234_data), GFP_KERNEL);
if (!data) if (!data)
return -ENOMEM; return -ENOMEM;
data->client = client; regmap = devm_regmap_init_i2c(client, &lm95234_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
data->regmap = regmap;
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
/* Initialize the LM95234 chip */ /* Initialize the LM95234 chip */
err = lm95234_init_client(client); err = lm95234_init_client(dev, regmap);
if (err < 0) if (err < 0)
return err; return err;
......
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