[PATCH] hwmon: Driver for ADT7410

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,
this patch brings basic support for the Analog Devices ADT7410 temperature sensor, based on the lm75 hwmon driver and the adt7410 iio driver. The following functionality has been implemented:

  * get current temperature
  * get/set minimum, maximum and critical temperature
  * get/set hysteresis
  * get alarm events for minimum, maximum and critical temperature

The ADT7410 provides some more configuration options, but would need non-standard sysfs symbols, so I prefer to get some feedback before implementing any:

  * get/set resolution (13/16 bits): temp#_resolution (13/16)?
  * get/set event mode (comparator/interrupt): temp#_eventmode (0/1)?
  * get/set polarity of INT pin (active-high/active-low): temp#_INT (0/1)?
  * get/set polarity of CT pin (active-high/active-low): temp#_CT (0/1)?
  * get/set sampling mode (continous/one sample per second/one-shot/power-down): temp#_mode (0/1/2/3)?
  * get/set fault queue (1 to 4 faults to trigger event): temp#_faultqueue (1/2/3/4)?
  * get device id: temp#_id?

Besides, I saw that there are several sensors (including the ADT7410) which have just one hysteresis register, that stores a delta value that applies to min, max and critical temperature. How are the chances to create a standard symbol "temp#_hyst"?

All implemented sysfs-symbols have been sucessfully tested at temperatures of 15°C to 40°C.

Signed-off-by: Hartmut Knaack <knaack.h <at> gmx.de>
---
diff --git a/Documentation/hwmon/adt7410 b/Documentation/hwmon/adt7410
new file mode 100644
index 0000000..5ccae11
--- /dev/null
+++ b/Documentation/hwmon/adt7410
@@ -0,0 +1,47 @@
+Kernel driver adt7410
+=====================
+
+Supported chips:
+  * Analog Devices ADT7410
+    Prefix: 'adt7410'
+    Addresses scanned: I2C 0x48 - 0x4B
+    Datasheet: Publicly available at the Analog Devices website
+               http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf
+
+Author: Hartmut Knaack <knaack.h <at> gmx.de>
+
+Description
+-----------
+
+The ADT7410 is a temperature sensor with rated temperature range of -55°C to
++150°C. It has a high accuracy of +/-0.5°C and can be operated at a resolution
+of 13 bits (0.0625°C) or 16 bits (0.0078°C). The sensor provides an INT pin to
+indicate an excession of a set minimum or maximum temperature, as well as a
+critical temperature (CT) pin to indicate an excession of a set critical
+temperature. Both pins can be set up with a common hysteresis of 0°C - 15°C
+and a fault queue ranging from 1 to 4 events. Both pins can individually set
+to be active-low or active-high, while the whole device can either run in
+comparator mode or interrupt mode. The ADT7410 supports continous temperature
+sampling, as well as sampling one temperature value per second or even just
+get one sample on demand for power saving. Besides, it can completely power
+down its ADC, if power management is required.
+
+Configuration Notes
+-------------------
+
+Since the device uses one hysteresis value, which is a delta to minimum,
+maximum and critical temperature, the driver will represent it as
+temp#_max_hyst.
+The device is set to 16 bit resolution and comparator mode by default.
+
+sysfs-Interface
+---------------
+
+temp#_input        - temperature input
+temp#_min        - temperature minimum setpoint
+temp#_max        - temperature maximum setpoint
+temp#_crit        - critical temperature setpoint
+temp#_max_hyst        - hysteresis for temperature maximum
+temp#_min_alarm        - temperature minimum alarm flag
+temp#_max_alarm        - temperature maximum alarm flag
+temp#_crit_alarm    - critical temperature alarm flag
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6f1d167..7ed1989 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -179,6 +179,16 @@ config SENSORS_ADM9240
       This driver can also be built as a module.  If so, the module
       will be called adm9240.
 
+config SENSORS_ADT7410
+    tristate "Analog Devices ADT7410"
+    depends on I2C && EXPERIMENTAL
+    help
+      If you say yes here you get support for the Analog Devices
+      ADT7410 temperature monitoring chip.
+
+      This driver can also be built as a module. If so, the module
+      will be called adt7410.
+
 config SENSORS_ADT7411
     tristate "Analog Devices ADT7411"
     depends on I2C && EXPERIMENTAL
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index e1eeac1..112ce3a 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADM9240)    += adm9240.o
 obj-$(CONFIG_SENSORS_ADS1015)    += ads1015.o
 obj-$(CONFIG_SENSORS_ADS7828)    += ads7828.o
 obj-$(CONFIG_SENSORS_ADS7871)    += ads7871.o
+obj-$(CONFIG_SENSORS_ADT7410)    += adt7410.o
 obj-$(CONFIG_SENSORS_ADT7411)    += adt7411.o
 obj-$(CONFIG_SENSORS_ADT7462)    += adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)    += adt7470.o
diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c
new file mode 100644
index 0000000..49f3c10
--- /dev/null
+++ b/drivers/hwmon/adt7410.c
@@ -0,0 +1,539 @@
+/*
+ * adt7410.c - Part of lm_sensors, Linux kernel modules for hardware
+ *     monitoring
+ * Hartmut Knaack <knaack.h <at> gmx.de> 2012-07-22
+ * based on lm75.c by Frodo Looijaard <frodol <at> dds.nl>
+ * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang <at> analog.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/*
+ * ADT7410 registers definition
+ */
+
+#define ADT7410_TEMPERATURE        0
+#define ADT7410_STATUS            2
+#define ADT7410_CONFIG            3
+#define ADT7410_T_ALARM_HIGH        4
+#define ADT7410_T_ALARM_LOW        6
+#define ADT7410_T_CRIT            8
+#define ADT7410_T_HYST            0xA
+#define ADT7410_ID            0xB
+#define ADT7410_RESET            0x2F
+
+/*
+ * ADT7410 status
+ */
+#define ADT7410_STAT_T_LOW        0x10
+#define ADT7410_STAT_T_HIGH        0x20
+#define ADT7410_STAT_T_CRIT        0x40
+#define ADT7410_STAT_NOT_RDY        0x80
+
+/*
+ * ADT7410 config
+ */
+#define ADT7410_FAULT_QUEUE_MASK    0x3
+#define ADT7410_CT_POLARITY        0x4
+#define ADT7410_INT_POLARITY        0x8
+#define ADT7410_EVENT_MODE        0x10
+#define ADT7410_MODE_MASK        0x60
+#define ADT7410_FULL            0x0
+#define ADT7410_ONESHOT            0x20
+#define ADT7410_SPS            0x40
+#define ADT7410_PD            0x60
+#define ADT7410_RESOLUTION        0x80
+
+/*
+ * ADT7410 masks
+ */
+#define ADT7410_T16_VALUE_SIGN            0x8000
+#define ADT7410_T16_VALUE_FLOAT_OFFSET        7
+#define ADT7410_T16_VALUE_FLOAT_MASK        0x7F
+#define ADT7410_T13_VALUE_MASK            0xFFF8
+#define ADT7410_T_HYST_MASK            0xF
+#define ADT7410_DEVICE_ID_MASK            0x7
+#define ADT7410_MANUFACTORE_ID_OFFSET        3
+#define ADT7410_MANUFACTURE_ID            0x19
+#define ADT7410_IRQS                2
+
+
+/* straight from the datasheet */
+#define ADT7410_TEMP_MIN (-55000)
+#define ADT7410_TEMP_MAX 150000
+
+/*
+ * This driver handles the ADT7410 and compatible digital temperature sensors.
+ */
+
+enum adt7410_type {        /* keep sorted in alphabetical order */
+    adt7410,
+};
+
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+                    I2C_CLIENT_END };
+
+static const u8 ADT7410_REG_TEMP[4] = {
+    ADT7410_TEMPERATURE,        /* input */
+    ADT7410_T_ALARM_HIGH,        /* high */
+    ADT7410_T_ALARM_LOW,        /* low */
+    ADT7410_T_CRIT,            /* critical */
+};
+
+/* Each client has this additional data */
+struct adt7410_data {
+    struct device        *hwmon_dev;
+    struct mutex        update_lock;
+    u8            config;
+    char            valid;        /* !=0 if registers are valid */
+    unsigned long        last_updated;    /* In jiffies */
+    u16            temp[4];    /* Register values,
+                           0 = input
+                           1 = high
+                           2 = low
+                           3 = critical */
+};
+
+/*
+ * adt7410 register access by I2C
+ */
+
+static int adt7410_i2c_read_word(struct i2c_client *client, u8 reg, u16 *data)
+{
+    int ret = 0;
+    ret = i2c_smbus_read_word_data(client, reg);
+    if (ret < 0) {
+        dev_err(&client->dev, "I2C read error\n");
+        return ret;
+    }
+
+    *data = swab16((u16)ret);
+
+    return 0;
+}
+
+static int adt7410_i2c_write_word(struct i2c_client *client, u8 reg, u16 data)
+{
+    int ret = 0;
+    ret = i2c_smbus_write_word_data(client, reg, swab16(data));
+    if (ret < 0)
+        dev_err(&client->dev, "I2C write error\n");
+
+    return ret;
+}
+
+static int adt7410_i2c_read_byte(struct i2c_client *client, u8 reg, u8 *data)
+{
+    int ret = 0;
+    ret = i2c_smbus_read_byte_data(client, reg);
+    if (ret < 0) {
+        dev_err(&client->dev, "I2C read error\n");
+        return ret;
+    }
+
+    *data = (u8)ret;
+
+    return 0;
+}
+
+static int adt7410_i2c_write_byte(struct i2c_client *client, u8 reg, u8 data)
+{
+    int ret = 0;
+    ret = i2c_smbus_write_byte_data(client, reg, data);
+    if (ret < 0)
+        dev_err(&client->dev, "I2C write error\n");
+
+    return ret;
+}
+
+static struct adt7410_data *adt7410_update_device(struct device *dev)
+{
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    struct adt7410_data *ret = data;
+    mutex_lock(&data->update_lock);
+
+    if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+        || !data->valid) {
+        int i;
+        dev_dbg(&client->dev, "Starting adt7410 update\n");
+
+        for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
+            int status;
+            if (i == 0) {        /* wait for register to */
+                int j = 0;    /* contain valid data */
+                u8 sreg;
+                do {
+                    status = adt7410_i2c_read_byte(client,
+                          ADT7410_STATUS, &sreg);
+                    if (status)
+                        return ERR_PTR(-EIO);
+                    j++;
+                    if (j == 10000)
+                        return ERR_PTR(-EIO);
+                    } while (sreg & ADT7410_STAT_NOT_RDY);
+            }
+            status = adt7410_i2c_read_word(client,
+                        ADT7410_REG_TEMP[i],
+                        &data->temp[i]);
+            if (unlikely(status < 0)) {
+                dev_dbg(dev,
+                    "ADT7410: Failed to read value: reg %d, error %d\n",
+                    ADT7410_REG_TEMP[i], status);
+                ret = ERR_PTR(status);
+                data->valid = 0;
+                goto abort;
+            }
+        }
+        data->last_updated = jiffies;
+        data->valid = 1;
+    }
+
+abort:
+    mutex_unlock(&data->update_lock);
+    return ret;
+}
+
+static u16 ADT7410_TEMP_TO_REG(long temp)
+{
+    return (u16)((SENSORS_LIMIT(temp, ADT7410_TEMP_MIN,
+            ADT7410_TEMP_MAX) * 128) / 1000);
+}
+
+static int ADT7410_REG_TO_TEMP(struct adt7410_data *data,
+        u16 reg)
+{
+    /* in 13 bit mode, bits 0-2 are status flags - mask them out */
+    if (!(data->config & ADT7410_RESOLUTION))
+        reg &= ADT7410_T13_VALUE_MASK;
+    /* temperature is stored in twos complement format, in steps of
+     * 1/128°C */
+    return (((int)reg * 1000) / 128);
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+
+/* sysfs attributes for hwmon */
+
+static ssize_t adt7410_show_temp(struct device *dev,
+        struct device_attribute *da,
+        char *buf)
+{
+    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+    struct adt7410_data *data = adt7410_update_device(dev);
+    if (IS_ERR(data))
+        return PTR_ERR(data);
+
+    return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data,
+            data->temp[attr->index]));
+}
+
+static ssize_t adt7410_set_temp(struct device *dev,
+        struct device_attribute *da,
+        const char *buf, size_t count)
+{
+    struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    int nr = attr->index;
+    long temp;
+    int ret;
+    ret = kstrtol(buf, 10, &temp);
+    if (ret)
+        return -EINVAL;
+
+    mutex_lock(&data->update_lock);
+    data->temp[nr] = ADT7410_TEMP_TO_REG(temp);
+    adt7410_i2c_write_word(client, ADT7410_REG_TEMP[nr], data->temp[nr]);
+    mutex_unlock(&data->update_lock);
+    return count;
+}
+
+static ssize_t adt7410_show_t_hyst(struct device *dev,
+        struct device_attribute *attr,
+        char *buf)
+{
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    int ret;
+    u8 t_hyst;
+    ret = adt7410_i2c_read_byte(client, ADT7410_T_HYST, &t_hyst);
+    if (ret)
+        return -EIO;
+    /* hysteresis is stored as a 4 bit delta in the device, convert it
+     * to an absolute value in relation to t_max */
+    return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, data->temp[1] -
+            ((u16)(t_hyst & ADT7410_T_HYST_MASK) << 7)));
+}
+
+static ssize_t adt7410_set_t_hyst(struct device *dev,
+        struct device_attribute *da,
+        const char *buf, size_t count)
+{
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    int ret;
+    long hyst;
+    u8 t_hyst;
+    ret = kstrtol(buf, 10, &hyst);
+    if ((hyst < ADT7410_TEMP_MIN) || (hyst > ADT7410_TEMP_MAX))
+        return -EINVAL;
+    /* convert absolute hysteresis value to a 4 bit delta value */
+    t_hyst = (u8)(((s32)((data->temp[1] * 1000) / 128) - hyst) / 1000);
+    if (ret || (t_hyst > ADT7410_T_HYST_MASK))
+        return -EINVAL;
+
+    ret = adt7410_i2c_write_byte(client, ADT7410_T_HYST, t_hyst);
+    if (ret)
+        return -EIO;
+
+    return count;
+}
+
+static ssize_t adt7410_show_alarm(struct device *dev,
+        u8 status,
+        char *buf)
+{
+    struct i2c_client *client = to_i2c_client(dev);
+    u8 reg;
+    int ret = 0;
+    ret = adt7410_i2c_read_byte(client, ADT7410_STATUS, &reg);
+    if (ret)
+        return -EIO;
+
+    return sprintf(buf, "%d\n", (reg & status) ? 1 : 0);
+}
+
+static ssize_t adt7410_show_min_alarm(struct device *dev,
+        struct device_attribute *attr,
+        char *buf)
+{
+    return adt7410_show_alarm(dev, ADT7410_STAT_T_LOW, buf);
+}
+
+static ssize_t adt7410_show_max_alarm(struct device *dev,
+        struct device_attribute *attr,
+        char *buf)
+{
+    return adt7410_show_alarm(dev, ADT7410_STAT_T_HIGH, buf);
+}
+
+static ssize_t adt7410_show_crit_alarm(struct device *dev,
+        struct device_attribute *attr,
+        char *buf)
+{
+    return adt7410_show_alarm(dev, ADT7410_STAT_T_CRIT, buf);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7410_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+            adt7410_show_temp, adt7410_set_temp, 1);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
+            adt7410_show_temp, adt7410_set_temp, 2);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO,
+            adt7410_show_temp, adt7410_set_temp, 3);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+            adt7410_show_t_hyst, adt7410_set_t_hyst, 4);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IWUSR | S_IRUGO,
+            adt7410_show_min_alarm, NULL, 5);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IWUSR | S_IRUGO,
+            adt7410_show_max_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IWUSR | S_IRUGO,
+            adt7410_show_crit_alarm, NULL, 7);
+
+static struct attribute *adt7410_attributes[] = {
+    &sensor_dev_attr_temp1_input.dev_attr.attr,
+    &sensor_dev_attr_temp1_max.dev_attr.attr,
+    &sensor_dev_attr_temp1_min.dev_attr.attr,
+    &sensor_dev_attr_temp1_crit.dev_attr.attr,
+    &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+    &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+    &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+    &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+    NULL
+};
+
+static const struct attribute_group adt7410_group = {
+    .attrs = adt7410_attributes,
+};
+
+/*-----------------------------------------------------------------------*/
+
+/* device probe and removal */
+
+static int
+adt7410_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+    struct adt7410_data *data;
+    int ret = 0;
+    u8 set_mask, clr_mask;
+    int new;
+    if (!i2c_check_functionality(client->adapter,
+            I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+        return -EIO;
+
+    data = kzalloc(sizeof(struct adt7410_data), GFP_KERNEL);
+    if (!data)
+        return -ENOMEM;
+
+    i2c_set_clientdata(client, data);
+    mutex_init(&data->update_lock);
+
+    /* Set to 16 bit resolution, continous conversion and comparator mode.
+     * Then tweak to be more precise when appropriate.
+     */
+    set_mask = ADT7410_FULL | ADT7410_RESOLUTION | ADT7410_EVENT_MODE;
+    clr_mask = 0;
+
+    /* configure as specified */
+    ret = adt7410_i2c_read_byte(client, ADT7410_CONFIG, &data->config);
+    if (ret) {
+        dev_dbg(&client->dev, "Can't read config? %d\n", ret);
+        goto exit_free;
+    }
+    new = (data->config & ~clr_mask) | set_mask;
+    if (data->config != new) {
+        adt7410_i2c_write_byte(client, ADT7410_CONFIG, new);
+        data->config = new;
+    }
+    dev_dbg(&client->dev, "Config %02x\n", new);
+
+    /* Register sysfs hooks */
+    ret = sysfs_create_group(&client->dev.kobj, &adt7410_group);
+    if (ret)
+        goto exit_free;
+
+    data->hwmon_dev = hwmon_device_register(&client->dev);
+    if (IS_ERR(data->hwmon_dev)) {
+        ret = PTR_ERR(data->hwmon_dev);
+        goto exit_remove;
+    }
+
+    dev_info(&client->dev, "%s: sensor '%s'\n",
+         dev_name(data->hwmon_dev), client->name);
+
+    return 0;
+
+exit_remove:
+    sysfs_remove_group(&client->dev.kobj, &adt7410_group);
+exit_free:
+    kfree(data);
+    return ret;
+}
+
+static int adt7410_remove(struct i2c_client *client)
+{
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    hwmon_device_unregister(data->hwmon_dev);
+    sysfs_remove_group(&client->dev.kobj, &adt7410_group);
+    adt7410_i2c_write_byte(client, ADT7410_CONFIG, data->config);
+    kfree(data);
+    return 0;
+}
+
+static const struct i2c_device_id adt7410_ids[] = {
+    { "adt7410", adt7410, },
+    { /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, adt7410_ids);
+
+/* Return 0 if detection is successful, -ENODEV otherwise
+ * very basic detection */
+static int adt7410_detect(struct i2c_client *new_client,
+               struct i2c_board_info *info)
+{
+    struct i2c_adapter *adapter = new_client->adapter;
+    int ret = 0;
+    u8 mid;
+    if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
+                     I2C_FUNC_SMBUS_WORD_DATA))
+        return -ENODEV;
+
+    ret = adt7410_i2c_read_byte(new_client, ADT7410_ID, &mid);
+    if (ret)
+        return -EIO;
+
+    if ((mid >> ADT7410_MANUFACTORE_ID_OFFSET) != ADT7410_MANUFACTURE_ID)
+        return -ENODEV;
+
+    strlcpy(info->type, "adt7410", I2C_NAME_SIZE);
+
+    return 0;
+}
+
+#ifdef CONFIG_PM
+static int adt7410_suspend(struct device *dev)
+{
+    int ret = 0;
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    ret = adt7410_i2c_write_byte(client, ADT7410_CONFIG,
+                     (data->config | ADT7410_PD));
+    if (ret)
+        return -EIO;
+    return 0;
+}
+
+static int adt7410_resume(struct device *dev)
+{
+    int ret = 0;
+    struct i2c_client *client = to_i2c_client(dev);
+    struct adt7410_data *data = i2c_get_clientdata(client);
+    ret = adt7410_i2c_write_byte(client, ADT7410_CONFIG, data->config);
+    if (ret)
+        return -EIO;
+    return 0;
+}
+
+static const struct dev_pm_ops adt7410_dev_pm_ops = {
+    .suspend    = adt7410_suspend,
+    .resume        = adt7410_resume,
+};
+#define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops)
+#else
+#define ADT7410_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static struct i2c_driver adt7410_driver = {
+    .class        = I2C_CLASS_HWMON,
+    .driver = {
+        .name    = "adt7410",
+        .pm    = ADT7410_DEV_PM_OPS,
+    },
+    .probe        = adt7410_probe,
+    .remove        = adt7410_remove,
+    .id_table    = adt7410_ids,
+    .detect        = adt7410_detect,
+    .address_list    = normal_i2c,
+};
+
+module_i2c_driver(adt7410_driver);
+
+MODULE_AUTHOR("Hartmut Knaack <knaack.h <at> gmx.de>");
+MODULE_DESCRIPTION("ADT7410 driver");
+MODULE_LICENSE("GPL");


_______________________________________________
lm-sensors mailing list
lm-sensors@xxxxxxxxxxxxxx
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux