1*21eb0be9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fb6c023aSMark Brown /*
3fb6c023aSMark Brown * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC
4fb6c023aSMark Brown * hardware monitoring features.
5fb6c023aSMark Brown *
6fb6c023aSMark Brown * Copyright (C) 2009 Wolfson Microelectronics plc
7fb6c023aSMark Brown */
8fb6c023aSMark Brown
9fb6c023aSMark Brown #include <linux/kernel.h>
10fb6c023aSMark Brown #include <linux/module.h>
11fb6c023aSMark Brown #include <linux/err.h>
12fb6c023aSMark Brown #include <linux/platform_device.h>
13fb6c023aSMark Brown #include <linux/hwmon.h>
14fb6c023aSMark Brown #include <linux/hwmon-sysfs.h>
15fb6c023aSMark Brown
16fb6c023aSMark Brown #include <linux/mfd/wm8350/core.h>
17fb6c023aSMark Brown #include <linux/mfd/wm8350/comparator.h>
18fb6c023aSMark Brown
19a68abd32SGuenter Roeck static const char * const input_names[] = {
20fb6c023aSMark Brown [WM8350_AUXADC_USB] = "USB",
21fb6c023aSMark Brown [WM8350_AUXADC_LINE] = "Line",
22fb6c023aSMark Brown [WM8350_AUXADC_BATT] = "Battery",
23fb6c023aSMark Brown };
24fb6c023aSMark Brown
show_voltage(struct device * dev,struct device_attribute * attr,char * buf)25fb6c023aSMark Brown static ssize_t show_voltage(struct device *dev,
26fb6c023aSMark Brown struct device_attribute *attr, char *buf)
27fb6c023aSMark Brown {
28fb6c023aSMark Brown struct wm8350 *wm8350 = dev_get_drvdata(dev);
29fb6c023aSMark Brown int channel = to_sensor_dev_attr(attr)->index;
30fb6c023aSMark Brown int val;
31fb6c023aSMark Brown
32fb6c023aSMark Brown val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF;
33fb6c023aSMark Brown val = DIV_ROUND_CLOSEST(val, 1000);
34fb6c023aSMark Brown
35fb6c023aSMark Brown return sprintf(buf, "%d\n", val);
36fb6c023aSMark Brown }
37fb6c023aSMark Brown
show_label(struct device * dev,struct device_attribute * attr,char * buf)38fb6c023aSMark Brown static ssize_t show_label(struct device *dev,
39fb6c023aSMark Brown struct device_attribute *attr, char *buf)
40fb6c023aSMark Brown {
41fb6c023aSMark Brown int channel = to_sensor_dev_attr(attr)->index;
42fb6c023aSMark Brown
43fb6c023aSMark Brown return sprintf(buf, "%s\n", input_names[channel]);
44fb6c023aSMark Brown }
45fb6c023aSMark Brown
46fb6c023aSMark Brown #define WM8350_NAMED_VOLTAGE(id, name) \
47fb6c023aSMark Brown static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\
48fb6c023aSMark Brown NULL, name); \
49fb6c023aSMark Brown static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \
50fb6c023aSMark Brown NULL, name)
51fb6c023aSMark Brown
52fb6c023aSMark Brown WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
53fb6c023aSMark Brown WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
54fb6c023aSMark Brown WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
55fb6c023aSMark Brown
56b3aabd6dSAxel Lin static struct attribute *wm8350_attrs[] = {
57fb6c023aSMark Brown &sensor_dev_attr_in0_input.dev_attr.attr,
58fb6c023aSMark Brown &sensor_dev_attr_in0_label.dev_attr.attr,
59fb6c023aSMark Brown &sensor_dev_attr_in1_input.dev_attr.attr,
60fb6c023aSMark Brown &sensor_dev_attr_in1_label.dev_attr.attr,
61fb6c023aSMark Brown &sensor_dev_attr_in2_input.dev_attr.attr,
62fb6c023aSMark Brown &sensor_dev_attr_in2_label.dev_attr.attr,
63fb6c023aSMark Brown
64fb6c023aSMark Brown NULL,
65fb6c023aSMark Brown };
66fb6c023aSMark Brown
67b3aabd6dSAxel Lin ATTRIBUTE_GROUPS(wm8350);
68fb6c023aSMark Brown
wm8350_hwmon_probe(struct platform_device * pdev)696c931ae1SBill Pemberton static int wm8350_hwmon_probe(struct platform_device *pdev)
70fb6c023aSMark Brown {
71fb6c023aSMark Brown struct wm8350 *wm8350 = platform_get_drvdata(pdev);
72b3aabd6dSAxel Lin struct device *hwmon_dev;
73fb6c023aSMark Brown
74b3aabd6dSAxel Lin hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm8350",
75b3aabd6dSAxel Lin wm8350,
76b3aabd6dSAxel Lin wm8350_groups);
77b3aabd6dSAxel Lin return PTR_ERR_OR_ZERO(hwmon_dev);
78fb6c023aSMark Brown }
79fb6c023aSMark Brown
80fb6c023aSMark Brown static struct platform_driver wm8350_hwmon_driver = {
81fb6c023aSMark Brown .probe = wm8350_hwmon_probe,
82fb6c023aSMark Brown .driver = {
83fb6c023aSMark Brown .name = "wm8350-hwmon",
84fb6c023aSMark Brown },
85fb6c023aSMark Brown };
86fb6c023aSMark Brown
8725a236a5SAxel Lin module_platform_driver(wm8350_hwmon_driver);
88fb6c023aSMark Brown
89fb6c023aSMark Brown MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
90fb6c023aSMark Brown MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
91fb6c023aSMark Brown MODULE_LICENSE("GPL");
92fb6c023aSMark Brown MODULE_ALIAS("platform:wm8350-hwmon");
93