aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2016-06-19 20:49:19 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-07-09 11:33:47 -0400
commite65365fed87f5385c04124b6e7ab8967ca600b26 (patch)
tree356442ff26bf557e9ed464e432517666783be019
parent5f7e5e29ab60967a009d307dc4fdecce57efaa9c (diff)
hwmon: (lm75) Convert to use regmap
Convert to use regmap. Leave caching to regmap and drop the register update function. While this can result in additional read operations if the temperature register is read continuously, it avoids re-reading the limit registers and thus overall reduces complexity. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/Kconfig1
-rw-r--r--drivers/hwmon/lm75.c162
2 files changed, 69 insertions, 94 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 91f145e0cd45..f271353b4b55 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -958,6 +958,7 @@ config SENSORS_LM75
958 tristate "National Semiconductor LM75 and compatibles" 958 tristate "National Semiconductor LM75 and compatibles"
959 depends on I2C 959 depends on I2C
960 depends on THERMAL || !THERMAL_OF 960 depends on THERMAL || !THERMAL_OF
961 select REGMAP_I2C
961 help 962 help
962 If you say yes here you get support for one common type of 963 If you say yes here you get support for one common type of
963 temperature sensor chip, with models including: 964 temperature sensor chip, with models including:
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index fe83f70ba62a..547a9c87c68c 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -26,8 +26,8 @@
26#include <linux/hwmon.h> 26#include <linux/hwmon.h>
27#include <linux/hwmon-sysfs.h> 27#include <linux/hwmon-sysfs.h>
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/mutex.h>
30#include <linux/of.h> 29#include <linux/of.h>
30#include <linux/regmap.h>
31#include <linux/thermal.h> 31#include <linux/thermal.h>
32#include "lm75.h" 32#include "lm75.h"
33 33
@@ -66,32 +66,21 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
66 66
67 67
68/* The LM75 registers */ 68/* The LM75 registers */
69#define LM75_REG_TEMP 0x00
69#define LM75_REG_CONF 0x01 70#define LM75_REG_CONF 0x01
70static const u8 LM75_REG_TEMP[3] = { 71#define LM75_REG_HYST 0x02
71 0x00, /* input */ 72#define LM75_REG_MAX 0x03
72 0x03, /* max */
73 0x02, /* hyst */
74};
75 73
76/* Each client has this additional data */ 74/* Each client has this additional data */
77struct lm75_data { 75struct lm75_data {
78 struct i2c_client *client; 76 struct i2c_client *client;
79 struct mutex update_lock; 77 struct regmap *regmap;
80 u8 orig_conf; 78 u8 orig_conf;
81 u8 resolution; /* In bits, between 9 and 12 */ 79 u8 resolution; /* In bits, between 9 and 12 */
82 u8 resolution_limits; 80 u8 resolution_limits;
83 char valid; /* !=0 if registers are valid */ 81 unsigned int sample_time; /* In ms */
84 unsigned long last_updated; /* In jiffies */
85 unsigned long sample_time; /* In jiffies */
86 s16 temp[3]; /* Register values,
87 0 = input
88 1 = max
89 2 = hyst */
90}; 82};
91 83
92static struct lm75_data *lm75_update_device(struct device *dev);
93
94
95/*-----------------------------------------------------------------------*/ 84/*-----------------------------------------------------------------------*/
96 85
97static inline long lm75_reg_to_mc(s16 temp, u8 resolution) 86static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
@@ -103,12 +92,15 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
103 92
104static int lm75_read_temp(void *dev, int *temp) 93static int lm75_read_temp(void *dev, int *temp)
105{ 94{
106 struct lm75_data *data = lm75_update_device(dev); 95 struct lm75_data *data = dev_get_drvdata(dev);
96 unsigned int _temp;
97 int err;
107 98
108 if (IS_ERR(data)) 99 err = regmap_read(data->regmap, LM75_REG_TEMP, &_temp);
109 return PTR_ERR(data); 100 if (err < 0)
101 return err;
110 102
111 *temp = lm75_reg_to_mc(data->temp[0], data->resolution); 103 *temp = lm75_reg_to_mc(_temp, data->resolution);
112 104
113 return 0; 105 return 0;
114} 106}
@@ -117,13 +109,15 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *da,
117 char *buf) 109 char *buf)
118{ 110{
119 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 111 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
120 struct lm75_data *data = lm75_update_device(dev); 112 struct lm75_data *data = dev_get_drvdata(dev);
113 unsigned int temp = 0;
114 int err;
121 115
122 if (IS_ERR(data)) 116 err = regmap_read(data->regmap, attr->index, &temp);
123 return PTR_ERR(data); 117 if (err < 0)
118 return err;
124 119
125 return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], 120 return sprintf(buf, "%ld\n", lm75_reg_to_mc(temp, data->resolution));
126 data->resolution));
127} 121}
128 122
129static ssize_t set_temp(struct device *dev, struct device_attribute *da, 123static ssize_t set_temp(struct device *dev, struct device_attribute *da,
@@ -131,8 +125,6 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
131{ 125{
132 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 126 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
133 struct lm75_data *data = dev_get_drvdata(dev); 127 struct lm75_data *data = dev_get_drvdata(dev);
134 struct i2c_client *client = data->client;
135 int nr = attr->index;
136 long temp; 128 long temp;
137 int error; 129 int error;
138 u8 resolution; 130 u8 resolution;
@@ -150,31 +142,29 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
150 else 142 else
151 resolution = data->resolution; 143 resolution = data->resolution;
152 144
153 mutex_lock(&data->update_lock);
154 temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); 145 temp = clamp_val(temp, LM75_TEMP_MIN, LM75_TEMP_MAX);
155 data->temp[nr] = DIV_ROUND_CLOSEST(temp << (resolution - 8), 146 temp = DIV_ROUND_CLOSEST(temp << (resolution - 8),
156 1000) << (16 - resolution); 147 1000) << (16 - resolution);
157 i2c_smbus_write_word_swapped(client, LM75_REG_TEMP[nr], data->temp[nr]); 148 error = regmap_write(data->regmap, attr->index, temp);
158 mutex_unlock(&data->update_lock); 149 if (error < 0)
150 return error;
151
159 return count; 152 return count;
160} 153}
161 154
162static ssize_t show_update_interval(struct device *dev, 155static ssize_t show_update_interval(struct device *dev,
163 struct device_attribute *da, char *buf) 156 struct device_attribute *da, char *buf)
164{ 157{
165 struct lm75_data *data = lm75_update_device(dev); 158 struct lm75_data *data = dev_get_drvdata(dev);
166
167 if (IS_ERR(data))
168 return PTR_ERR(data);
169 159
170 return sprintf(buf, "%u\n", jiffies_to_msecs(data->sample_time)); 160 return sprintf(buf, "%u\n", data->sample_time);
171} 161}
172 162
173static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 163static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
174 show_temp, set_temp, 1); 164 show_temp, set_temp, LM75_REG_MAX);
175static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, 165static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
176 show_temp, set_temp, 2); 166 show_temp, set_temp, LM75_REG_HYST);
177static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 167static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, LM75_REG_TEMP);
178static DEVICE_ATTR(update_interval, S_IRUGO, show_update_interval, NULL); 168static DEVICE_ATTR(update_interval, S_IRUGO, show_update_interval, NULL);
179 169
180static struct attribute *lm75_attrs[] = { 170static struct attribute *lm75_attrs[] = {
@@ -195,6 +185,27 @@ static const struct thermal_zone_of_device_ops lm75_of_thermal_ops = {
195 185
196/* device probe and removal */ 186/* device probe and removal */
197 187
188static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg)
189{
190 return reg != LM75_REG_TEMP;
191}
192
193static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg)
194{
195 return reg == LM75_REG_TEMP;
196}
197
198static const struct regmap_config lm75_regmap_config = {
199 .reg_bits = 8,
200 .val_bits = 16,
201 .max_register = LM75_REG_MAX,
202 .writeable_reg = lm75_is_writeable_reg,
203 .volatile_reg = lm75_is_volatile_reg,
204 .val_format_endian = REGMAP_ENDIAN_BIG,
205 .cache_type = REGCACHE_RBTREE,
206 .use_single_rw = true,
207};
208
198static void lm75_remove(void *data) 209static void lm75_remove(void *data)
199{ 210{
200 struct lm75_data *lm75 = data; 211 struct lm75_data *lm75 = data;
@@ -223,8 +234,10 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
223 return -ENOMEM; 234 return -ENOMEM;
224 235
225 data->client = client; 236 data->client = client;
226 i2c_set_clientdata(client, data); 237
227 mutex_init(&data->update_lock); 238 data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config);
239 if (IS_ERR(data->regmap))
240 return PTR_ERR(data->regmap);
228 241
229 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range. 242 /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
230 * Then tweak to be more precise when appropriate. 243 * Then tweak to be more precise when appropriate.
@@ -236,7 +249,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
236 case adt75: 249 case adt75:
237 clr_mask |= 1 << 5; /* not one-shot mode */ 250 clr_mask |= 1 << 5; /* not one-shot mode */
238 data->resolution = 12; 251 data->resolution = 12;
239 data->sample_time = HZ / 8; 252 data->sample_time = MSEC_PER_SEC / 8;
240 break; 253 break;
241 case ds1775: 254 case ds1775:
242 case ds75: 255 case ds75:
@@ -244,35 +257,35 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
244 clr_mask |= 3 << 5; 257 clr_mask |= 3 << 5;
245 set_mask |= 2 << 5; /* 11-bit mode */ 258 set_mask |= 2 << 5; /* 11-bit mode */
246 data->resolution = 11; 259 data->resolution = 11;
247 data->sample_time = HZ; 260 data->sample_time = MSEC_PER_SEC;
248 break; 261 break;
249 case ds7505: 262 case ds7505:
250 set_mask |= 3 << 5; /* 12-bit mode */ 263 set_mask |= 3 << 5; /* 12-bit mode */
251 data->resolution = 12; 264 data->resolution = 12;
252 data->sample_time = HZ / 4; 265 data->sample_time = MSEC_PER_SEC / 4;
253 break; 266 break;
254 case g751: 267 case g751:
255 case lm75: 268 case lm75:
256 case lm75a: 269 case lm75a:
257 data->resolution = 9; 270 data->resolution = 9;
258 data->sample_time = HZ / 2; 271 data->sample_time = MSEC_PER_SEC / 2;
259 break; 272 break;
260 case lm75b: 273 case lm75b:
261 data->resolution = 11; 274 data->resolution = 11;
262 data->sample_time = HZ / 4; 275 data->sample_time = MSEC_PER_SEC / 4;
263 break; 276 break;
264 case max6625: 277 case max6625:
265 data->resolution = 9; 278 data->resolution = 9;
266 data->sample_time = HZ / 4; 279 data->sample_time = MSEC_PER_SEC / 4;
267 break; 280 break;
268 case max6626: 281 case max6626:
269 data->resolution = 12; 282 data->resolution = 12;
270 data->resolution_limits = 9; 283 data->resolution_limits = 9;
271 data->sample_time = HZ / 4; 284 data->sample_time = MSEC_PER_SEC / 4;
272 break; 285 break;
273 case tcn75: 286 case tcn75:
274 data->resolution = 9; 287 data->resolution = 9;
275 data->sample_time = HZ / 8; 288 data->sample_time = MSEC_PER_SEC / 8;
276 break; 289 break;
277 case mcp980x: 290 case mcp980x:
278 data->resolution_limits = 9; 291 data->resolution_limits = 9;
@@ -281,14 +294,14 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
281 case tmp101: 294 case tmp101:
282 set_mask |= 3 << 5; /* 12-bit mode */ 295 set_mask |= 3 << 5; /* 12-bit mode */
283 data->resolution = 12; 296 data->resolution = 12;
284 data->sample_time = HZ; 297 data->sample_time = MSEC_PER_SEC;
285 clr_mask |= 1 << 7; /* not one-shot mode */ 298 clr_mask |= 1 << 7; /* not one-shot mode */
286 break; 299 break;
287 case tmp112: 300 case tmp112:
288 set_mask |= 3 << 5; /* 12-bit mode */ 301 set_mask |= 3 << 5; /* 12-bit mode */
289 clr_mask |= 1 << 7; /* not one-shot mode */ 302 clr_mask |= 1 << 7; /* not one-shot mode */
290 data->resolution = 12; 303 data->resolution = 12;
291 data->sample_time = HZ / 4; 304 data->sample_time = MSEC_PER_SEC / 4;
292 break; 305 break;
293 case tmp105: 306 case tmp105:
294 case tmp175: 307 case tmp175:
@@ -297,12 +310,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
297 set_mask |= 3 << 5; /* 12-bit mode */ 310 set_mask |= 3 << 5; /* 12-bit mode */
298 clr_mask |= 1 << 7; /* not one-shot mode */ 311 clr_mask |= 1 << 7; /* not one-shot mode */
299 data->resolution = 12; 312 data->resolution = 12;
300 data->sample_time = HZ / 2; 313 data->sample_time = MSEC_PER_SEC / 2;
301 break; 314 break;
302 case tmp75c: 315 case tmp75c:
303 clr_mask |= 1 << 5; /* not one-shot mode */ 316 clr_mask |= 1 << 5; /* not one-shot mode */
304 data->resolution = 12; 317 data->resolution = 12;
305 data->sample_time = HZ / 4; 318 data->sample_time = MSEC_PER_SEC / 4;
306 break; 319 break;
307 } 320 }
308 321
@@ -506,45 +519,6 @@ static struct i2c_driver lm75_driver = {
506 .address_list = normal_i2c, 519 .address_list = normal_i2c,
507}; 520};
508 521
509/*-----------------------------------------------------------------------*/
510
511static struct lm75_data *lm75_update_device(struct device *dev)
512{
513 struct lm75_data *data = dev_get_drvdata(dev);
514 struct i2c_client *client = data->client;
515 struct lm75_data *ret = data;
516
517 mutex_lock(&data->update_lock);
518
519 if (time_after(jiffies, data->last_updated + data->sample_time)
520 || !data->valid) {
521 int i;
522 dev_dbg(&client->dev, "Starting lm75 update\n");
523
524 for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
525 int status;
526
527 status = i2c_smbus_read_word_swapped(client,
528 LM75_REG_TEMP[i]);
529 if (unlikely(status < 0)) {
530 dev_dbg(dev,
531 "LM75: Failed to read value: reg %d, error %d\n",
532 LM75_REG_TEMP[i], status);
533 ret = ERR_PTR(status);
534 data->valid = 0;
535 goto abort;
536 }
537 data->temp[i] = status;
538 }
539 data->last_updated = jiffies;
540 data->valid = 1;
541 }
542
543abort:
544 mutex_unlock(&data->update_lock);
545 return ret;
546}
547
548module_i2c_driver(lm75_driver); 522module_i2c_driver(lm75_driver);
549 523
550MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); 524MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");