diff options
author | Guenter Roeck <linux@roeck-us.net> | 2016-07-03 00:40:19 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2016-09-09 00:34:18 -0400 |
commit | fcc448cfe48ed7a74a299709457b32a7e5ca663a (patch) | |
tree | 8569f3789b778f7d60356f76f08dd30f89ea699d | |
parent | 54187ff9d766b2138bd83df74b6df7d78d422965 (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.c | 293 |
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 */ | 256 | static int jc42_read(struct device *dev, enum hwmon_sensor_types type, |
258 | 257 | u32 attr, int channel, long *val) | |
259 | static 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 | |||
270 | static 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 | ||
286 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | 304 | static 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], |
311 | static 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 | ||
349 | static 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 | ||
365 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input); | 364 | static umode_t jc42_is_visible(const void *_data, enum hwmon_sensor_types type, |
366 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, set_temp, t_crit); | 365 | u32 attr, int channel) |
367 | static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, set_temp, t_min); | ||
368 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, set_temp, t_max); | ||
369 | |||
370 | static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO, show_temp_hyst, | ||
371 | set_temp_crit_hyst, t_crit); | ||
372 | static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max); | ||
373 | |||
374 | static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, | ||
375 | JC42_ALARM_CRIT_BIT); | ||
376 | static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, | ||
377 | JC42_ALARM_MIN_BIT); | ||
378 | static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, | ||
379 | JC42_ALARM_MAX_BIT); | ||
380 | |||
381 | static 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 | |||
394 | static 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 | ||
415 | static 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 */ |
422 | static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) | 399 | static 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 | ||
430 | static 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 | |||
437 | static const struct hwmon_channel_info jc42_temp = { | ||
438 | .type = hwmon_temp, | ||
439 | .config = jc42_temp_config, | ||
440 | }; | ||
441 | |||
442 | static const struct hwmon_channel_info *jc42_info[] = { | ||
443 | &jc42_temp, | ||
444 | NULL | ||
445 | }; | ||
446 | |||
447 | static const struct hwmon_ops jc42_hwmon_ops = { | ||
448 | .is_visible = jc42_is_visible, | ||
449 | .read = jc42_read, | ||
450 | .write = jc42_write, | ||
451 | }; | ||
452 | |||
453 | static const struct hwmon_chip_info jc42_chip_info = { | ||
454 | .ops = &jc42_hwmon_ops, | ||
455 | .info = jc42_info, | ||
456 | }; | ||
457 | |||
453 | static int jc42_probe(struct i2c_client *client, const struct i2c_device_id *id) | 458 | static 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 | ||