aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-07-20 07:43:45 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2009-09-17 03:46:51 -0400
commitfb6c023a2b845df1ec383b74644ac35a4bbb76b6 (patch)
treedbb8acdaa37c8ce80ee702a55f672476b6e45444
parent39b1772a24126d74699cea623f96b50ca6b6f08f (diff)
hwmon: Add WM835x PMIC hardware monitoring driver
This driver provides reporting of the status supply voltage rails of the WM835x series of PMICs via the hwmon API. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--Documentation/hwmon/wm835026
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/wm8350-hwmon.c151
-rw-r--r--drivers/mfd/wm8350-core.c3
-rw-r--r--include/linux/mfd/wm8350/core.h6
6 files changed, 197 insertions, 0 deletions
diff --git a/Documentation/hwmon/wm8350 b/Documentation/hwmon/wm8350
new file mode 100644
index 000000000000..98f923bd2e92
--- /dev/null
+++ b/Documentation/hwmon/wm8350
@@ -0,0 +1,26 @@
1Kernel driver wm8350-hwmon
2==========================
3
4Supported chips:
5 * Wolfson Microelectronics WM835x PMICs
6 Prefix: 'wm8350'
7 Datasheet:
8 http://www.wolfsonmicro.com/products/WM8350
9 http://www.wolfsonmicro.com/products/WM8351
10 http://www.wolfsonmicro.com/products/WM8352
11
12Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
13
14Description
15-----------
16
17The WM835x series of PMICs include an AUXADC which can be used to
18monitor a range of system operating parameters, including the voltages
19of the major supplies within the system. Currently the driver provides
20simple access to these major supplies.
21
22Voltage Monitoring
23------------------
24
25Voltages are sampled by a 12 bit ADC. For the internal supplies the ADC
26is referenced to the system VRTC.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2e25b7a827d3..120085ce651a 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -937,6 +937,16 @@ config SENSORS_W83627EHF
937 This driver can also be built as a module. If so, the module 937 This driver can also be built as a module. If so, the module
938 will be called w83627ehf. 938 will be called w83627ehf.
939 939
940config SENSORS_WM8350
941 tristate "Wolfson Microelectronics WM835x"
942 depends on MFD_WM8350
943 help
944 If you say yes here you get support for the hardware
945 monitoring features of the WM835x series of PMICs.
946
947 This driver can also be built as a module. If so, the module
948 will be called wm8350-hwmon.
949
940config SENSORS_ULTRA45 950config SENSORS_ULTRA45
941 tristate "Sun Ultra45 PIC16F747" 951 tristate "Sun Ultra45 PIC16F747"
942 depends on SPARC64 952 depends on SPARC64
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 7f239a247c33..ed5f1781b8c4 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
90obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o 90obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
91obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o 91obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
92obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o 92obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o
93obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
93 94
94ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) 95ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
95EXTRA_CFLAGS += -DDEBUG 96EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c
new file mode 100644
index 000000000000..13290595ca86
--- /dev/null
+++ b/drivers/hwmon/wm8350-hwmon.c
@@ -0,0 +1,151 @@
1/*
2 * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC
3 * hardware monitoring features.
4 *
5 * Copyright (C) 2009 Wolfson Microelectronics plc
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License v2 as published by the
9 * Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/err.h>
24#include <linux/platform_device.h>
25#include <linux/hwmon.h>
26#include <linux/hwmon-sysfs.h>
27
28#include <linux/mfd/wm8350/core.h>
29#include <linux/mfd/wm8350/comparator.h>
30
31static ssize_t show_name(struct device *dev,
32 struct device_attribute *attr, char *buf)
33{
34 return sprintf(buf, "wm8350\n");
35}
36
37static const char *input_names[] = {
38 [WM8350_AUXADC_USB] = "USB",
39 [WM8350_AUXADC_LINE] = "Line",
40 [WM8350_AUXADC_BATT] = "Battery",
41};
42
43
44static ssize_t show_voltage(struct device *dev,
45 struct device_attribute *attr, char *buf)
46{
47 struct wm8350 *wm8350 = dev_get_drvdata(dev);
48 int channel = to_sensor_dev_attr(attr)->index;
49 int val;
50
51 val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF;
52 val = DIV_ROUND_CLOSEST(val, 1000);
53
54 return sprintf(buf, "%d\n", val);
55}
56
57static ssize_t show_label(struct device *dev,
58 struct device_attribute *attr, char *buf)
59{
60 int channel = to_sensor_dev_attr(attr)->index;
61
62 return sprintf(buf, "%s\n", input_names[channel]);
63}
64
65#define WM8350_NAMED_VOLTAGE(id, name) \
66 static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\
67 NULL, name); \
68 static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \
69 NULL, name)
70
71static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
72
73WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
74WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
75WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
76
77static struct attribute *wm8350_attributes[] = {
78 &dev_attr_name.attr,
79
80 &sensor_dev_attr_in0_input.dev_attr.attr,
81 &sensor_dev_attr_in0_label.dev_attr.attr,
82 &sensor_dev_attr_in1_input.dev_attr.attr,
83 &sensor_dev_attr_in1_label.dev_attr.attr,
84 &sensor_dev_attr_in2_input.dev_attr.attr,
85 &sensor_dev_attr_in2_label.dev_attr.attr,
86
87 NULL,
88};
89
90static const struct attribute_group wm8350_attr_group = {
91 .attrs = wm8350_attributes,
92};
93
94static int __devinit wm8350_hwmon_probe(struct platform_device *pdev)
95{
96 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
97 int ret;
98
99 ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group);
100 if (ret)
101 goto err;
102
103 wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev);
104 if (IS_ERR(wm8350->hwmon.classdev)) {
105 ret = PTR_ERR(wm8350->hwmon.classdev);
106 goto err_group;
107 }
108
109 return 0;
110
111err_group:
112 sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
113err:
114 return ret;
115}
116
117static int __devexit wm8350_hwmon_remove(struct platform_device *pdev)
118{
119 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
120
121 hwmon_device_unregister(wm8350->hwmon.classdev);
122 sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
123
124 return 0;
125}
126
127static struct platform_driver wm8350_hwmon_driver = {
128 .probe = wm8350_hwmon_probe,
129 .remove = __devexit_p(wm8350_hwmon_remove),
130 .driver = {
131 .name = "wm8350-hwmon",
132 .owner = THIS_MODULE,
133 },
134};
135
136static int __init wm8350_hwmon_init(void)
137{
138 return platform_driver_register(&wm8350_hwmon_driver);
139}
140module_init(wm8350_hwmon_init);
141
142static void __exit wm8350_hwmon_exit(void)
143{
144 platform_driver_unregister(&wm8350_hwmon_driver);
145}
146module_exit(wm8350_hwmon_exit);
147
148MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
149MODULE_DESCRIPTION("WM8350 Hardware Monitoring");
150MODULE_LICENSE("GPL");
151MODULE_ALIAS("platform:wm8350-hwmon");
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index fe24079387c5..9d662a576a41 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1472,6 +1472,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
1472 &(wm8350->codec.pdev)); 1472 &(wm8350->codec.pdev));
1473 wm8350_client_dev_register(wm8350, "wm8350-gpio", 1473 wm8350_client_dev_register(wm8350, "wm8350-gpio",
1474 &(wm8350->gpio.pdev)); 1474 &(wm8350->gpio.pdev));
1475 wm8350_client_dev_register(wm8350, "wm8350-hwmon",
1476 &(wm8350->hwmon.pdev));
1475 wm8350_client_dev_register(wm8350, "wm8350-power", 1477 wm8350_client_dev_register(wm8350, "wm8350-power",
1476 &(wm8350->power.pdev)); 1478 &(wm8350->power.pdev));
1477 wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev)); 1479 wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev));
@@ -1498,6 +1500,7 @@ void wm8350_device_exit(struct wm8350 *wm8350)
1498 platform_device_unregister(wm8350->wdt.pdev); 1500 platform_device_unregister(wm8350->wdt.pdev);
1499 platform_device_unregister(wm8350->rtc.pdev); 1501 platform_device_unregister(wm8350->rtc.pdev);
1500 platform_device_unregister(wm8350->power.pdev); 1502 platform_device_unregister(wm8350->power.pdev);
1503 platform_device_unregister(wm8350->hwmon.pdev);
1501 platform_device_unregister(wm8350->gpio.pdev); 1504 platform_device_unregister(wm8350->gpio.pdev);
1502 platform_device_unregister(wm8350->codec.pdev); 1505 platform_device_unregister(wm8350->codec.pdev);
1503 1506
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h
index 42cca672f340..969b0b55615c 100644
--- a/include/linux/mfd/wm8350/core.h
+++ b/include/linux/mfd/wm8350/core.h
@@ -605,6 +605,11 @@ struct wm8350_irq {
605 void *data; 605 void *data;
606}; 606};
607 607
608struct wm8350_hwmon {
609 struct platform_device *pdev;
610 struct device *classdev;
611};
612
608struct wm8350 { 613struct wm8350 {
609 struct device *dev; 614 struct device *dev;
610 615
@@ -629,6 +634,7 @@ struct wm8350 {
629 /* Client devices */ 634 /* Client devices */
630 struct wm8350_codec codec; 635 struct wm8350_codec codec;
631 struct wm8350_gpio gpio; 636 struct wm8350_gpio gpio;
637 struct wm8350_hwmon hwmon;
632 struct wm8350_pmic pmic; 638 struct wm8350_pmic pmic;
633 struct wm8350_power power; 639 struct wm8350_power power;
634 struct wm8350_rtc rtc; 640 struct wm8350_rtc rtc;