xref: /linux/drivers/hwmon/lm95241.c (revision 797eaa4b0242a41cb6bc913890b9ec22ec8788ed)
106160327SDavide Rizzo /*
206160327SDavide Rizzo  * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
306160327SDavide Rizzo  *             monitoring
406160327SDavide Rizzo  * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
506160327SDavide Rizzo  *
606160327SDavide Rizzo  * Based on the max1619 driver. The LM95241 is a sensor chip made by National
706160327SDavide Rizzo  *   Semiconductors.
806160327SDavide Rizzo  * It reports up to three temperatures (its own plus up to
906160327SDavide Rizzo  * two external ones). Complete datasheet can be
1006160327SDavide Rizzo  * obtained from National's website at:
1106160327SDavide Rizzo  *   http://www.national.com/ds.cgi/LM/LM95241.pdf
1206160327SDavide Rizzo  *
1306160327SDavide Rizzo  * This program is free software; you can redistribute it and/or modify
1406160327SDavide Rizzo  * it under the terms of the GNU General Public License as published by
1506160327SDavide Rizzo  * the Free Software Foundation; either version 2 of the License, or
1606160327SDavide Rizzo  * (at your option) any later version.
1706160327SDavide Rizzo  *
1806160327SDavide Rizzo  * This program is distributed in the hope that it will be useful,
1906160327SDavide Rizzo  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2006160327SDavide Rizzo  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2106160327SDavide Rizzo  * GNU General Public License for more details.
2206160327SDavide Rizzo  *
2306160327SDavide Rizzo  * You should have received a copy of the GNU General Public License
2406160327SDavide Rizzo  * along with this program; if not, write to the Free Software
2506160327SDavide Rizzo  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2606160327SDavide Rizzo  */
2706160327SDavide Rizzo 
2806160327SDavide Rizzo #include <linux/module.h>
2906160327SDavide Rizzo #include <linux/init.h>
3006160327SDavide Rizzo #include <linux/slab.h>
3106160327SDavide Rizzo #include <linux/jiffies.h>
3206160327SDavide Rizzo #include <linux/i2c.h>
3306160327SDavide Rizzo #include <linux/hwmon.h>
3406160327SDavide Rizzo #include <linux/hwmon-sysfs.h>
3506160327SDavide Rizzo #include <linux/err.h>
3606160327SDavide Rizzo #include <linux/mutex.h>
3706160327SDavide Rizzo #include <linux/sysfs.h>
3806160327SDavide Rizzo 
3906160327SDavide Rizzo static const unsigned short normal_i2c[] = {
4006160327SDavide Rizzo 	0x19, 0x2a, 0x2b, I2C_CLIENT_END};
4106160327SDavide Rizzo 
4206160327SDavide Rizzo /* Insmod parameters */
4306160327SDavide Rizzo I2C_CLIENT_INSMOD_1(lm95241);
4406160327SDavide Rizzo 
4506160327SDavide Rizzo /* LM95241 registers */
4606160327SDavide Rizzo #define LM95241_REG_R_MAN_ID		0xFE
4706160327SDavide Rizzo #define LM95241_REG_R_CHIP_ID		0xFF
4806160327SDavide Rizzo #define LM95241_REG_R_STATUS		0x02
4906160327SDavide Rizzo #define LM95241_REG_RW_CONFIG		0x03
5006160327SDavide Rizzo #define LM95241_REG_RW_REM_FILTER	0x06
5106160327SDavide Rizzo #define LM95241_REG_RW_TRUTHERM		0x07
5206160327SDavide Rizzo #define LM95241_REG_W_ONE_SHOT  	0x0F
5306160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPH	0x10
5406160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPH	0x11
5506160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPH	0x12
5606160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPL	0x20
5706160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPL	0x21
5806160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPL	0x22
5906160327SDavide Rizzo #define LM95241_REG_RW_REMOTE_MODEL	0x30
6006160327SDavide Rizzo 
6106160327SDavide Rizzo /* LM95241 specific bitfields */
6206160327SDavide Rizzo #define CFG_STOP 0x40
6306160327SDavide Rizzo #define CFG_CR0076 0x00
6406160327SDavide Rizzo #define CFG_CR0182 0x10
6506160327SDavide Rizzo #define CFG_CR1000 0x20
6606160327SDavide Rizzo #define CFG_CR2700 0x30
6706160327SDavide Rizzo #define R1MS_SHIFT 0
6806160327SDavide Rizzo #define R2MS_SHIFT 2
6906160327SDavide Rizzo #define R1MS_MASK (0x01 << (R1MS_SHIFT))
7006160327SDavide Rizzo #define R2MS_MASK (0x01 << (R2MS_SHIFT))
7106160327SDavide Rizzo #define R1DF_SHIFT 1
7206160327SDavide Rizzo #define R2DF_SHIFT 2
7306160327SDavide Rizzo #define R1DF_MASK (0x01 << (R1DF_SHIFT))
7406160327SDavide Rizzo #define R2DF_MASK (0x01 << (R2DF_SHIFT))
7506160327SDavide Rizzo #define R1FE_MASK 0x01
7606160327SDavide Rizzo #define R2FE_MASK 0x05
7706160327SDavide Rizzo #define TT1_SHIFT 0
7806160327SDavide Rizzo #define TT2_SHIFT 4
7906160327SDavide Rizzo #define TT_OFF 0
8006160327SDavide Rizzo #define TT_ON 1
8106160327SDavide Rizzo #define TT_MASK 7
8206160327SDavide Rizzo #define MANUFACTURER_ID 0x01
8306160327SDavide Rizzo #define DEFAULT_REVISION 0xA4
8406160327SDavide Rizzo 
8506160327SDavide Rizzo /* Conversions and various macros */
8606160327SDavide Rizzo #define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
8706160327SDavide Rizzo     (val_h)) * 1000 + (val_l) * 1000 / 256)
8806160327SDavide Rizzo 
8906160327SDavide Rizzo /* Functions declaration */
9006160327SDavide Rizzo static void lm95241_init_client(struct i2c_client *client);
9106160327SDavide Rizzo static struct lm95241_data *lm95241_update_device(struct device *dev);
9206160327SDavide Rizzo 
9306160327SDavide Rizzo /* Client data (each client gets its own) */
9406160327SDavide Rizzo struct lm95241_data {
9506160327SDavide Rizzo 	struct device *hwmon_dev;
9606160327SDavide Rizzo 	struct mutex update_lock;
9706160327SDavide Rizzo 	unsigned long last_updated, rate; /* in jiffies */
9806160327SDavide Rizzo 	char valid; /* zero until following fields are valid */
9906160327SDavide Rizzo 	/* registers values */
10006160327SDavide Rizzo 	u8 local_h, local_l; /* local */
10106160327SDavide Rizzo 	u8 remote1_h, remote1_l; /* remote1 */
10206160327SDavide Rizzo 	u8 remote2_h, remote2_l; /* remote2 */
10306160327SDavide Rizzo 	u8 config, model, trutherm;
10406160327SDavide Rizzo };
10506160327SDavide Rizzo 
10606160327SDavide Rizzo /* Sysfs stuff */
10706160327SDavide Rizzo #define show_temp(value) \
10806160327SDavide Rizzo static ssize_t show_##value(struct device *dev, \
10906160327SDavide Rizzo     struct device_attribute *attr, char *buf) \
11006160327SDavide Rizzo { \
11106160327SDavide Rizzo 	struct lm95241_data *data = lm95241_update_device(dev); \
11206160327SDavide Rizzo 	snprintf(buf, PAGE_SIZE - 1, "%d\n", \
11306160327SDavide Rizzo 		TEMP_FROM_REG(data->value##_h, data->value##_l)); \
11406160327SDavide Rizzo 	return strlen(buf); \
11506160327SDavide Rizzo }
11606160327SDavide Rizzo show_temp(local);
11706160327SDavide Rizzo show_temp(remote1);
11806160327SDavide Rizzo show_temp(remote2);
11906160327SDavide Rizzo 
12006160327SDavide Rizzo static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
12106160327SDavide Rizzo 			 char *buf)
12206160327SDavide Rizzo {
12306160327SDavide Rizzo 	struct lm95241_data *data = lm95241_update_device(dev);
12406160327SDavide Rizzo 
12506160327SDavide Rizzo 	snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
12606160327SDavide Rizzo 	return strlen(buf);
12706160327SDavide Rizzo }
12806160327SDavide Rizzo 
12906160327SDavide Rizzo static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
13006160327SDavide Rizzo 			const char *buf, size_t count)
13106160327SDavide Rizzo {
13206160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
13306160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
13406160327SDavide Rizzo 
13506160327SDavide Rizzo 	strict_strtol(buf, 10, &data->rate);
13606160327SDavide Rizzo 	data->rate = data->rate * HZ / 1000;
13706160327SDavide Rizzo 
13806160327SDavide Rizzo 	return count;
13906160327SDavide Rizzo }
14006160327SDavide Rizzo 
14106160327SDavide Rizzo #define show_type(flag) \
14206160327SDavide Rizzo static ssize_t show_type##flag(struct device *dev, \
14306160327SDavide Rizzo 				   struct device_attribute *attr, char *buf) \
14406160327SDavide Rizzo { \
14506160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
14606160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
14706160327SDavide Rizzo \
14806160327SDavide Rizzo 	snprintf(buf, PAGE_SIZE - 1, \
14906160327SDavide Rizzo 		data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
15006160327SDavide Rizzo 	return strlen(buf); \
15106160327SDavide Rizzo }
15206160327SDavide Rizzo show_type(1);
15306160327SDavide Rizzo show_type(2);
15406160327SDavide Rizzo 
15506160327SDavide Rizzo #define show_min(flag) \
15606160327SDavide Rizzo static ssize_t show_min##flag(struct device *dev, \
15706160327SDavide Rizzo     struct device_attribute *attr, char *buf) \
15806160327SDavide Rizzo { \
15906160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
16006160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
16106160327SDavide Rizzo \
16206160327SDavide Rizzo 	snprintf(buf, PAGE_SIZE - 1, \
16306160327SDavide Rizzo 		data->config & R##flag##DF_MASK ?	\
16406160327SDavide Rizzo 		"-127000\n" : "0\n"); \
16506160327SDavide Rizzo 	return strlen(buf); \
16606160327SDavide Rizzo }
16706160327SDavide Rizzo show_min(1);
16806160327SDavide Rizzo show_min(2);
16906160327SDavide Rizzo 
17006160327SDavide Rizzo #define show_max(flag) \
17106160327SDavide Rizzo static ssize_t show_max##flag(struct device *dev, \
17206160327SDavide Rizzo     struct device_attribute *attr, char *buf) \
17306160327SDavide Rizzo { \
17406160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
17506160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
17606160327SDavide Rizzo \
17706160327SDavide Rizzo 	snprintf(buf, PAGE_SIZE - 1, \
17806160327SDavide Rizzo 		data->config & R##flag##DF_MASK ? \
17906160327SDavide Rizzo 		"127000\n" : "255000\n"); \
18006160327SDavide Rizzo 	return strlen(buf); \
18106160327SDavide Rizzo }
18206160327SDavide Rizzo show_max(1);
18306160327SDavide Rizzo show_max(2);
18406160327SDavide Rizzo 
18506160327SDavide Rizzo #define set_type(flag) \
18606160327SDavide Rizzo static ssize_t set_type##flag(struct device *dev, \
18706160327SDavide Rizzo 				  struct device_attribute *attr, \
18806160327SDavide Rizzo 				  const char *buf, size_t count) \
18906160327SDavide Rizzo { \
19006160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
19106160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
19206160327SDavide Rizzo \
19306160327SDavide Rizzo 	long val; \
19406160327SDavide Rizzo 	strict_strtol(buf, 10, &val); \
19506160327SDavide Rizzo \
19606160327SDavide Rizzo 	if ((val == 1) || (val == 2)) { \
19706160327SDavide Rizzo \
19806160327SDavide Rizzo 		mutex_lock(&data->update_lock); \
19906160327SDavide Rizzo \
20006160327SDavide Rizzo 		data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
20106160327SDavide Rizzo 		if (val == 1) { \
20206160327SDavide Rizzo 			data->model |= R##flag##MS_MASK; \
20306160327SDavide Rizzo 			data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
20406160327SDavide Rizzo 		} \
20506160327SDavide Rizzo 		else { \
20606160327SDavide Rizzo 			data->model &= ~R##flag##MS_MASK; \
20706160327SDavide Rizzo 			data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
20806160327SDavide Rizzo 		} \
20906160327SDavide Rizzo \
21006160327SDavide Rizzo 		data->valid = 0; \
21106160327SDavide Rizzo \
21206160327SDavide Rizzo 		i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
21306160327SDavide Rizzo 					  data->model); \
21406160327SDavide Rizzo 		i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
21506160327SDavide Rizzo 					  data->trutherm); \
21606160327SDavide Rizzo \
21706160327SDavide Rizzo 		mutex_unlock(&data->update_lock); \
21806160327SDavide Rizzo \
21906160327SDavide Rizzo 	} \
22006160327SDavide Rizzo 	return count; \
22106160327SDavide Rizzo }
22206160327SDavide Rizzo set_type(1);
22306160327SDavide Rizzo set_type(2);
22406160327SDavide Rizzo 
22506160327SDavide Rizzo #define set_min(flag) \
22606160327SDavide Rizzo static ssize_t set_min##flag(struct device *dev, \
22706160327SDavide Rizzo 	struct device_attribute *devattr, const char *buf, size_t count) \
22806160327SDavide Rizzo { \
22906160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
23006160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
23106160327SDavide Rizzo \
23206160327SDavide Rizzo 	long val; \
23306160327SDavide Rizzo 	strict_strtol(buf, 10, &val); \
23406160327SDavide Rizzo \
23506160327SDavide Rizzo 	mutex_lock(&data->update_lock); \
23606160327SDavide Rizzo \
23706160327SDavide Rizzo 	if (val < 0) \
23806160327SDavide Rizzo 		data->config |= R##flag##DF_MASK; \
23906160327SDavide Rizzo 	else \
24006160327SDavide Rizzo 		data->config &= ~R##flag##DF_MASK; \
24106160327SDavide Rizzo \
24206160327SDavide Rizzo 	data->valid = 0; \
24306160327SDavide Rizzo \
24406160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
24506160327SDavide Rizzo 		data->config); \
24606160327SDavide Rizzo \
24706160327SDavide Rizzo 	mutex_unlock(&data->update_lock); \
24806160327SDavide Rizzo \
24906160327SDavide Rizzo 	return count; \
25006160327SDavide Rizzo }
25106160327SDavide Rizzo set_min(1);
25206160327SDavide Rizzo set_min(2);
25306160327SDavide Rizzo 
25406160327SDavide Rizzo #define set_max(flag) \
25506160327SDavide Rizzo static ssize_t set_max##flag(struct device *dev, \
25606160327SDavide Rizzo 	struct device_attribute *devattr, const char *buf, size_t count) \
25706160327SDavide Rizzo { \
25806160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev); \
25906160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client); \
26006160327SDavide Rizzo \
26106160327SDavide Rizzo 	long val; \
26206160327SDavide Rizzo 	strict_strtol(buf, 10, &val); \
26306160327SDavide Rizzo \
26406160327SDavide Rizzo 	mutex_lock(&data->update_lock); \
26506160327SDavide Rizzo \
26606160327SDavide Rizzo 	if (val <= 127000) \
26706160327SDavide Rizzo 		data->config |= R##flag##DF_MASK; \
26806160327SDavide Rizzo 	else \
26906160327SDavide Rizzo 		data->config &= ~R##flag##DF_MASK; \
27006160327SDavide Rizzo \
27106160327SDavide Rizzo 	data->valid = 0; \
27206160327SDavide Rizzo \
27306160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
27406160327SDavide Rizzo 		data->config); \
27506160327SDavide Rizzo \
27606160327SDavide Rizzo 	mutex_unlock(&data->update_lock); \
27706160327SDavide Rizzo \
27806160327SDavide Rizzo 	return count; \
27906160327SDavide Rizzo }
28006160327SDavide Rizzo set_max(1);
28106160327SDavide Rizzo set_max(2);
28206160327SDavide Rizzo 
28306160327SDavide Rizzo static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
28406160327SDavide Rizzo static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
28506160327SDavide Rizzo static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
28606160327SDavide Rizzo static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
28706160327SDavide Rizzo static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
28806160327SDavide Rizzo static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
28906160327SDavide Rizzo static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
29006160327SDavide Rizzo static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
29106160327SDavide Rizzo static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
29206160327SDavide Rizzo static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
29306160327SDavide Rizzo 
29406160327SDavide Rizzo static struct attribute *lm95241_attributes[] = {
29506160327SDavide Rizzo 	&dev_attr_temp1_input.attr,
29606160327SDavide Rizzo 	&dev_attr_temp2_input.attr,
29706160327SDavide Rizzo 	&dev_attr_temp3_input.attr,
29806160327SDavide Rizzo 	&dev_attr_temp2_type.attr,
29906160327SDavide Rizzo 	&dev_attr_temp3_type.attr,
30006160327SDavide Rizzo 	&dev_attr_temp2_min.attr,
30106160327SDavide Rizzo 	&dev_attr_temp3_min.attr,
30206160327SDavide Rizzo 	&dev_attr_temp2_max.attr,
30306160327SDavide Rizzo 	&dev_attr_temp3_max.attr,
30406160327SDavide Rizzo 	&dev_attr_rate.attr,
30506160327SDavide Rizzo 	NULL
30606160327SDavide Rizzo };
30706160327SDavide Rizzo 
30806160327SDavide Rizzo static const struct attribute_group lm95241_group = {
30906160327SDavide Rizzo 	.attrs = lm95241_attributes,
31006160327SDavide Rizzo };
31106160327SDavide Rizzo 
312*797eaa4bSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
313*797eaa4bSJean Delvare static int lm95241_detect(struct i2c_client *new_client, int kind,
314*797eaa4bSJean Delvare 			  struct i2c_board_info *info)
31506160327SDavide Rizzo {
316*797eaa4bSJean Delvare 	struct i2c_adapter *adapter = new_client->adapter;
317*797eaa4bSJean Delvare 	int address = new_client->addr;
31806160327SDavide Rizzo 	const char *name = "";
31906160327SDavide Rizzo 
32006160327SDavide Rizzo 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
321*797eaa4bSJean Delvare 		return -ENODEV;
32206160327SDavide Rizzo 
32306160327SDavide Rizzo 	/*
32406160327SDavide Rizzo 	 * Now we do the remaining detection. A negative kind means that
32506160327SDavide Rizzo 	 * the driver was loaded with no force parameter (default), so we
32606160327SDavide Rizzo 	 * must both detect and identify the chip. A zero kind means that
32706160327SDavide Rizzo 	 * the driver was loaded with the force parameter, the detection
32806160327SDavide Rizzo 	 * step shall be skipped. A positive kind means that the driver
32906160327SDavide Rizzo 	 * was loaded with the force parameter and a given kind of chip is
33006160327SDavide Rizzo 	 * requested, so both the detection and the identification steps
33106160327SDavide Rizzo 	 * are skipped.
33206160327SDavide Rizzo 	 */
33306160327SDavide Rizzo 	if (kind < 0) {	/* detection */
33406160327SDavide Rizzo 		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
33506160327SDavide Rizzo 		     != MANUFACTURER_ID)
33606160327SDavide Rizzo 		|| (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
33706160327SDavide Rizzo 		    < DEFAULT_REVISION)) {
33806160327SDavide Rizzo 			dev_dbg(&adapter->dev,
33906160327SDavide Rizzo 				"LM95241 detection failed at 0x%02x.\n",
34006160327SDavide Rizzo 				address);
341*797eaa4bSJean Delvare 			return -ENODEV;
34206160327SDavide Rizzo 		}
34306160327SDavide Rizzo 	}
34406160327SDavide Rizzo 
34506160327SDavide Rizzo 	if (kind <= 0) { /* identification */
34606160327SDavide Rizzo 		if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
34706160327SDavide Rizzo 		     == MANUFACTURER_ID)
34806160327SDavide Rizzo 		&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
34906160327SDavide Rizzo 		    >= DEFAULT_REVISION)) {
35006160327SDavide Rizzo 
35106160327SDavide Rizzo 			kind = lm95241;
35206160327SDavide Rizzo 
35306160327SDavide Rizzo 			if (kind <= 0) { /* identification failed */
35406160327SDavide Rizzo 				dev_info(&adapter->dev, "Unsupported chip\n");
355*797eaa4bSJean Delvare 				return -ENODEV;
35606160327SDavide Rizzo 			}
35706160327SDavide Rizzo 		}
35806160327SDavide Rizzo 	}
35906160327SDavide Rizzo 
360*797eaa4bSJean Delvare 	/* Fill the i2c board info */
36106160327SDavide Rizzo 	if (kind == lm95241)
36206160327SDavide Rizzo 		name = "lm95241";
363*797eaa4bSJean Delvare 	strlcpy(info->type, name, I2C_NAME_SIZE);
364*797eaa4bSJean Delvare 	return 0;
365*797eaa4bSJean Delvare }
36606160327SDavide Rizzo 
367*797eaa4bSJean Delvare static int lm95241_probe(struct i2c_client *new_client,
368*797eaa4bSJean Delvare 			 const struct i2c_device_id *id)
369*797eaa4bSJean Delvare {
370*797eaa4bSJean Delvare 	struct lm95241_data *data;
371*797eaa4bSJean Delvare 	int err;
372*797eaa4bSJean Delvare 
373*797eaa4bSJean Delvare 	data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
374*797eaa4bSJean Delvare 	if (!data) {
375*797eaa4bSJean Delvare 		err = -ENOMEM;
376*797eaa4bSJean Delvare 		goto exit;
377*797eaa4bSJean Delvare 	}
378*797eaa4bSJean Delvare 
379*797eaa4bSJean Delvare 	i2c_set_clientdata(new_client, data);
38006160327SDavide Rizzo 	mutex_init(&data->update_lock);
38106160327SDavide Rizzo 
38206160327SDavide Rizzo 	/* Initialize the LM95241 chip */
38306160327SDavide Rizzo 	lm95241_init_client(new_client);
38406160327SDavide Rizzo 
38506160327SDavide Rizzo 	/* Register sysfs hooks */
38606160327SDavide Rizzo 	err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
38706160327SDavide Rizzo 	if (err)
388*797eaa4bSJean Delvare 		goto exit_free;
38906160327SDavide Rizzo 
39006160327SDavide Rizzo 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
39106160327SDavide Rizzo 	if (IS_ERR(data->hwmon_dev)) {
39206160327SDavide Rizzo 		err = PTR_ERR(data->hwmon_dev);
39306160327SDavide Rizzo 		goto exit_remove_files;
39406160327SDavide Rizzo 	}
39506160327SDavide Rizzo 
39606160327SDavide Rizzo 	return 0;
39706160327SDavide Rizzo 
39806160327SDavide Rizzo exit_remove_files:
39906160327SDavide Rizzo 	sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
40006160327SDavide Rizzo exit_free:
40106160327SDavide Rizzo 	kfree(data);
40206160327SDavide Rizzo exit:
40306160327SDavide Rizzo 	return err;
40406160327SDavide Rizzo }
40506160327SDavide Rizzo 
40606160327SDavide Rizzo static void lm95241_init_client(struct i2c_client *client)
40706160327SDavide Rizzo {
40806160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
40906160327SDavide Rizzo 
41006160327SDavide Rizzo 	data->rate = HZ;    /* 1 sec default */
41106160327SDavide Rizzo 	data->valid = 0;
41206160327SDavide Rizzo 	data->config = CFG_CR0076;
41306160327SDavide Rizzo 	data->model = 0;
41406160327SDavide Rizzo 	data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
41506160327SDavide Rizzo 
41606160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
41706160327SDavide Rizzo 				  data->config);
41806160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
41906160327SDavide Rizzo 				  R1FE_MASK | R2FE_MASK);
42006160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
42106160327SDavide Rizzo 				  data->trutherm);
42206160327SDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
42306160327SDavide Rizzo 				  data->model);
42406160327SDavide Rizzo }
42506160327SDavide Rizzo 
426*797eaa4bSJean Delvare static int lm95241_remove(struct i2c_client *client)
42706160327SDavide Rizzo {
42806160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
42906160327SDavide Rizzo 
43006160327SDavide Rizzo 	hwmon_device_unregister(data->hwmon_dev);
43106160327SDavide Rizzo 	sysfs_remove_group(&client->dev.kobj, &lm95241_group);
43206160327SDavide Rizzo 
433*797eaa4bSJean Delvare 	i2c_set_clientdata(client, NULL);
43406160327SDavide Rizzo 	kfree(data);
43506160327SDavide Rizzo 	return 0;
43606160327SDavide Rizzo }
43706160327SDavide Rizzo 
43806160327SDavide Rizzo static struct lm95241_data *lm95241_update_device(struct device *dev)
43906160327SDavide Rizzo {
44006160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
44106160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
44206160327SDavide Rizzo 
44306160327SDavide Rizzo 	mutex_lock(&data->update_lock);
44406160327SDavide Rizzo 
44506160327SDavide Rizzo 	if (time_after(jiffies, data->last_updated + data->rate) ||
44606160327SDavide Rizzo 	    !data->valid) {
44706160327SDavide Rizzo 		dev_dbg(&client->dev, "Updating lm95241 data.\n");
44806160327SDavide Rizzo 		data->local_h =
44906160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
45006160327SDavide Rizzo 						 LM95241_REG_R_LOCAL_TEMPH);
45106160327SDavide Rizzo 		data->local_l =
45206160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
45306160327SDavide Rizzo 						 LM95241_REG_R_LOCAL_TEMPL);
45406160327SDavide Rizzo 		data->remote1_h =
45506160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
45606160327SDavide Rizzo 						 LM95241_REG_R_REMOTE1_TEMPH);
45706160327SDavide Rizzo 		data->remote1_l =
45806160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
45906160327SDavide Rizzo 						 LM95241_REG_R_REMOTE1_TEMPL);
46006160327SDavide Rizzo 		data->remote2_h =
46106160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
46206160327SDavide Rizzo 						 LM95241_REG_R_REMOTE2_TEMPH);
46306160327SDavide Rizzo 		data->remote2_l =
46406160327SDavide Rizzo 			i2c_smbus_read_byte_data(client,
46506160327SDavide Rizzo 						 LM95241_REG_R_REMOTE2_TEMPL);
46606160327SDavide Rizzo 		data->last_updated = jiffies;
46706160327SDavide Rizzo 		data->valid = 1;
46806160327SDavide Rizzo 	}
46906160327SDavide Rizzo 
47006160327SDavide Rizzo 	mutex_unlock(&data->update_lock);
47106160327SDavide Rizzo 
47206160327SDavide Rizzo 	return data;
47306160327SDavide Rizzo }
47406160327SDavide Rizzo 
475*797eaa4bSJean Delvare /* Driver data (common to all clients) */
476*797eaa4bSJean Delvare static const struct i2c_device_id lm95241_id[] = {
477*797eaa4bSJean Delvare 	{ "lm95241", lm95241 },
478*797eaa4bSJean Delvare 	{ }
479*797eaa4bSJean Delvare };
480*797eaa4bSJean Delvare MODULE_DEVICE_TABLE(i2c, lm95241_id);
481*797eaa4bSJean Delvare 
482*797eaa4bSJean Delvare static struct i2c_driver lm95241_driver = {
483*797eaa4bSJean Delvare 	.class		= I2C_CLASS_HWMON,
484*797eaa4bSJean Delvare 	.driver = {
485*797eaa4bSJean Delvare 		.name   = "lm95241",
486*797eaa4bSJean Delvare 	},
487*797eaa4bSJean Delvare 	.probe		= lm95241_probe,
488*797eaa4bSJean Delvare 	.remove		= lm95241_remove,
489*797eaa4bSJean Delvare 	.id_table	= lm95241_id,
490*797eaa4bSJean Delvare 	.detect		= lm95241_detect,
491*797eaa4bSJean Delvare 	.address_data	= &addr_data,
492*797eaa4bSJean Delvare };
493*797eaa4bSJean Delvare 
49406160327SDavide Rizzo static int __init sensors_lm95241_init(void)
49506160327SDavide Rizzo {
49606160327SDavide Rizzo 	return i2c_add_driver(&lm95241_driver);
49706160327SDavide Rizzo }
49806160327SDavide Rizzo 
49906160327SDavide Rizzo static void __exit sensors_lm95241_exit(void)
50006160327SDavide Rizzo {
50106160327SDavide Rizzo 	i2c_del_driver(&lm95241_driver);
50206160327SDavide Rizzo }
50306160327SDavide Rizzo 
50406160327SDavide Rizzo MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
50506160327SDavide Rizzo MODULE_DESCRIPTION("LM95241 sensor driver");
50606160327SDavide Rizzo MODULE_LICENSE("GPL");
50706160327SDavide Rizzo 
50806160327SDavide Rizzo module_init(sensors_lm95241_init);
50906160327SDavide Rizzo module_exit(sensors_lm95241_exit);
510