xref: /linux/drivers/hwmon/lm95241.c (revision 0f1deb4b820cfacf22492abd7b17e891dafc51ae)
106160327SDavide Rizzo /*
2*0f1deb4bSDavide Rizzo  * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com>
306160327SDavide Rizzo  *
4*0f1deb4bSDavide Rizzo  * The LM95241 is a sensor chip made by National Semiconductors.
5*0f1deb4bSDavide Rizzo  * It reports up to three temperatures (its own plus up to two external ones).
6*0f1deb4bSDavide Rizzo  * Complete datasheet can be obtained from National's website at:
706160327SDavide Rizzo  *   http://www.national.com/ds.cgi/LM/LM95241.pdf
806160327SDavide Rizzo  *
906160327SDavide Rizzo  * This program is free software; you can redistribute it and/or modify
1006160327SDavide Rizzo  * it under the terms of the GNU General Public License as published by
1106160327SDavide Rizzo  * the Free Software Foundation; either version 2 of the License, or
1206160327SDavide Rizzo  * (at your option) any later version.
1306160327SDavide Rizzo  *
1406160327SDavide Rizzo  * This program is distributed in the hope that it will be useful,
1506160327SDavide Rizzo  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1606160327SDavide Rizzo  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1706160327SDavide Rizzo  * GNU General Public License for more details.
1806160327SDavide Rizzo  *
1906160327SDavide Rizzo  * You should have received a copy of the GNU General Public License
2006160327SDavide Rizzo  * along with this program; if not, write to the Free Software
2106160327SDavide Rizzo  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2206160327SDavide Rizzo  */
2306160327SDavide Rizzo 
2406160327SDavide Rizzo #include <linux/module.h>
2506160327SDavide Rizzo #include <linux/init.h>
2606160327SDavide Rizzo #include <linux/slab.h>
2706160327SDavide Rizzo #include <linux/jiffies.h>
2806160327SDavide Rizzo #include <linux/i2c.h>
2906160327SDavide Rizzo #include <linux/hwmon.h>
3006160327SDavide Rizzo #include <linux/hwmon-sysfs.h>
3106160327SDavide Rizzo #include <linux/err.h>
3206160327SDavide Rizzo #include <linux/mutex.h>
3306160327SDavide Rizzo #include <linux/sysfs.h>
3406160327SDavide Rizzo 
35*0f1deb4bSDavide Rizzo #define DEVNAME "lm95241"
36*0f1deb4bSDavide Rizzo 
3706160327SDavide Rizzo static const unsigned short normal_i2c[] = {
3806160327SDavide Rizzo 	0x19, 0x2a, 0x2b, I2C_CLIENT_END };
3906160327SDavide Rizzo 
4006160327SDavide Rizzo /* LM95241 registers */
4106160327SDavide Rizzo #define LM95241_REG_R_MAN_ID		0xFE
4206160327SDavide Rizzo #define LM95241_REG_R_CHIP_ID		0xFF
4306160327SDavide Rizzo #define LM95241_REG_R_STATUS		0x02
4406160327SDavide Rizzo #define LM95241_REG_RW_CONFIG		0x03
4506160327SDavide Rizzo #define LM95241_REG_RW_REM_FILTER	0x06
4606160327SDavide Rizzo #define LM95241_REG_RW_TRUTHERM		0x07
4706160327SDavide Rizzo #define LM95241_REG_W_ONE_SHOT		0x0F
4806160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPH	0x10
4906160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPH	0x11
5006160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPH	0x12
5106160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPL	0x20
5206160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPL	0x21
5306160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPL	0x22
5406160327SDavide Rizzo #define LM95241_REG_RW_REMOTE_MODEL	0x30
5506160327SDavide Rizzo 
5606160327SDavide Rizzo /* LM95241 specific bitfields */
5706160327SDavide Rizzo #define CFG_STOP 0x40
5806160327SDavide Rizzo #define CFG_CR0076 0x00
5906160327SDavide Rizzo #define CFG_CR0182 0x10
6006160327SDavide Rizzo #define CFG_CR1000 0x20
6106160327SDavide Rizzo #define CFG_CR2700 0x30
6206160327SDavide Rizzo #define R1MS_SHIFT 0
6306160327SDavide Rizzo #define R2MS_SHIFT 2
6406160327SDavide Rizzo #define R1MS_MASK (0x01 << (R1MS_SHIFT))
6506160327SDavide Rizzo #define R2MS_MASK (0x01 << (R2MS_SHIFT))
6606160327SDavide Rizzo #define R1DF_SHIFT 1
6706160327SDavide Rizzo #define R2DF_SHIFT 2
6806160327SDavide Rizzo #define R1DF_MASK (0x01 << (R1DF_SHIFT))
6906160327SDavide Rizzo #define R2DF_MASK (0x01 << (R2DF_SHIFT))
7006160327SDavide Rizzo #define R1FE_MASK 0x01
7106160327SDavide Rizzo #define R2FE_MASK 0x05
7206160327SDavide Rizzo #define TT1_SHIFT 0
7306160327SDavide Rizzo #define TT2_SHIFT 4
7406160327SDavide Rizzo #define TT_OFF 0
7506160327SDavide Rizzo #define TT_ON 1
7606160327SDavide Rizzo #define TT_MASK 7
7706160327SDavide Rizzo #define MANUFACTURER_ID 0x01
7806160327SDavide Rizzo #define DEFAULT_REVISION 0xA4
7906160327SDavide Rizzo 
80*0f1deb4bSDavide Rizzo static const u8 lm95241_reg_address[] = {
81*0f1deb4bSDavide Rizzo 	LM95241_REG_R_LOCAL_TEMPH,
82*0f1deb4bSDavide Rizzo 	LM95241_REG_R_LOCAL_TEMPL,
83*0f1deb4bSDavide Rizzo 	LM95241_REG_R_REMOTE1_TEMPH,
84*0f1deb4bSDavide Rizzo 	LM95241_REG_R_REMOTE1_TEMPL,
85*0f1deb4bSDavide Rizzo 	LM95241_REG_R_REMOTE2_TEMPH,
86*0f1deb4bSDavide Rizzo 	LM95241_REG_R_REMOTE2_TEMPL
87*0f1deb4bSDavide Rizzo };
8806160327SDavide Rizzo 
8906160327SDavide Rizzo /* Client data (each client gets its own) */
9006160327SDavide Rizzo struct lm95241_data {
9106160327SDavide Rizzo 	struct device *hwmon_dev;
9206160327SDavide Rizzo 	struct mutex update_lock;
93bc482bf0SGuenter Roeck 	unsigned long last_updated, interval;	/* in jiffies */
9406160327SDavide Rizzo 	char valid;		/* zero until following fields are valid */
9506160327SDavide Rizzo 	/* registers values */
96*0f1deb4bSDavide Rizzo 	u8 temp[ARRAY_SIZE(lm95241_reg_address)];
9706160327SDavide Rizzo 	u8 config, model, trutherm;
9806160327SDavide Rizzo };
9906160327SDavide Rizzo 
100*0f1deb4bSDavide Rizzo /* Conversions */
101*0f1deb4bSDavide Rizzo static int TempFromReg(u8 val_h, u8 val_l)
102*0f1deb4bSDavide Rizzo {
103*0f1deb4bSDavide Rizzo 	if (val_h & 0x80)
104*0f1deb4bSDavide Rizzo 		return val_h - 0x100;
105*0f1deb4bSDavide Rizzo 	return val_h * 1000 + val_l * 1000 / 256;
10606160327SDavide Rizzo }
107*0f1deb4bSDavide Rizzo 
108*0f1deb4bSDavide Rizzo static struct lm95241_data *lm95241_update_device(struct device *dev)
109*0f1deb4bSDavide Rizzo {
110*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
111*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
112*0f1deb4bSDavide Rizzo 
113*0f1deb4bSDavide Rizzo 	mutex_lock(&data->update_lock);
114*0f1deb4bSDavide Rizzo 
115*0f1deb4bSDavide Rizzo 	if (time_after(jiffies, data->last_updated + data->interval) ||
116*0f1deb4bSDavide Rizzo 	    !data->valid) {
117*0f1deb4bSDavide Rizzo 		int i;
118*0f1deb4bSDavide Rizzo 
119*0f1deb4bSDavide Rizzo 		dev_dbg(&client->dev, "Updating lm95241 data.\n");
120*0f1deb4bSDavide Rizzo 		for (i = 0; i < ARRAY_SIZE(lm95241_reg_address); i++)
121*0f1deb4bSDavide Rizzo 			data->temp[i]
122*0f1deb4bSDavide Rizzo 			  = i2c_smbus_read_byte_data(client,
123*0f1deb4bSDavide Rizzo 						     lm95241_reg_address[i]);
124*0f1deb4bSDavide Rizzo 		data->last_updated = jiffies;
125*0f1deb4bSDavide Rizzo 		data->valid = 1;
126*0f1deb4bSDavide Rizzo 	}
127*0f1deb4bSDavide Rizzo 
128*0f1deb4bSDavide Rizzo 	mutex_unlock(&data->update_lock);
129*0f1deb4bSDavide Rizzo 
130*0f1deb4bSDavide Rizzo 	return data;
131*0f1deb4bSDavide Rizzo }
132*0f1deb4bSDavide Rizzo 
133*0f1deb4bSDavide Rizzo /* Sysfs stuff */
134*0f1deb4bSDavide Rizzo static ssize_t show_input(struct device *dev, struct device_attribute *attr,
135*0f1deb4bSDavide Rizzo 			  char *buf)
136*0f1deb4bSDavide Rizzo {
137*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = lm95241_update_device(dev);
138*0f1deb4bSDavide Rizzo 
139*0f1deb4bSDavide Rizzo 	return snprintf(buf, PAGE_SIZE - 1, "%d\n",
140*0f1deb4bSDavide Rizzo 		TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
141*0f1deb4bSDavide Rizzo 			    data->temp[to_sensor_dev_attr(attr)->index + 1]));
142*0f1deb4bSDavide Rizzo }
143*0f1deb4bSDavide Rizzo 
144*0f1deb4bSDavide Rizzo static ssize_t show_type(struct device *dev, struct device_attribute *attr,
145*0f1deb4bSDavide Rizzo 			 char *buf)
146*0f1deb4bSDavide Rizzo {
147*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
148*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
149*0f1deb4bSDavide Rizzo 
150*0f1deb4bSDavide Rizzo 	return snprintf(buf, PAGE_SIZE - 1,
151*0f1deb4bSDavide Rizzo 		data->model & to_sensor_dev_attr(attr)->index ? "1\n" : "2\n");
152*0f1deb4bSDavide Rizzo }
153*0f1deb4bSDavide Rizzo 
154*0f1deb4bSDavide Rizzo static ssize_t set_type(struct device *dev, struct device_attribute *attr,
155*0f1deb4bSDavide Rizzo 			const char *buf, size_t count)
156*0f1deb4bSDavide Rizzo {
157*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
158*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
159*0f1deb4bSDavide Rizzo 	unsigned long val;
160*0f1deb4bSDavide Rizzo 	int shift;
161*0f1deb4bSDavide Rizzo 	u8 mask = to_sensor_dev_attr(attr)->index;
162*0f1deb4bSDavide Rizzo 
163*0f1deb4bSDavide Rizzo 	if (strict_strtoul(buf, 10, &val) < 0)
164*0f1deb4bSDavide Rizzo 		return -EINVAL;
165*0f1deb4bSDavide Rizzo 	if (val != 1 && val != 2)
166*0f1deb4bSDavide Rizzo 		return -EINVAL;
167*0f1deb4bSDavide Rizzo 
168*0f1deb4bSDavide Rizzo 	shift = mask == R1MS_MASK ? TT1_SHIFT : TT2_SHIFT;
169*0f1deb4bSDavide Rizzo 
170*0f1deb4bSDavide Rizzo 	mutex_lock(&data->update_lock);
171*0f1deb4bSDavide Rizzo 
172*0f1deb4bSDavide Rizzo 	data->trutherm &= ~(TT_MASK << shift);
173*0f1deb4bSDavide Rizzo 	if (val == 1) {
174*0f1deb4bSDavide Rizzo 		data->model |= mask;
175*0f1deb4bSDavide Rizzo 		data->trutherm |= (TT_ON << shift);
176*0f1deb4bSDavide Rizzo 	} else {
177*0f1deb4bSDavide Rizzo 		data->model &= ~mask;
178*0f1deb4bSDavide Rizzo 		data->trutherm |= (TT_OFF << shift);
179*0f1deb4bSDavide Rizzo 	}
180*0f1deb4bSDavide Rizzo 	data->valid = 0;
181*0f1deb4bSDavide Rizzo 
182*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
183*0f1deb4bSDavide Rizzo 				  data->model);
184*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
185*0f1deb4bSDavide Rizzo 				  data->trutherm);
186*0f1deb4bSDavide Rizzo 
187*0f1deb4bSDavide Rizzo 	mutex_unlock(&data->update_lock);
188*0f1deb4bSDavide Rizzo 
189*0f1deb4bSDavide Rizzo 	return count;
190*0f1deb4bSDavide Rizzo }
191*0f1deb4bSDavide Rizzo 
192*0f1deb4bSDavide Rizzo static ssize_t show_min(struct device *dev, struct device_attribute *attr,
193*0f1deb4bSDavide Rizzo 			char *buf)
194*0f1deb4bSDavide Rizzo {
195*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
196*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
197*0f1deb4bSDavide Rizzo 
198*0f1deb4bSDavide Rizzo 	return snprintf(buf, PAGE_SIZE - 1,
199*0f1deb4bSDavide Rizzo 			data->config & to_sensor_dev_attr(attr)->index ?
200*0f1deb4bSDavide Rizzo 			"-127000\n" : "0\n");
201*0f1deb4bSDavide Rizzo }
202*0f1deb4bSDavide Rizzo 
203*0f1deb4bSDavide Rizzo static ssize_t set_min(struct device *dev, struct device_attribute *attr,
204*0f1deb4bSDavide Rizzo 		       const char *buf, size_t count)
205*0f1deb4bSDavide Rizzo {
206*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
207*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
208*0f1deb4bSDavide Rizzo 	long val;
209*0f1deb4bSDavide Rizzo 
210*0f1deb4bSDavide Rizzo 	if (strict_strtol(buf, 10, &val) < 0)
211*0f1deb4bSDavide Rizzo 		return -EINVAL;
212*0f1deb4bSDavide Rizzo 	if (val < -128000)
213*0f1deb4bSDavide Rizzo 		return -EINVAL;
214*0f1deb4bSDavide Rizzo 
215*0f1deb4bSDavide Rizzo 	mutex_lock(&data->update_lock);
216*0f1deb4bSDavide Rizzo 
217*0f1deb4bSDavide Rizzo 	if (val < 0)
218*0f1deb4bSDavide Rizzo 		data->config |= to_sensor_dev_attr(attr)->index;
219*0f1deb4bSDavide Rizzo 	else
220*0f1deb4bSDavide Rizzo 		data->config &= ~to_sensor_dev_attr(attr)->index;
221*0f1deb4bSDavide Rizzo 	data->valid = 0;
222*0f1deb4bSDavide Rizzo 
223*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
224*0f1deb4bSDavide Rizzo 
225*0f1deb4bSDavide Rizzo 	mutex_unlock(&data->update_lock);
226*0f1deb4bSDavide Rizzo 
227*0f1deb4bSDavide Rizzo 	return count;
228*0f1deb4bSDavide Rizzo }
229*0f1deb4bSDavide Rizzo 
230*0f1deb4bSDavide Rizzo static ssize_t show_max(struct device *dev, struct device_attribute *attr,
231*0f1deb4bSDavide Rizzo 			char *buf)
232*0f1deb4bSDavide Rizzo {
233*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
234*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
235*0f1deb4bSDavide Rizzo 
236*0f1deb4bSDavide Rizzo 	return snprintf(buf, PAGE_SIZE - 1,
237*0f1deb4bSDavide Rizzo 			data->config & to_sensor_dev_attr(attr)->index ?
238*0f1deb4bSDavide Rizzo 			"127000\n" : "255000\n");
239*0f1deb4bSDavide Rizzo }
240*0f1deb4bSDavide Rizzo 
241*0f1deb4bSDavide Rizzo static ssize_t set_max(struct device *dev, struct device_attribute *attr,
242*0f1deb4bSDavide Rizzo 		       const char *buf, size_t count)
243*0f1deb4bSDavide Rizzo {
244*0f1deb4bSDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
245*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
246*0f1deb4bSDavide Rizzo 	long val;
247*0f1deb4bSDavide Rizzo 
248*0f1deb4bSDavide Rizzo 	if (strict_strtol(buf, 10, &val) < 0)
249*0f1deb4bSDavide Rizzo 		return -EINVAL;
250*0f1deb4bSDavide Rizzo 	if (val >= 256000)
251*0f1deb4bSDavide Rizzo 		return -EINVAL;
252*0f1deb4bSDavide Rizzo 
253*0f1deb4bSDavide Rizzo 	mutex_lock(&data->update_lock);
254*0f1deb4bSDavide Rizzo 
255*0f1deb4bSDavide Rizzo 	if (val <= 127000)
256*0f1deb4bSDavide Rizzo 		data->config |= to_sensor_dev_attr(attr)->index;
257*0f1deb4bSDavide Rizzo 	else
258*0f1deb4bSDavide Rizzo 		data->config &= ~to_sensor_dev_attr(attr)->index;
259*0f1deb4bSDavide Rizzo 	data->valid = 0;
260*0f1deb4bSDavide Rizzo 
261*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
262*0f1deb4bSDavide Rizzo 
263*0f1deb4bSDavide Rizzo 	mutex_unlock(&data->update_lock);
264*0f1deb4bSDavide Rizzo 
265*0f1deb4bSDavide Rizzo 	return count;
266*0f1deb4bSDavide Rizzo }
26706160327SDavide Rizzo 
268bc482bf0SGuenter Roeck static ssize_t show_interval(struct device *dev, struct device_attribute *attr,
26906160327SDavide Rizzo 			     char *buf)
27006160327SDavide Rizzo {
27106160327SDavide Rizzo 	struct lm95241_data *data = lm95241_update_device(dev);
27206160327SDavide Rizzo 
273*0f1deb4bSDavide Rizzo 	return snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval
274*0f1deb4bSDavide Rizzo 			/ HZ);
27506160327SDavide Rizzo }
27606160327SDavide Rizzo 
277bc482bf0SGuenter Roeck static ssize_t set_interval(struct device *dev, struct device_attribute *attr,
27806160327SDavide Rizzo 			    const char *buf, size_t count)
27906160327SDavide Rizzo {
28006160327SDavide Rizzo 	struct i2c_client *client = to_i2c_client(dev);
28106160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
28261ec2da5SJean Delvare 	unsigned long val;
28306160327SDavide Rizzo 
28461ec2da5SJean Delvare 	if (strict_strtoul(buf, 10, &val) < 0)
28561ec2da5SJean Delvare 		return -EINVAL;
28661ec2da5SJean Delvare 
28761ec2da5SJean Delvare 	data->interval = val * HZ / 1000;
28806160327SDavide Rizzo 
28906160327SDavide Rizzo 	return count;
29006160327SDavide Rizzo }
29106160327SDavide Rizzo 
292*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0);
293*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2);
294*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 4);
295*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type,
296*0f1deb4bSDavide Rizzo 			  R1MS_MASK);
297*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type,
298*0f1deb4bSDavide Rizzo 			  R2MS_MASK);
299*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min,
300*0f1deb4bSDavide Rizzo 			  R1DF_MASK);
301*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min,
302*0f1deb4bSDavide Rizzo 			  R2DF_MASK);
303*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max,
304*0f1deb4bSDavide Rizzo 			  R1DF_MASK);
305*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max,
306*0f1deb4bSDavide Rizzo 			  R2DF_MASK);
307bc482bf0SGuenter Roeck static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval,
308bc482bf0SGuenter Roeck 		   set_interval);
30906160327SDavide Rizzo 
31006160327SDavide Rizzo static struct attribute *lm95241_attributes[] = {
311*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp1_input.dev_attr.attr,
312*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp2_input.dev_attr.attr,
313*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp3_input.dev_attr.attr,
314*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp2_type.dev_attr.attr,
315*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp3_type.dev_attr.attr,
316*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp2_min.dev_attr.attr,
317*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp3_min.dev_attr.attr,
318*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp2_max.dev_attr.attr,
319*0f1deb4bSDavide Rizzo 	&sensor_dev_attr_temp3_max.dev_attr.attr,
320bc482bf0SGuenter Roeck 	&dev_attr_update_interval.attr,
32106160327SDavide Rizzo 	NULL
32206160327SDavide Rizzo };
32306160327SDavide Rizzo 
32406160327SDavide Rizzo static const struct attribute_group lm95241_group = {
32506160327SDavide Rizzo 	.attrs = lm95241_attributes,
32606160327SDavide Rizzo };
32706160327SDavide Rizzo 
328797eaa4bSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */
329310ec792SJean Delvare static int lm95241_detect(struct i2c_client *new_client,
330797eaa4bSJean Delvare 			  struct i2c_board_info *info)
33106160327SDavide Rizzo {
332797eaa4bSJean Delvare 	struct i2c_adapter *adapter = new_client->adapter;
333797eaa4bSJean Delvare 	int address = new_client->addr;
33452df6440SJean Delvare 	const char *name;
33506160327SDavide Rizzo 
33606160327SDavide Rizzo 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
337797eaa4bSJean Delvare 		return -ENODEV;
33806160327SDavide Rizzo 
33906160327SDavide Rizzo 	if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
34006160327SDavide Rizzo 	     == MANUFACTURER_ID)
34106160327SDavide Rizzo 	    && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
34206160327SDavide Rizzo 		>= DEFAULT_REVISION)) {
343*0f1deb4bSDavide Rizzo 		name = DEVNAME;
34452df6440SJean Delvare 	} else {
34552df6440SJean Delvare 		dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
34652df6440SJean Delvare 			address);
347797eaa4bSJean Delvare 		return -ENODEV;
34806160327SDavide Rizzo 	}
34906160327SDavide Rizzo 
350797eaa4bSJean Delvare 	/* Fill the i2c board info */
351797eaa4bSJean Delvare 	strlcpy(info->type, name, I2C_NAME_SIZE);
352797eaa4bSJean Delvare 	return 0;
353797eaa4bSJean Delvare }
35406160327SDavide Rizzo 
355*0f1deb4bSDavide Rizzo static void lm95241_init_client(struct i2c_client *client)
356*0f1deb4bSDavide Rizzo {
357*0f1deb4bSDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
358*0f1deb4bSDavide Rizzo 
359*0f1deb4bSDavide Rizzo 	data->interval = HZ;	/* 1 sec default */
360*0f1deb4bSDavide Rizzo 	data->valid = 0;
361*0f1deb4bSDavide Rizzo 	data->config = CFG_CR0076;
362*0f1deb4bSDavide Rizzo 	data->model = 0;
363*0f1deb4bSDavide Rizzo 	data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
364*0f1deb4bSDavide Rizzo 
365*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config);
366*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
367*0f1deb4bSDavide Rizzo 				  R1FE_MASK | R2FE_MASK);
368*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
369*0f1deb4bSDavide Rizzo 				  data->trutherm);
370*0f1deb4bSDavide Rizzo 	i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
371*0f1deb4bSDavide Rizzo 				  data->model);
372*0f1deb4bSDavide Rizzo }
373*0f1deb4bSDavide Rizzo 
374797eaa4bSJean Delvare static int lm95241_probe(struct i2c_client *new_client,
375797eaa4bSJean Delvare 			 const struct i2c_device_id *id)
376797eaa4bSJean Delvare {
377797eaa4bSJean Delvare 	struct lm95241_data *data;
378797eaa4bSJean Delvare 	int err;
379797eaa4bSJean Delvare 
380797eaa4bSJean Delvare 	data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
381797eaa4bSJean Delvare 	if (!data) {
382797eaa4bSJean Delvare 		err = -ENOMEM;
383797eaa4bSJean Delvare 		goto exit;
384797eaa4bSJean Delvare 	}
385797eaa4bSJean Delvare 
386797eaa4bSJean Delvare 	i2c_set_clientdata(new_client, data);
38706160327SDavide Rizzo 	mutex_init(&data->update_lock);
38806160327SDavide Rizzo 
38906160327SDavide Rizzo 	/* Initialize the LM95241 chip */
39006160327SDavide Rizzo 	lm95241_init_client(new_client);
39106160327SDavide Rizzo 
39206160327SDavide Rizzo 	/* Register sysfs hooks */
39306160327SDavide Rizzo 	err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
39406160327SDavide Rizzo 	if (err)
395797eaa4bSJean Delvare 		goto exit_free;
39606160327SDavide Rizzo 
39706160327SDavide Rizzo 	data->hwmon_dev = hwmon_device_register(&new_client->dev);
39806160327SDavide Rizzo 	if (IS_ERR(data->hwmon_dev)) {
39906160327SDavide Rizzo 		err = PTR_ERR(data->hwmon_dev);
40006160327SDavide Rizzo 		goto exit_remove_files;
40106160327SDavide Rizzo 	}
40206160327SDavide Rizzo 
40306160327SDavide Rizzo 	return 0;
40406160327SDavide Rizzo 
40506160327SDavide Rizzo exit_remove_files:
40606160327SDavide Rizzo 	sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
40706160327SDavide Rizzo exit_free:
40806160327SDavide Rizzo 	kfree(data);
40906160327SDavide Rizzo exit:
41006160327SDavide Rizzo 	return err;
41106160327SDavide Rizzo }
41206160327SDavide Rizzo 
413797eaa4bSJean Delvare static int lm95241_remove(struct i2c_client *client)
41406160327SDavide Rizzo {
41506160327SDavide Rizzo 	struct lm95241_data *data = i2c_get_clientdata(client);
41606160327SDavide Rizzo 
41706160327SDavide Rizzo 	hwmon_device_unregister(data->hwmon_dev);
41806160327SDavide Rizzo 	sysfs_remove_group(&client->dev.kobj, &lm95241_group);
41906160327SDavide Rizzo 
42006160327SDavide Rizzo 	kfree(data);
42106160327SDavide Rizzo 	return 0;
42206160327SDavide Rizzo }
42306160327SDavide Rizzo 
424797eaa4bSJean Delvare /* Driver data (common to all clients) */
425797eaa4bSJean Delvare static const struct i2c_device_id lm95241_id[] = {
426*0f1deb4bSDavide Rizzo 	{ DEVNAME, 0 },
427797eaa4bSJean Delvare 	{ }
428797eaa4bSJean Delvare };
429797eaa4bSJean Delvare MODULE_DEVICE_TABLE(i2c, lm95241_id);
430797eaa4bSJean Delvare 
431797eaa4bSJean Delvare static struct i2c_driver lm95241_driver = {
432797eaa4bSJean Delvare 	.class		= I2C_CLASS_HWMON,
433797eaa4bSJean Delvare 	.driver = {
434*0f1deb4bSDavide Rizzo 		.name	= DEVNAME,
435797eaa4bSJean Delvare 	},
436797eaa4bSJean Delvare 	.probe		= lm95241_probe,
437797eaa4bSJean Delvare 	.remove		= lm95241_remove,
438797eaa4bSJean Delvare 	.id_table	= lm95241_id,
439797eaa4bSJean Delvare 	.detect		= lm95241_detect,
440c3813d6aSJean Delvare 	.address_list	= normal_i2c,
441797eaa4bSJean Delvare };
442797eaa4bSJean Delvare 
44306160327SDavide Rizzo static int __init sensors_lm95241_init(void)
44406160327SDavide Rizzo {
44506160327SDavide Rizzo 	return i2c_add_driver(&lm95241_driver);
44606160327SDavide Rizzo }
44706160327SDavide Rizzo 
44806160327SDavide Rizzo static void __exit sensors_lm95241_exit(void)
44906160327SDavide Rizzo {
45006160327SDavide Rizzo 	i2c_del_driver(&lm95241_driver);
45106160327SDavide Rizzo }
45206160327SDavide Rizzo 
453*0f1deb4bSDavide Rizzo MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>");
45406160327SDavide Rizzo MODULE_DESCRIPTION("LM95241 sensor driver");
45506160327SDavide Rizzo MODULE_LICENSE("GPL");
45606160327SDavide Rizzo 
45706160327SDavide Rizzo module_init(sensors_lm95241_init);
45806160327SDavide Rizzo module_exit(sensors_lm95241_exit);
459