lm63.c 19.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3
/*
 * lm63.c - driver for the National Semiconductor LM63 temperature sensor
 *          with integrated fan control
4
 * Copyright (C) 2004-2008  Jean Delvare <khali@linux-fr.org>
L
Linus Torvalds 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
 * Based on the lm90 driver.
 *
 * The LM63 is a sensor chip made by National Semiconductor. It measures
 * two temperatures (its own and one external one) and the speed of one
 * fan, those speed it can additionally control. Complete datasheet can be
 * obtained from National's website at:
 *   http://www.national.com/pf/LM/LM63.html
 *
 * The LM63 is basically an LM86 with fan speed monitoring and control
 * capabilities added. It misses some of the LM86 features though:
 *  - No low limit for local temperature.
 *  - No critical limit for local temperature.
 *  - Critical limit for remote temperature can be changed only once. We
 *    will consider that the critical limit is read-only.
 *
 * The datasheet isn't very clear about what the tachometer reading is.
 * I had a explanation from National Semiconductor though. The two lower
 * bits of the read value have to be masked out. The value is still 16 bit
 * in width.
 *
 * 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>
45
#include <linux/hwmon-sysfs.h>
46 47
#include <linux/hwmon.h>
#include <linux/err.h>
48
#include <linux/mutex.h>
49
#include <linux/sysfs.h>
L
Linus Torvalds 已提交
50 51 52 53 54 55

/*
 * Addresses to scan
 * Address is fully defined internally and cannot be changed.
 */

56
static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
L
Linus Torvalds 已提交
57 58 59 60 61

/*
 * Insmod parameters
 */

62
I2C_CLIENT_INSMOD_1(lm63);
L
Linus Torvalds 已提交
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

/*
 * The LM63 registers
 */

#define LM63_REG_CONFIG1		0x03
#define LM63_REG_CONFIG2		0xBF
#define LM63_REG_CONFIG_FAN		0x4A

#define LM63_REG_TACH_COUNT_MSB		0x47
#define LM63_REG_TACH_COUNT_LSB		0x46
#define LM63_REG_TACH_LIMIT_MSB		0x49
#define LM63_REG_TACH_LIMIT_LSB		0x48

#define LM63_REG_PWM_VALUE		0x4C
#define LM63_REG_PWM_FREQ		0x4D

#define LM63_REG_LOCAL_TEMP		0x00
#define LM63_REG_LOCAL_HIGH		0x05

#define LM63_REG_REMOTE_TEMP_MSB	0x01
#define LM63_REG_REMOTE_TEMP_LSB	0x10
#define LM63_REG_REMOTE_OFFSET_MSB	0x11
#define LM63_REG_REMOTE_OFFSET_LSB	0x12
#define LM63_REG_REMOTE_HIGH_MSB	0x07
#define LM63_REG_REMOTE_HIGH_LSB	0x13
#define LM63_REG_REMOTE_LOW_MSB		0x08
#define LM63_REG_REMOTE_LOW_LSB		0x14
#define LM63_REG_REMOTE_TCRIT		0x19
#define LM63_REG_REMOTE_TCRIT_HYST	0x21

#define LM63_REG_ALERT_STATUS		0x02
#define LM63_REG_ALERT_MASK		0x16

#define LM63_REG_MAN_ID			0xFE
#define LM63_REG_CHIP_ID		0xFF

/*
 * Conversions and various macros
 * For tachometer counts, the LM63 uses 16-bit values.
 * For local temperature and high limit, remote critical limit and hysteresis
104
 * value, it uses signed 8-bit values with LSB = 1 degree Celsius.
L
Linus Torvalds 已提交
105
 * For remote temperature, low and high limits, it uses signed 11-bit values
106
 * with LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
L
Linus Torvalds 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
 */

#define FAN_FROM_REG(reg)	((reg) == 0xFFFC || (reg) == 0 ? 0 : \
				 5400000 / (reg))
#define FAN_TO_REG(val)		((val) <= 82 ? 0xFFFC : \
				 (5400000 / (val)) & 0xFFFC)
#define TEMP8_FROM_REG(reg)	((reg) * 1000)
#define TEMP8_TO_REG(val)	((val) <= -128000 ? -128 : \
				 (val) >= 127000 ? 127 : \
				 (val) < 0 ? ((val) - 500) / 1000 : \
				 ((val) + 500) / 1000)
#define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
#define TEMP11_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
				 (val) >= 127875 ? 0x7FE0 : \
				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
				 ((val) + 62) / 125 * 32)
#define HYST_TO_REG(val)	((val) <= 0 ? 0 : \
				 (val) >= 127000 ? 127 : \
				 ((val) + 500) / 1000)

/*
 * Functions declaration
 */

131 132 133
static int lm63_probe(struct i2c_client *client,
		      const struct i2c_device_id *id);
static int lm63_remove(struct i2c_client *client);
L
Linus Torvalds 已提交
134 135 136

static struct lm63_data *lm63_update_device(struct device *dev);

137 138
static int lm63_detect(struct i2c_client *client, int kind,
		       struct i2c_board_info *info);
L
Linus Torvalds 已提交
139 140 141 142 143 144
static void lm63_init_client(struct i2c_client *client);

/*
 * Driver data (common to all clients)
 */

145 146 147 148 149 150
static const struct i2c_device_id lm63_id[] = {
	{ "lm63", lm63 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, lm63_id);

L
Linus Torvalds 已提交
151
static struct i2c_driver lm63_driver = {
152
	.class		= I2C_CLASS_HWMON,
153 154 155
	.driver = {
		.name	= "lm63",
	},
156 157 158 159 160
	.probe		= lm63_probe,
	.remove		= lm63_remove,
	.id_table	= lm63_id,
	.detect		= lm63_detect,
	.address_data	= &addr_data,
L
Linus Torvalds 已提交
161 162 163 164 165 166 167
};

/*
 * Client data (each client gets its own)
 */

struct lm63_data {
168
	struct device *hwmon_dev;
169
	struct mutex update_lock;
L
Linus Torvalds 已提交
170 171 172 173 174
	char valid; /* zero until following fields are valid */
	unsigned long last_updated; /* in jiffies */

	/* registers values */
	u8 config, config_fan;
175 176
	u16 fan[2];	/* 0: input
			   1: low limit */
L
Linus Torvalds 已提交
177 178
	u8 pwm1_freq;
	u8 pwm1_value;
179 180 181 182 183 184
	s8 temp8[3];	/* 0: local input
			   1: local high limit
			   2: remote critical limit */
	s16 temp11[3];	/* 0: remote input
			   1: remote low limit
			   2: remote high limit */
L
Linus Torvalds 已提交
185 186 187 188 189 190 191 192
	u8 temp2_crit_hyst;
	u8 alarms;
};

/*
 * Sysfs callback functions and files
 */

193 194 195 196 197 198
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
			char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index]));
L
Linus Torvalds 已提交
199 200
}

201 202
static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
		       const char *buf, size_t count)
L
Linus Torvalds 已提交
203 204 205 206 207
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	unsigned long val = simple_strtoul(buf, NULL, 10);

208
	mutex_lock(&data->update_lock);
209
	data->fan[1] = FAN_TO_REG(val);
L
Linus Torvalds 已提交
210
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
211
				  data->fan[1] & 0xFF);
L
Linus Torvalds 已提交
212
	i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
213
				  data->fan[1] >> 8);
214
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
215 216 217
	return count;
}

218 219
static ssize_t show_pwm1(struct device *dev, struct device_attribute *dummy,
			 char *buf)
L
Linus Torvalds 已提交
220 221 222 223 224 225 226
{
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%d\n", data->pwm1_value >= 2 * data->pwm1_freq ?
		       255 : (data->pwm1_value * 255 + data->pwm1_freq) /
		       (2 * data->pwm1_freq));
}

227 228
static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
			const char *buf, size_t count)
L
Linus Torvalds 已提交
229 230 231 232 233 234 235 236 237
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	unsigned long val;
	
	if (!(data->config_fan & 0x20)) /* register is read-only */
		return -EPERM;

	val = simple_strtoul(buf, NULL, 10);
238
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
239 240 241 242
	data->pwm1_value = val <= 0 ? 0 :
			   val >= 255 ? 2 * data->pwm1_freq :
			   (val * data->pwm1_freq * 2 + 127) / 255;
	i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
243
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
244 245 246
	return count;
}

247 248
static ssize_t show_pwm1_enable(struct device *dev, struct device_attribute *dummy,
				char *buf)
L
Linus Torvalds 已提交
249 250 251 252 253
{
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%d\n", data->config_fan & 0x20 ? 1 : 2);
}

254 255 256 257 258 259
static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
			  char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[attr->index]));
L
Linus Torvalds 已提交
260
}
261 262 263 264 265 266 267 268

static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
			 const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);

269
	mutex_lock(&data->update_lock);
270 271
	data->temp8[1] = TEMP8_TO_REG(val);
	i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]);
272
	mutex_unlock(&data->update_lock);
273
	return count;
L
Linus Torvalds 已提交
274
}
275 276 277 278 279 280 281

static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
			   char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%d\n", TEMP11_FROM_REG(data->temp11[attr->index]));
L
Linus Torvalds 已提交
282
}
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299

static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
			  const char *buf, size_t count)
{
	static const u8 reg[4] = {
		LM63_REG_REMOTE_LOW_MSB,
		LM63_REG_REMOTE_LOW_LSB,
		LM63_REG_REMOTE_HIGH_MSB,
		LM63_REG_REMOTE_HIGH_LSB,
	};

	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);
	int nr = attr->index;

300
	mutex_lock(&data->update_lock);
301 302 303 304 305
	data->temp11[nr] = TEMP11_TO_REG(val);
	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
				  data->temp11[nr] >> 8);
	i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
				  data->temp11[nr] & 0xff);
306
	mutex_unlock(&data->update_lock);
307
	return count;
L
Linus Torvalds 已提交
308 309 310 311
}

/* Hysteresis register holds a relative value, while we want to present
   an absolute to user-space */
312 313
static ssize_t show_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
				    char *buf)
L
Linus Torvalds 已提交
314 315
{
	struct lm63_data *data = lm63_update_device(dev);
316
	return sprintf(buf, "%d\n", TEMP8_FROM_REG(data->temp8[2])
L
Linus Torvalds 已提交
317 318 319 320 321
		       - TEMP8_FROM_REG(data->temp2_crit_hyst));
}

/* And now the other way around, user-space provides an absolute
   hysteresis value and we have to store a relative one */
322 323
static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *dummy,
				   const char *buf, size_t count)
L
Linus Torvalds 已提交
324 325 326 327 328 329
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);
	long val = simple_strtol(buf, NULL, 10);
	long hyst;

330
	mutex_lock(&data->update_lock);
331
	hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
L
Linus Torvalds 已提交
332 333
	i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
				  HYST_TO_REG(hyst));
334
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
335 336 337
	return count;
}

338 339
static ssize_t show_alarms(struct device *dev, struct device_attribute *dummy,
			   char *buf)
L
Linus Torvalds 已提交
340 341 342 343 344
{
	struct lm63_data *data = lm63_update_device(dev);
	return sprintf(buf, "%u\n", data->alarms);
}

345 346 347 348 349 350 351 352 353 354
static ssize_t show_alarm(struct device *dev, struct device_attribute *devattr,
			  char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct lm63_data *data = lm63_update_device(dev);
	int bitnr = attr->index;

	return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1);
}

355 356 357
static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0);
static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan,
	set_fan, 1);
L
Linus Torvalds 已提交
358 359 360 361

static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm1, set_pwm1);
static DEVICE_ATTR(pwm1_enable, S_IRUGO, show_pwm1_enable, NULL);

362 363 364
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
	set_temp8, 1);
L
Linus Torvalds 已提交
365

366 367 368 369 370 371
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
	set_temp11, 1);
static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
	set_temp11, 2);
static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp8, NULL, 2);
L
Linus Torvalds 已提交
372 373 374
static DEVICE_ATTR(temp2_crit_hyst, S_IWUSR | S_IRUGO, show_temp2_crit_hyst,
	set_temp2_crit_hyst);

375 376 377
/* Individual alarm files */
static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 1);
378
static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
379 380 381 382
static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
/* Raw alarm file for compatibility */
L
Linus Torvalds 已提交
383 384
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);

385 386 387 388 389 390 391 392 393 394 395 396
static struct attribute *lm63_attributes[] = {
	&dev_attr_pwm1.attr,
	&dev_attr_pwm1_enable.attr,
	&sensor_dev_attr_temp1_input.dev_attr.attr,
	&sensor_dev_attr_temp2_input.dev_attr.attr,
	&sensor_dev_attr_temp2_min.dev_attr.attr,
	&sensor_dev_attr_temp1_max.dev_attr.attr,
	&sensor_dev_attr_temp2_max.dev_attr.attr,
	&sensor_dev_attr_temp2_crit.dev_attr.attr,
	&dev_attr_temp2_crit_hyst.attr,

	&sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
397
	&sensor_dev_attr_temp2_fault.dev_attr.attr,
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
	&sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
	&dev_attr_alarms.attr,
	NULL
};

static const struct attribute_group lm63_group = {
	.attrs = lm63_attributes,
};

static struct attribute *lm63_attributes_fan1[] = {
	&sensor_dev_attr_fan1_input.dev_attr.attr,
	&sensor_dev_attr_fan1_min.dev_attr.attr,

	&sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
	NULL
};

static const struct attribute_group lm63_group_fan1 = {
	.attrs = lm63_attributes_fan1,
};

L
Linus Torvalds 已提交
421 422 423 424
/*
 * Real code
 */

425 426 427
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm63_detect(struct i2c_client *new_client, int kind,
		       struct i2c_board_info *info)
L
Linus Torvalds 已提交
428
{
429
	struct i2c_adapter *adapter = new_client->adapter;
J
Jean Delvare 已提交
430 431
	u8 man_id, chip_id, reg_config1, reg_config2;
	u8 reg_alert_status, reg_alert_mask;
L
Linus Torvalds 已提交
432 433

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
434
		return -ENODEV;
L
Linus Torvalds 已提交
435

J
Jean Delvare 已提交
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
	man_id = i2c_smbus_read_byte_data(new_client, LM63_REG_MAN_ID);
	chip_id = i2c_smbus_read_byte_data(new_client, LM63_REG_CHIP_ID);

	reg_config1 = i2c_smbus_read_byte_data(new_client,
		      LM63_REG_CONFIG1);
	reg_config2 = i2c_smbus_read_byte_data(new_client,
		      LM63_REG_CONFIG2);
	reg_alert_status = i2c_smbus_read_byte_data(new_client,
			   LM63_REG_ALERT_STATUS);
	reg_alert_mask = i2c_smbus_read_byte_data(new_client,
			 LM63_REG_ALERT_MASK);

	if (man_id != 0x01 /* National Semiconductor */
	 || chip_id != 0x41 /* LM63 */
	 || (reg_config1 & 0x18) != 0x00
	 || (reg_config2 & 0xF8) != 0x00
	 || (reg_alert_status & 0x20) != 0x00
	 || (reg_alert_mask & 0xA4) != 0xA4) {
		dev_dbg(&adapter->dev,
			"Unsupported chip (man_id=0x%02X, chip_id=0x%02X)\n",
			man_id, chip_id);
		return -ENODEV;
L
Linus Torvalds 已提交
458 459
	}

460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
	strlcpy(info->type, "lm63", I2C_NAME_SIZE);

	return 0;
}

static int lm63_probe(struct i2c_client *new_client,
		      const struct i2c_device_id *id)
{
	struct lm63_data *data;
	int err;

	data = kzalloc(sizeof(struct lm63_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto exit;
	}

	i2c_set_clientdata(new_client, data);
L
Linus Torvalds 已提交
478
	data->valid = 0;
479
	mutex_init(&data->update_lock);
L
Linus Torvalds 已提交
480 481 482 483 484

	/* Initialize the LM63 chip */
	lm63_init_client(new_client);

	/* Register sysfs hooks */
485 486
	if ((err = sysfs_create_group(&new_client->dev.kobj,
				      &lm63_group)))
487
		goto exit_free;
488 489 490 491
	if (data->config & 0x04) { /* tachometer enabled */
		if ((err = sysfs_create_group(&new_client->dev.kobj,
					      &lm63_group_fan1)))
			goto exit_remove_files;
492 493
	}

494 495 496
	data->hwmon_dev = hwmon_device_register(&new_client->dev);
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
497
		goto exit_remove_files;
L
Linus Torvalds 已提交
498 499 500 501
	}

	return 0;

502 503 504
exit_remove_files:
	sysfs_remove_group(&new_client->dev.kobj, &lm63_group);
	sysfs_remove_group(&new_client->dev.kobj, &lm63_group_fan1);
L
Linus Torvalds 已提交
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
exit_free:
	kfree(data);
exit:
	return err;
}

/* Idealy we shouldn't have to initialize anything, since the BIOS
   should have taken care of everything */
static void lm63_init_client(struct i2c_client *client)
{
	struct lm63_data *data = i2c_get_clientdata(client);

	data->config = i2c_smbus_read_byte_data(client, LM63_REG_CONFIG1);
	data->config_fan = i2c_smbus_read_byte_data(client,
						    LM63_REG_CONFIG_FAN);

	/* Start converting if needed */
	if (data->config & 0x40) { /* standby */
523
		dev_dbg(&client->dev, "Switching to operational mode\n");
L
Linus Torvalds 已提交
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
		data->config &= 0xA7;
		i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1,
					  data->config);
	}

	/* We may need pwm1_freq before ever updating the client data */
	data->pwm1_freq = i2c_smbus_read_byte_data(client, LM63_REG_PWM_FREQ);
	if (data->pwm1_freq == 0)
		data->pwm1_freq = 1;

	/* Show some debug info about the LM63 configuration */
	dev_dbg(&client->dev, "Alert/tach pin configured for %s\n",
		(data->config & 0x04) ? "tachometer input" :
		"alert output");
	dev_dbg(&client->dev, "PWM clock %s kHz, output frequency %u Hz\n",
		(data->config_fan & 0x08) ? "1.4" : "360",
		((data->config_fan & 0x08) ? 700 : 180000) / data->pwm1_freq);
	dev_dbg(&client->dev, "PWM output active %s, %s mode\n",
		(data->config_fan & 0x10) ? "low" : "high",
		(data->config_fan & 0x20) ? "manual" : "auto");
}

546
static int lm63_remove(struct i2c_client *client)
L
Linus Torvalds 已提交
547
{
548
	struct lm63_data *data = i2c_get_clientdata(client);
L
Linus Torvalds 已提交
549

550
	hwmon_device_unregister(data->hwmon_dev);
551 552
	sysfs_remove_group(&client->dev.kobj, &lm63_group);
	sysfs_remove_group(&client->dev.kobj, &lm63_group_fan1);
553 554

	kfree(data);
L
Linus Torvalds 已提交
555 556 557 558 559 560 561 562
	return 0;
}

static struct lm63_data *lm63_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct lm63_data *data = i2c_get_clientdata(client);

563
	mutex_lock(&data->update_lock);
L
Linus Torvalds 已提交
564 565 566 567

	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
		if (data->config & 0x04) { /* tachometer enabled  */
			/* order matters for fan1_input */
568 569 570 571 572 573 574 575
			data->fan[0] = i2c_smbus_read_byte_data(client,
				       LM63_REG_TACH_COUNT_LSB) & 0xFC;
			data->fan[0] |= i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_COUNT_MSB) << 8;
			data->fan[1] = (i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_LIMIT_LSB) & 0xFC)
				     | (i2c_smbus_read_byte_data(client,
					LM63_REG_TACH_LIMIT_MSB) << 8);
L
Linus Torvalds 已提交
576 577 578 579 580 581 582 583 584
		}

		data->pwm1_freq = i2c_smbus_read_byte_data(client,
				  LM63_REG_PWM_FREQ);
		if (data->pwm1_freq == 0)
			data->pwm1_freq = 1;
		data->pwm1_value = i2c_smbus_read_byte_data(client,
				   LM63_REG_PWM_VALUE);

585 586 587 588
		data->temp8[0] = i2c_smbus_read_byte_data(client,
				 LM63_REG_LOCAL_TEMP);
		data->temp8[1] = i2c_smbus_read_byte_data(client,
				 LM63_REG_LOCAL_HIGH);
L
Linus Torvalds 已提交
589 590

		/* order matters for temp2_input */
591 592 593 594 595
		data->temp11[0] = i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_TEMP_MSB) << 8;
		data->temp11[0] |= i2c_smbus_read_byte_data(client,
				   LM63_REG_REMOTE_TEMP_LSB);
		data->temp11[1] = (i2c_smbus_read_byte_data(client,
L
Linus Torvalds 已提交
596 597 598
				  LM63_REG_REMOTE_LOW_MSB) << 8)
				| i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_LOW_LSB);
599 600 601 602 603 604
		data->temp11[2] = (i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_HIGH_MSB) << 8)
				| i2c_smbus_read_byte_data(client,
				  LM63_REG_REMOTE_HIGH_LSB);
		data->temp8[2] = i2c_smbus_read_byte_data(client,
				 LM63_REG_REMOTE_TCRIT);
L
Linus Torvalds 已提交
605 606 607 608 609 610 611 612 613 614
		data->temp2_crit_hyst = i2c_smbus_read_byte_data(client,
					LM63_REG_REMOTE_TCRIT_HYST);

		data->alarms = i2c_smbus_read_byte_data(client,
			       LM63_REG_ALERT_STATUS) & 0x7F;

		data->last_updated = jiffies;
		data->valid = 1;
	}

615
	mutex_unlock(&data->update_lock);
L
Linus Torvalds 已提交
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635

	return data;
}

static int __init sensors_lm63_init(void)
{
	return i2c_add_driver(&lm63_driver);
}

static void __exit sensors_lm63_exit(void)
{
	i2c_del_driver(&lm63_driver);
}

MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
MODULE_DESCRIPTION("LM63 driver");
MODULE_LICENSE("GPL");

module_init(sensors_lm63_init);
module_exit(sensors_lm63_exit);