aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2016-07-03 00:40:19 -0400
committerGuenter Roeck <linux@roeck-us.net>2016-09-09 00:34:18 -0400
commitfcc448cfe48ed7a74a299709457b32a7e5ca663a (patch)
tree8569f3789b778f7d60356f76f08dd30f89ea699d
parent54187ff9d766b2138bd83df74b6df7d78d422965 (diff)
hwmon: (jc42) 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>
-rw-r--r--drivers/hwmon/jc42.c293
1 files changed, 149 insertions, 144 deletions
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 9d5f85f3384f..1bf22eff0b08 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -28,7 +28,6 @@
28#include <linux/jiffies.h> 28#include <linux/jiffies.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/hwmon.h> 30#include <linux/hwmon.h>
31#include <linux/hwmon-sysfs.h>
32#include <linux/err.h> 31#include <linux/err.h>
33#include <linux/mutex.h> 32#include <linux/mutex.h>
34#include <linux/of.h> 33#include <linux/of.h>
@@ -254,170 +253,148 @@ abort:
254 return ret; 253 return ret;
255} 254}
256 255
257/* sysfs functions */ 256static int jc42_read(struct device *dev, enum hwmon_sensor_types type,
258 257 u32 attr, int channel, long *val)
259static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
260 char *buf)
261{
262 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
263 struct jc42_data *data = jc42_update_device(dev);
264 if (IS_ERR(data))
265 return PTR_ERR(data);
266 return sprintf(buf, "%d\n",
267 jc42_temp_from_reg(data->temp[attr->index]));
268}
269
270static ssize_t show_temp_hyst(struct device *dev,
271 struct device_attribute *devattr, char *buf)
272{ 258{
273 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
274 struct jc42_data *data = jc42_update_device(dev); 259 struct jc42_data *data = jc42_update_device(dev);
275 int temp, hyst; 260 int temp, hyst;
276 261
277 if (IS_ERR(data)) 262 if (IS_ERR(data))
278 return PTR_ERR(data); 263 return PTR_ERR(data);
279 264
280 temp = jc42_temp_from_reg(data->temp[attr->index]); 265 switch (attr) {
281 hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK) 266 case hwmon_temp_input:
282 >> JC42_CFG_HYST_SHIFT]; 267 *val = jc42_temp_from_reg(data->temp[t_input]);
283 return sprintf(buf, "%d\n", temp - hyst); 268 return 0;
269 case hwmon_temp_min:
270 *val = jc42_temp_from_reg(data->temp[t_min]);
271 return 0;
272 case hwmon_temp_max:
273 *val = jc42_temp_from_reg(data->temp[t_max]);
274 return 0;
275 case hwmon_temp_crit:
276 *val = jc42_temp_from_reg(data->temp[t_crit]);
277 return 0;
278 case hwmon_temp_max_hyst:
279 temp = jc42_temp_from_reg(data->temp[t_max]);
280 hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
281 >> JC42_CFG_HYST_SHIFT];
282 *val = temp - hyst;
283 return 0;
284 case hwmon_temp_crit_hyst:
285 temp = jc42_temp_from_reg(data->temp[t_crit]);
286 hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
287 >> JC42_CFG_HYST_SHIFT];
288 *val = temp - hyst;
289 return 0;
290 case hwmon_temp_min_alarm:
291 *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1;
292 return 0;
293 case hwmon_temp_max_alarm:
294 *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1;
295 return 0;
296 case hwmon_temp_crit_alarm:
297 *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1;
298 return 0;
299 default:
300 return -EOPNOTSUPP;
301 }
284} 302}
285 303
286static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, 304static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
287 const char *buf, size_t count) 305 u32 attr, int channel, long val)
288{ 306{
289 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
290 struct jc42_data *data = dev_get_drvdata(dev); 307 struct jc42_data *data = dev_get_drvdata(dev);
291 int err, ret = count; 308 struct i2c_client *client = data->client;
292 int nr = attr->index; 309 int diff, hyst;
293 long val; 310 int ret;
294 311
295 if (kstrtol(buf, 10, &val) < 0)
296 return -EINVAL;
297 mutex_lock(&data->update_lock); 312 mutex_lock(&data->update_lock);
298 data->temp[nr] = jc42_temp_to_reg(val, data->extended);
299 err = i2c_smbus_write_word_swapped(data->client, temp_regs[nr],
300 data->temp[nr]);
301 if (err < 0)
302 ret = err;
303 mutex_unlock(&data->update_lock);
304 return ret;
305}
306 313
307/* 314 switch (attr) {
308 * JC42.4 compliant chips only support four hysteresis values. 315 case hwmon_temp_min:
309 * Pick best choice and go from there. 316 data->temp[t_min] = jc42_temp_to_reg(val, data->extended);
310 */ 317 ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min],
311static ssize_t set_temp_crit_hyst(struct device *dev, 318 data->temp[t_min]);
312 struct device_attribute *attr, 319 break;
313 const char *buf, size_t count) 320 case hwmon_temp_max:
314{ 321 data->temp[t_max] = jc42_temp_to_reg(val, data->extended);
315 struct jc42_data *data = dev_get_drvdata(dev); 322 ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max],
316 long val; 323 data->temp[t_max]);
317 int diff, hyst; 324 break;
318 int err; 325 case hwmon_temp_crit:
319 int ret = count; 326 data->temp[t_crit] = jc42_temp_to_reg(val, data->extended);
320 327 ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit],
321 if (kstrtol(buf, 10, &val) < 0) 328 data->temp[t_crit]);
322 return -EINVAL; 329 break;
323 330 case hwmon_temp_crit_hyst:
324 val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED : 331 /*
325 JC42_TEMP_MIN) - 6000, JC42_TEMP_MAX); 332 * JC42.4 compliant chips only support four hysteresis values.
326 diff = jc42_temp_from_reg(data->temp[t_crit]) - val; 333 * Pick best choice and go from there.
327 334 */
328 hyst = 0; 335 val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED
329 if (diff > 0) { 336 : JC42_TEMP_MIN) - 6000,
330 if (diff < 2250) 337 JC42_TEMP_MAX);
331 hyst = 1; /* 1.5 degrees C */ 338 diff = jc42_temp_from_reg(data->temp[t_crit]) - val;
332 else if (diff < 4500) 339 hyst = 0;
333 hyst = 2; /* 3.0 degrees C */ 340 if (diff > 0) {
334 else 341 if (diff < 2250)
335 hyst = 3; /* 6.0 degrees C */ 342 hyst = 1; /* 1.5 degrees C */
343 else if (diff < 4500)
344 hyst = 2; /* 3.0 degrees C */
345 else
346 hyst = 3; /* 6.0 degrees C */
347 }
348 data->config = (data->config & ~JC42_CFG_HYST_MASK) |
349 (hyst << JC42_CFG_HYST_SHIFT);
350 ret = i2c_smbus_write_word_swapped(data->client,
351 JC42_REG_CONFIG,
352 data->config);
353 break;
354 default:
355 ret = -EOPNOTSUPP;
356 break;
336 } 357 }
337 358
338 mutex_lock(&data->update_lock);
339 data->config = (data->config & ~JC42_CFG_HYST_MASK)
340 | (hyst << JC42_CFG_HYST_SHIFT);
341 err = i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
342 data->config);
343 if (err < 0)
344 ret = err;
345 mutex_unlock(&data->update_lock); 359 mutex_unlock(&data->update_lock);
346 return ret;
347}
348 360
349static ssize_t show_alarm(struct device *dev, 361 return ret;
350 struct device_attribute *attr, char *buf)
351{
352 u16 bit = to_sensor_dev_attr(attr)->index;
353 struct jc42_data *data = jc42_update_device(dev);
354 u16 val;
355
356 if (IS_ERR(data))
357 return PTR_ERR(data);
358
359 val = data->temp[t_input];
360 if (bit != JC42_ALARM_CRIT_BIT && (data->config & JC42_CFG_CRIT_ONLY))
361 val = 0;
362 return sprintf(buf, "%u\n", (val >> bit) & 1);
363} 362}
364 363
365static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); 364static umode_t jc42_is_visible(const void *_data, enum hwmon_sensor_types type,
366static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, set_temp, t_crit); 365 u32 attr, int channel)
367static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, set_temp, t_min);
368static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, set_temp, t_max);
369
370static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_hyst,
371 set_temp_crit_hyst, t_crit);
372static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max);
373
374static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL,
375 JC42_ALARM_CRIT_BIT);
376static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL,
377 JC42_ALARM_MIN_BIT);
378static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
379 JC42_ALARM_MAX_BIT);
380
381static struct attribute *jc42_attributes[] = {
382 &sensor_dev_attr_temp1_input.dev_attr.attr,
383 &sensor_dev_attr_temp1_crit.dev_attr.attr,
384 &sensor_dev_attr_temp1_min.dev_attr.attr,
385 &sensor_dev_attr_temp1_max.dev_attr.attr,
386 &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
387 &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
388 &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
389 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
390 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
391 NULL
392};
393
394static umode_t jc42_attribute_mode(struct kobject *kobj,
395 struct attribute *attr, int index)
396{ 366{
397 struct device *dev = container_of(kobj, struct device, kobj); 367 const struct jc42_data *data = _data;
398 struct jc42_data *data = dev_get_drvdata(dev);
399 unsigned int config = data->config; 368 unsigned int config = data->config;
400 bool readonly; 369 umode_t mode = S_IRUGO;
401 370
402 if (attr == &sensor_dev_attr_temp1_crit.dev_attr.attr) 371 switch (attr) {
403 readonly = config & JC42_CFG_TCRIT_LOCK; 372 case hwmon_temp_min:
404 else if (attr == &sensor_dev_attr_temp1_min.dev_attr.attr || 373 case hwmon_temp_max:
405 attr == &sensor_dev_attr_temp1_max.dev_attr.attr) 374 if (!(config & JC42_CFG_EVENT_LOCK))
406 readonly = config & JC42_CFG_EVENT_LOCK; 375 mode |= S_IWUSR;
407 else if (attr == &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr) 376 break;
408 readonly = config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK); 377 case hwmon_temp_crit:
409 else 378 if (!(config & JC42_CFG_TCRIT_LOCK))
410 readonly = true; 379 mode |= S_IWUSR;
411 380 break;
412 return S_IRUGO | (readonly ? 0 : S_IWUSR); 381 case hwmon_temp_crit_hyst:
382 if (!(config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK)))
383 mode |= S_IWUSR;
384 break;
385 case hwmon_temp_input:
386 case hwmon_temp_max_hyst:
387 case hwmon_temp_min_alarm:
388 case hwmon_temp_max_alarm:
389 case hwmon_temp_crit_alarm:
390 break;
391 default:
392 mode = 0;
393 break;
394 }
395 return mode;
413} 396}
414 397
415static const struct attribute_group jc42_group = {
416 .attrs = jc42_attributes,
417 .is_visible = jc42_attribute_mode,
418};
419__ATTRIBUTE_GROUPS(jc42);
420
421/* Return 0 if detection is successful, -ENODEV otherwise */ 398/* Return 0 if detection is successful, -ENODEV otherwise */
422static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) 399static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)
423{ 400{
@@ -450,6 +427,34 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)
450 return -ENODEV; 427 return -ENODEV;
451} 428}
452 429
430static const u32 jc42_temp_config[] = {
431 HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | HWMON_T_CRIT |
432 HWMON_T_MAX_HYST | HWMON_T_CRIT_HYST |
433 HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,
434 0
435};
436
437static const struct hwmon_channel_info jc42_temp = {
438 .type = hwmon_temp,
439 .config = jc42_temp_config,
440};
441
442static const struct hwmon_channel_info *jc42_info[] = {
443 &jc42_temp,
444 NULL
445};
446
447static const struct hwmon_ops jc42_hwmon_ops = {
448 .is_visible = jc42_is_visible,
449 .read = jc42_read,
450 .write = jc42_write,
451};
452
453static const struct hwmon_chip_info jc42_chip_info = {
454 .ops = &jc42_hwmon_ops,
455 .info = jc42_info,
456};
457
453static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) 458static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
454{ 459{
455 struct device *dev = &client->dev; 460 struct device *dev = &client->dev;
@@ -482,9 +487,9 @@ static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id)
482 } 487 }
483 data->config = config; 488 data->config = config;
484 489
485 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 490 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
486 data, 491 data, &jc42_chip_info,
487 jc42_groups); 492 NULL);
488 return PTR_ERR_OR_ZERO(hwmon_dev); 493 return PTR_ERR_OR_ZERO(hwmon_dev);
489} 494}
490 495