Hi Mark, On Mon, Jul 20, 2009 at 12:43:45PM +0100, Mark Brown wrote: > This driver provides reporting of the status supply voltage rails > of the WM835x series of PMICs via the hwmon API. Applied to my for-next branch, thanks. Cheers, Samuel. > Signed-off-by: Mark Brown <broonie at opensource.wolfsonmicro.com> > --- > > This should address all the issues Jean raised: > - Add a brief document to the hwmon directory. > - Use full constant names as arguments for template macro. > - Use DIV_ROUND_CLOSEST() > - Set driver owner. > - Fix typos. > > Thanks to Jonathan and Jean for their reviews. > > Documentation/hwmon/wm8350 | 26 +++++++ > drivers/hwmon/Kconfig | 10 +++ > drivers/hwmon/Makefile | 1 + > drivers/hwmon/wm8350-hwmon.c | 151 +++++++++++++++++++++++++++++++++++++++ > drivers/mfd/wm8350-core.c | 3 + > include/linux/mfd/wm8350/core.h | 6 ++ > 6 files changed, 197 insertions(+), 0 deletions(-) > create mode 100644 Documentation/hwmon/wm8350 > create mode 100644 drivers/hwmon/wm8350-hwmon.c > > diff --git a/Documentation/hwmon/wm8350 b/Documentation/hwmon/wm8350 > new file mode 100644 > index 0000000..98f923b > --- /dev/null > +++ b/Documentation/hwmon/wm8350 > @@ -0,0 +1,26 @@ > +Kernel driver wm8350-hwmon > +========================== > + > +Supported chips: > + * Wolfson Microelectronics WM835x PMICs > + Prefix: 'wm8350' > + Datasheet: > + http://www.wolfsonmicro.com/products/WM8350 > + http://www.wolfsonmicro.com/products/WM8351 > + http://www.wolfsonmicro.com/products/WM8352 > + > +Authors: Mark Brown <broonie at opensource.wolfsonmicro.com> > + > +Description > +----------- > + > +The WM835x series of PMICs include an AUXADC which can be used to > +monitor a range of system operating parameters, including the voltages > +of the major supplies within the system. Currently the driver provides > +simple access to these major supplies. > + > +Voltage Monitoring > +------------------ > + > +Voltages are sampled by a 12 bit ADC. For the internal supplies the ADC > +is referenced to the system VRTC. > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index 2d50166..c94d708 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -920,6 +920,16 @@ config SENSORS_W83627EHF > This driver can also be built as a module. If so, the module > will be called w83627ehf. > > +config SENSORS_WM8350 > + tristate "Wolfson Microelectronics WM835x" > + depends on MFD_WM8350 > + help > + If you say yes here you get support for the hardware > + monitoring features of the WM835x series of PMICs. > + > + This driver can also be built as a module. If so, the module > + will be called wm8350-hwmon. > + > config SENSORS_ULTRA45 > tristate "Sun Ultra45 PIC16F747" > depends on SPARC64 > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile > index b793dce..c02e90e 100644 > --- a/drivers/hwmon/Makefile > +++ b/drivers/hwmon/Makefile > @@ -89,6 +89,7 @@ obj-$(CONFIG_SENSORS_VT8231) += vt8231.o > obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o > obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o > obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o > +obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o > > ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) > EXTRA_CFLAGS += -DDEBUG > diff --git a/drivers/hwmon/wm8350-hwmon.c b/drivers/hwmon/wm8350-hwmon.c > new file mode 100644 > index 0000000..1329059 > --- /dev/null > +++ b/drivers/hwmon/wm8350-hwmon.c > @@ -0,0 +1,151 @@ > +/* > + * drivers/hwmon/wm8350-hwmon.c - Wolfson Microelectronics WM8350 PMIC > + * hardware monitoring features. > + * > + * Copyright (C) 2009 Wolfson Microelectronics plc > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License v2 as published by the > + * Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, but WITHOUT > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for > + * more details. > + * > + * You should have received a copy of the GNU General Public License along with > + * this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/err.h> > +#include <linux/platform_device.h> > +#include <linux/hwmon.h> > +#include <linux/hwmon-sysfs.h> > + > +#include <linux/mfd/wm8350/core.h> > +#include <linux/mfd/wm8350/comparator.h> > + > +static ssize_t show_name(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + return sprintf(buf, "wm8350\n"); > +} > + > +static const char *input_names[] = { > + [WM8350_AUXADC_USB] = "USB", > + [WM8350_AUXADC_LINE] = "Line", > + [WM8350_AUXADC_BATT] = "Battery", > +}; > + > + > +static ssize_t show_voltage(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct wm8350 *wm8350 = dev_get_drvdata(dev); > + int channel = to_sensor_dev_attr(attr)->index; > + int val; > + > + val = wm8350_read_auxadc(wm8350, channel, 0, 0) * WM8350_AUX_COEFF; > + val = DIV_ROUND_CLOSEST(val, 1000); > + > + return sprintf(buf, "%d\n", val); > +} > + > +static ssize_t show_label(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + int channel = to_sensor_dev_attr(attr)->index; > + > + return sprintf(buf, "%s\n", input_names[channel]); > +} > + > +#define WM8350_NAMED_VOLTAGE(id, name) \ > + static SENSOR_DEVICE_ATTR(in##id##_input, S_IRUGO, show_voltage,\ > + NULL, name); \ > + static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label, \ > + NULL, name) > + > +static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); > + > +WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB); > +WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT); > +WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE); > + > +static struct attribute *wm8350_attributes[] = { > + &dev_attr_name.attr, > + > + &sensor_dev_attr_in0_input.dev_attr.attr, > + &sensor_dev_attr_in0_label.dev_attr.attr, > + &sensor_dev_attr_in1_input.dev_attr.attr, > + &sensor_dev_attr_in1_label.dev_attr.attr, > + &sensor_dev_attr_in2_input.dev_attr.attr, > + &sensor_dev_attr_in2_label.dev_attr.attr, > + > + NULL, > +}; > + > +static const struct attribute_group wm8350_attr_group = { > + .attrs = wm8350_attributes, > +}; > + > +static int __devinit wm8350_hwmon_probe(struct platform_device *pdev) > +{ > + struct wm8350 *wm8350 = platform_get_drvdata(pdev); > + int ret; > + > + ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group); > + if (ret) > + goto err; > + > + wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev); > + if (IS_ERR(wm8350->hwmon.classdev)) { > + ret = PTR_ERR(wm8350->hwmon.classdev); > + goto err_group; > + } > + > + return 0; > + > +err_group: > + sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group); > +err: > + return ret; > +} > + > +static int __devexit wm8350_hwmon_remove(struct platform_device *pdev) > +{ > + struct wm8350 *wm8350 = platform_get_drvdata(pdev); > + > + hwmon_device_unregister(wm8350->hwmon.classdev); > + sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group); > + > + return 0; > +} > + > +static struct platform_driver wm8350_hwmon_driver = { > + .probe = wm8350_hwmon_probe, > + .remove = __devexit_p(wm8350_hwmon_remove), > + .driver = { > + .name = "wm8350-hwmon", > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init wm8350_hwmon_init(void) > +{ > + return platform_driver_register(&wm8350_hwmon_driver); > +} > +module_init(wm8350_hwmon_init); > + > +static void __exit wm8350_hwmon_exit(void) > +{ > + platform_driver_unregister(&wm8350_hwmon_driver); > +} > +module_exit(wm8350_hwmon_exit); > + > +MODULE_AUTHOR("Mark Brown <broonie at opensource.wolfsonmicro.com>"); > +MODULE_DESCRIPTION("WM8350 Hardware Monitoring"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:wm8350-hwmon"); > diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c > index fe24079..9d662a5 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, > &(wm8350->codec.pdev)); > wm8350_client_dev_register(wm8350, "wm8350-gpio", > &(wm8350->gpio.pdev)); > + wm8350_client_dev_register(wm8350, "wm8350-hwmon", > + &(wm8350->hwmon.pdev)); > wm8350_client_dev_register(wm8350, "wm8350-power", > &(wm8350->power.pdev)); > wm8350_client_dev_register(wm8350, "wm8350-rtc", &(wm8350->rtc.pdev)); > @@ -1498,6 +1500,7 @@ void wm8350_device_exit(struct wm8350 *wm8350) > platform_device_unregister(wm8350->wdt.pdev); > platform_device_unregister(wm8350->rtc.pdev); > platform_device_unregister(wm8350->power.pdev); > + platform_device_unregister(wm8350->hwmon.pdev); > platform_device_unregister(wm8350->gpio.pdev); > platform_device_unregister(wm8350->codec.pdev); > > diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h > index 42cca67..969b0b5 100644 > --- a/include/linux/mfd/wm8350/core.h > +++ b/include/linux/mfd/wm8350/core.h > @@ -605,6 +605,11 @@ struct wm8350_irq { > void *data; > }; > > +struct wm8350_hwmon { > + struct platform_device *pdev; > + struct device *classdev; > +}; > + > struct wm8350 { > struct device *dev; > > @@ -629,6 +634,7 @@ struct wm8350 { > /* Client devices */ > struct wm8350_codec codec; > struct wm8350_gpio gpio; > + struct wm8350_hwmon hwmon; > struct wm8350_pmic pmic; > struct wm8350_power power; > struct wm8350_rtc rtc; > -- > 1.6.3.3 > -- Intel Open Source Technology Centre http://oss.intel.com/