linux/drivers/hwmon/wm8350-hwmon.c
<<
>>
Prefs
   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");
 152