11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * lm92 - Hardware monitoring driver
37c81c60f3789a082e141d7a013392af5f78db16aJean Delvare * Copyright (C) 2005-2008  Jean Delvare <jdelvare@suse.de>
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Based on the lm90 driver, with some ideas taken from the lm_sensors
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * lm92 driver as well.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The LM92 is a sensor chip made by National Semiconductor. It reports
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * its own temperature with a 0.0625 deg resolution and a 0.33 deg
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * accuracy. Complete datasheet can be obtained from National's website
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * at:
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *   http://www.national.com/pf/LM/LM92.html
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This driver also supports the MAX6635 sensor chip made by Maxim.
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This chip is compatible with the LM92, but has a lesser accuracy
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (1.0 deg). Complete datasheet can be obtained from Maxim's website
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * at:
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *   http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3074
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Since the LM92 was the first chipset supported by this driver, most
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * comments will refer to this chipset, but are actually general and
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * concern all supported chipsets, unless mentioned otherwise.
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Support could easily be added for the National Semiconductor LM76
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and Maxim MAX6633 and MAX6634 chips, which are mostly compatible
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with the LM92.
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version.
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful,
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details.
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h>
43943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h>
446cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare#include <linux/hwmon-sysfs.h>
45943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h>
469a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h>
47dcd8f39230b9f724ba4f55f14ed2bb8119204385Jean Delvare#include <linux/jiffies.h>
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
49a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck/*
50a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * The LM92 and MAX6635 have 2 two-state pins for address selection,
51a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * resulting in 4 possible addresses.
52a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck */
5325e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
5425e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffman						I2C_CLIENT_END };
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The LM92 registers */
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_CONFIG			0x01 /* 8-bit, RW */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_TEMP			0x00 /* 16-bit, RO */
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_TEMP_HYST		0x02 /* 16-bit, RW */
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_TEMP_CRIT		0x03 /* 16-bit, RW */
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_TEMP_LOW		0x04 /* 16-bit, RW */
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_TEMP_HIGH		0x05 /* 16-bit, RW */
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM92_REG_MAN_ID			0x07 /* 16-bit, RO, LM92 only */
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
65a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck/*
66a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * The LM92 uses signed 13-bit values with LSB = 0.0625 degree Celsius,
67a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * left-justified in 16-bit registers. No rounding is done, with such
68a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * a resolution it's just not worth it. Note that the MAX6635 doesn't
69a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * make use of the 4 lower bits for limits (i.e. effective resolution
70a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * for limits is 1 degree Celsius).
71a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck */
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int TEMP_FROM_REG(s16 reg)
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return reg / 8 * 625 / 10;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
775b963089161b8fb244889c972edf553b9d737545Axel Linstatic inline s16 TEMP_TO_REG(long val)
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
795b963089161b8fb244889c972edf553b9d737545Axel Lin	val = clamp_val(val, -60000, 160000);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return val * 10 / 625 * 8;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Alarm flags are stored in the 3 LSB of the temperature register */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 ALARMS_FROM_REG(s16 reg)
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return reg & 0x0007;
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
89b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckenum temp_index {
90b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_input,
91b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_crit,
92b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_min,
93b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_max,
94b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_hyst,
95b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	t_num_regs
96b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck};
97b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
98b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic const u8 regs[t_num_regs] = {
99b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	[t_input] = LM92_REG_TEMP,
100b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	[t_crit] = LM92_REG_TEMP_CRIT,
101b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	[t_min] = LM92_REG_TEMP_LOW,
102b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	[t_max] = LM92_REG_TEMP_HIGH,
103b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	[t_hyst] = LM92_REG_TEMP_HYST,
104b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck};
105b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Client data (each client gets its own) */
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm92_data {
108030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct i2c_client *client;
1099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	struct mutex update_lock;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char valid; /* zero until following fields are valid */
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long last_updated; /* in jiffies */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* registers values */
114b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	s16 temp[t_num_regs];	/* index with enum temp_index */
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sysfs attributes and callback functions
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct lm92_data *lm92_update_device(struct device *dev)
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
123030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct lm92_data *data = dev_get_drvdata(dev);
124030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct i2c_client *client = data->client;
125b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	int i;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1279a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (time_after(jiffies, data->last_updated + HZ)
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 || !data->valid) {
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev_dbg(&client->dev, "Updating lm92 data\n");
132b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck		for (i = 0; i < t_num_regs; i++) {
133b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			data->temp[i] =
134b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck				i2c_smbus_read_word_swapped(client, regs[i]);
135b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck		}
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->last_updated = jiffies;
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data->valid = 1;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1409a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return data;
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
145b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
146b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			 char *buf)
147b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck{
148b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
149b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	struct lm92_data *data = lm92_update_device(dev);
150b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
151b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
154b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
155b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			   const char *buf, size_t count)
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
157b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
158030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct lm92_data *data = dev_get_drvdata(dev);
159030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct i2c_client *client = data->client;
160b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	int nr = attr->index;
161b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	long val;
162b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	int err;
163b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
164b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	err = kstrtol(buf, 10, &val);
165b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	if (err)
166b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck		return err;
167b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
168b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	mutex_lock(&data->update_lock);
169b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	data->temp[nr] = TEMP_TO_REG(val);
170b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	i2c_smbus_write_word_swapped(client, regs[nr], data->temp[nr]);
171b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	mutex_unlock(&data->update_lock);
172b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return count;
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
174b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
175b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic ssize_t show_temp_hyst(struct device *dev,
176b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			      struct device_attribute *devattr, char *buf)
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
178b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm92_data *data = lm92_update_device(dev);
180b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index])
181b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck		       - TEMP_FROM_REG(data->temp[t_hyst]));
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
183b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck
184b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic ssize_t show_temp_min_hyst(struct device *dev,
185b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck				  struct device_attribute *attr, char *buf)
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm92_data *data = lm92_update_device(dev);
188b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[t_min])
189b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck		       + TEMP_FROM_REG(data->temp[t_hyst]));
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
192b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic ssize_t set_temp_hyst(struct device *dev,
193b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			     struct device_attribute *devattr,
194b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			     const char *buf, size_t count)
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
196b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
197030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct lm92_data *data = dev_get_drvdata(dev);
198030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct i2c_client *client = data->client;
199a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	long val;
200a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	int err;
201a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck
202a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	err = kstrtol(buf, 10, &val);
203a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	if (err)
204a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck		return err;
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2065b963089161b8fb244889c972edf553b9d737545Axel Lin	val = clamp_val(val, -120000, 220000);
2079a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_lock(&data->update_lock);
2085b963089161b8fb244889c972edf553b9d737545Axel Lin	 data->temp[t_hyst] =
2095b963089161b8fb244889c972edf553b9d737545Axel Lin		TEMP_TO_REG(TEMP_FROM_REG(data->temp[attr->index]) - val);
21090f4102ce59226954edbe960b2434d8b3da5f086Jean Delvare	i2c_smbus_write_word_swapped(client, LM92_REG_TEMP_HYST,
2115b963089161b8fb244889c972edf553b9d737545Axel Lin				     data->temp[t_hyst]);
2129a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_unlock(&data->update_lock);
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return count;
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
216a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeckstatic ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
217a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck			   char *buf)
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct lm92_data *data = lm92_update_device(dev);
220b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->temp[t_input]));
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2236cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvarestatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
2246cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare			  char *buf)
2256cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare{
2266cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare	int bitnr = to_sensor_dev_attr(attr)->index;
2276cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare	struct lm92_data *data = lm92_update_device(dev);
228b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	return sprintf(buf, "%d\n", (data->temp[t_input] >> bitnr) & 1);
2296cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare}
2306cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare
231b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, t_input);
232b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp, set_temp,
233b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			  t_crit);
234b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temp_hyst,
235b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			  set_temp_hyst, t_crit);
236b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp, set_temp,
237b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			  t_min);
238b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic DEVICE_ATTR(temp1_min_hyst, S_IRUGO, show_temp_min_hyst, NULL);
239b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp, set_temp,
240b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck			  t_max);
241b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO, show_temp_hyst, NULL, t_max);
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
2436cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 2);
2446cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
2456cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvarestatic SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 1);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Detection and registration
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void lm92_init_client(struct i2c_client *client)
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 config;
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Start the conversions if needed */
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	config = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (config & 0x01)
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i2c_smbus_write_byte_data(client, LM92_REG_CONFIG,
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					  config & 0xFE);
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
262a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck/*
263a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * The MAX6635 has no identification register, so we have to use tricks
264a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * to identify it reliably. This is somewhat slow.
265a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * Note that we do NOT rely on the 2 MSB of the configuration register
266a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * always reading 0, as suggested by the datasheet, because it was once
267a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck * reported not to be true.
268a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck */
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int max6635_check(struct i2c_client *client)
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u16 temp_low, temp_high, temp_hyst, temp_crit;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u8 conf;
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
275a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	/*
276a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * No manufacturer ID register, so a read from this address will
277a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * always return the last read value.
278a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 */
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_low = i2c_smbus_read_word_data(client, LM92_REG_TEMP_LOW);
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_low)
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_high = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HIGH);
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (i2c_smbus_read_word_data(client, LM92_REG_MAN_ID) != temp_high)
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
285a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Limits are stored as integer values (signed, 9-bit). */
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((temp_low & 0x7f00) || (temp_high & 0x7f00))
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_hyst = i2c_smbus_read_word_data(client, LM92_REG_TEMP_HYST);
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_crit = i2c_smbus_read_word_data(client, LM92_REG_TEMP_CRIT);
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((temp_hyst & 0x7f00) || (temp_crit & 0x7f00))
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
294a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	/*
295a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * Registers addresses were found to cycle over 16-byte boundaries.
296a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * We don't test all registers with all offsets so as to save some
297a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * reads and time, but this should still be sufficient to dismiss
298a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 * non-MAX6635 chips.
299a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	 */
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	conf = i2c_smbus_read_byte_data(client, LM92_REG_CONFIG);
301a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck	for (i = 16; i < 96; i *= 2) {
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (temp_hyst != i2c_smbus_read_word_data(client,
303a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck				 LM92_REG_TEMP_HYST + i - 16)
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 || temp_crit != i2c_smbus_read_word_data(client,
305a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck				 LM92_REG_TEMP_CRIT + i)
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 || temp_low != i2c_smbus_read_word_data(client,
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				LM92_REG_TEMP_LOW + i + 16)
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 || temp_high != i2c_smbus_read_word_data(client,
309a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck				 LM92_REG_TEMP_HIGH + i + 32)
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 || conf != i2c_smbus_read_byte_data(client,
311a318afd890ea4cf1e35543ad100704173edb4406Guenter Roeck			    LM92_REG_CONFIG + i))
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return 0;
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
318030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeckstatic struct attribute *lm92_attrs[] = {
319b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_input.dev_attr.attr,
320b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_crit.dev_attr.attr,
321b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
322b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_min.dev_attr.attr,
3230501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	&dev_attr_temp1_min_hyst.attr,
324b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_max.dev_attr.attr,
325b8fe58e9532d8cbaa8efcedf95a9c18f726e75ceGuenter Roeck	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
3260501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	&dev_attr_alarms.attr,
3276cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare	&sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
3286cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare	&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
3296cb59e915d04f71c62a0ee8fab34de274aa3fe2aJean Delvare	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
3300501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman	NULL
3310501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman};
332030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter RoeckATTRIBUTE_GROUPS(lm92);
3330501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman
334910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare/* Return 0 if detection is successful, -ENODEV otherwise */
335310ec79210d754afe51e2e4a983e846b60179abdJean Delvarestatic int lm92_detect(struct i2c_client *new_client,
336910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare		       struct i2c_board_info *info)
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
338910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	struct i2c_adapter *adapter = new_client->adapter;
33952df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	u8 config;
34052df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	u16 man_id;
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					    | I2C_FUNC_SMBUS_WORD_DATA))
344910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare		return -ENODEV;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
34652df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	config = i2c_smbus_read_byte_data(new_client, LM92_REG_CONFIG);
34752df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	man_id = i2c_smbus_read_word_data(new_client, LM92_REG_MAN_ID);
34852df6440a29123eed912183fe785bbe174ef14b9Jean Delvare
34952df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	if ((config & 0xe0) == 0x00 && man_id == 0x0180)
35052df6440a29123eed912183fe785bbe174ef14b9Jean Delvare		pr_info("lm92: Found National Semiconductor LM92 chip\n");
35152df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	else if (max6635_check(new_client))
35252df6440a29123eed912183fe785bbe174ef14b9Jean Delvare		pr_info("lm92: Found Maxim MAX6635 chip\n");
35352df6440a29123eed912183fe785bbe174ef14b9Jean Delvare	else
35452df6440a29123eed912183fe785bbe174ef14b9Jean Delvare		return -ENODEV;
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
356910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	strlcpy(info->type, "lm92", I2C_NAME_SIZE);
357910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare
358910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	return 0;
359910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare}
360910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare
361910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvarestatic int lm92_probe(struct i2c_client *new_client,
362910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare		      const struct i2c_device_id *id)
363910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare{
364030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	struct device *hwmon_dev;
365910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	struct lm92_data *data;
366910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare
367705375cc41f2bd63dfffcf4830afff76c63e5681Guenter Roeck	data = devm_kzalloc(&new_client->dev, sizeof(struct lm92_data),
368705375cc41f2bd63dfffcf4830afff76c63e5681Guenter Roeck			    GFP_KERNEL);
369705375cc41f2bd63dfffcf4830afff76c63e5681Guenter Roeck	if (!data)
370705375cc41f2bd63dfffcf4830afff76c63e5681Guenter Roeck		return -ENOMEM;
371910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare
372030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	data->client = new_client;
3739a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar	mutex_init(&data->update_lock);
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Initialize the chipset */
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	lm92_init_client(new_client);
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
378030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	hwmon_dev = devm_hwmon_device_register_with_groups(&new_client->dev,
379030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck							   new_client->name,
380030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck							   data, lm92_groups);
381030004b1edf1d3b7e7a0957b4cb11b28372b8d70Guenter Roeck	return PTR_ERR_OR_ZERO(hwmon_dev);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module and driver stuff
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
389910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvarestatic const struct i2c_device_id lm92_id[] = {
3901f86df49ddfd0067cce941187d57b2fd2f749a9eJean Delvare	{ "lm92", 0 },
391910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	/* max6635 could be added here */
392910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	{ }
393910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare};
394910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean DelvareMODULE_DEVICE_TABLE(i2c, lm92_id);
395910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct i2c_driver lm92_driver = {
397910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	.class		= I2C_CLASS_HWMON,
398cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard	.driver = {
399cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard		.name	= "lm92",
400cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard	},
401910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	.probe		= lm92_probe,
402910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	.id_table	= lm92_id,
403910e8dcf16dd7afc08dc1791155cc69e07ca4183Jean Delvare	.detect		= lm92_detect,
404c3813d6af177fab19e322f3114b1f64fbcf08d71Jean Delvare	.address_list	= normal_i2c,
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
407f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm92_driver);
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4097c81c60f3789a082e141d7a013392af5f78db16aJean DelvareMODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("LM92/MAX6635 driver");
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
412