smsc47m1.c revision 8d5d45fb14680326f833295f2316a4ec5e357220
1/*
2    smsc47m1.c - Part of lm_sensors, Linux kernel modules
3                 for hardware monitoring
4
5    Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x
6    Super-I/O chips.
7
8    Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
9    Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
10    Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
11                        and Jean Delvare
12
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/ioport.h>
31#include <linux/jiffies.h>
32#include <linux/i2c.h>
33#include <linux/i2c-sensor.h>
34#include <linux/init.h>
35#include <asm/io.h>
36
37static unsigned short normal_i2c[] = { I2C_CLIENT_END };
38/* Address is autodetected, there is no default value */
39static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
40static struct i2c_force_data forces[] = {{NULL}};
41
42enum chips { any_chip, smsc47m1 };
43static struct i2c_address_data addr_data = {
44	.normal_i2c		= normal_i2c,
45	.normal_isa		= normal_isa,
46	.forces			= forces,
47};
48
49/* Super-I/0 registers and commands */
50
51#define	REG	0x2e	/* The register to read/write */
52#define	VAL	0x2f	/* The value to read/write */
53
54static inline void
55superio_outb(int reg, int val)
56{
57	outb(reg, REG);
58	outb(val, VAL);
59}
60
61static inline int
62superio_inb(int reg)
63{
64	outb(reg, REG);
65	return inb(VAL);
66}
67
68/* logical device for fans is 0x0A */
69#define superio_select() superio_outb(0x07, 0x0A)
70
71static inline void
72superio_enter(void)
73{
74	outb(0x55, REG);
75}
76
77static inline void
78superio_exit(void)
79{
80	outb(0xAA, REG);
81}
82
83#define SUPERIO_REG_ACT		0x30
84#define SUPERIO_REG_BASE	0x60
85#define SUPERIO_REG_DEVID	0x20
86
87/* Logical device registers */
88
89#define SMSC_EXTENT		0x80
90
91/* nr is 0 or 1 in the macros below */
92#define SMSC47M1_REG_ALARM		0x04
93#define SMSC47M1_REG_TPIN(nr)		(0x34 - (nr))
94#define SMSC47M1_REG_PPIN(nr)		(0x36 - (nr))
95#define SMSC47M1_REG_PWM(nr)		(0x56 + (nr))
96#define SMSC47M1_REG_FANDIV		0x58
97#define SMSC47M1_REG_FAN(nr)		(0x59 + (nr))
98#define SMSC47M1_REG_FAN_PRELOAD(nr)	(0x5B + (nr))
99
100#define MIN_FROM_REG(reg,div)		((reg)>=192 ? 0 : \
101					 983040/((192-(reg))*(div)))
102#define FAN_FROM_REG(reg,div,preload)	((reg)<=(preload) || (reg)==255 ? 0 : \
103					 983040/(((reg)-(preload))*(div)))
104#define DIV_FROM_REG(reg)		(1 << (reg))
105#define PWM_FROM_REG(reg)		(((reg) & 0x7E) << 1)
106#define PWM_EN_FROM_REG(reg)		((~(reg)) & 0x01)
107#define PWM_TO_REG(reg)			(((reg) >> 1) & 0x7E)
108
109struct smsc47m1_data {
110	struct i2c_client client;
111	struct semaphore lock;
112
113	struct semaphore update_lock;
114	unsigned long last_updated;	/* In jiffies */
115
116	u8 fan[2];		/* Register value */
117	u8 fan_preload[2];	/* Register value */
118	u8 fan_div[2];		/* Register encoding, shifted right */
119	u8 alarms;		/* Register encoding */
120	u8 pwm[2];		/* Register value (bit 7 is enable) */
121};
122
123
124static int smsc47m1_attach_adapter(struct i2c_adapter *adapter);
125static int smsc47m1_find(int *address);
126static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
127static int smsc47m1_detach_client(struct i2c_client *client);
128
129static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
130static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
131
132static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
133		int init);
134
135
136static struct i2c_driver smsc47m1_driver = {
137	.owner		= THIS_MODULE,
138	.name		= "smsc47m1",
139	.id		= I2C_DRIVERID_SMSC47M1,
140	.flags		= I2C_DF_NOTIFY,
141	.attach_adapter	= smsc47m1_attach_adapter,
142	.detach_client	= smsc47m1_detach_client,
143};
144
145/* nr is 0 or 1 in the callback functions below */
146
147static ssize_t get_fan(struct device *dev, char *buf, int nr)
148{
149	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
150	/* This chip (stupidly) stops monitoring fan speed if PWM is
151	   enabled and duty cycle is 0%. This is fine if the monitoring
152	   and control concern the same fan, but troublesome if they are
153	   not (which could as well happen). */
154	int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
155		  FAN_FROM_REG(data->fan[nr],
156			       DIV_FROM_REG(data->fan_div[nr]),
157			       data->fan_preload[nr]);
158	return sprintf(buf, "%d\n", rpm);
159}
160
161static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
162{
163	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
164	int rpm = MIN_FROM_REG(data->fan_preload[nr],
165			       DIV_FROM_REG(data->fan_div[nr]));
166	return sprintf(buf, "%d\n", rpm);
167}
168
169static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
170{
171	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
172	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
173}
174
175static ssize_t get_pwm(struct device *dev, char *buf, int nr)
176{
177	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
178	return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
179}
180
181static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
182{
183	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
184	return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
185}
186
187static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
188{
189	struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
190	return sprintf(buf, "%d\n", data->alarms);
191}
192
193static ssize_t set_fan_min(struct device *dev, const char *buf,
194		size_t count, int nr)
195{
196	struct i2c_client *client = to_i2c_client(dev);
197	struct smsc47m1_data *data = i2c_get_clientdata(client);
198	long rpmdiv, val = simple_strtol(buf, NULL, 10);
199
200	down(&data->update_lock);
201	rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
202
203	if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
204		up(&data->update_lock);
205		return -EINVAL;
206	}
207
208	data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
209	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
210			     data->fan_preload[nr]);
211	up(&data->update_lock);
212
213	return count;
214}
215
216/* Note: we save and restore the fan minimum here, because its value is
217   determined in part by the fan clock divider.  This follows the principle
218   of least suprise; the user doesn't expect the fan minimum to change just
219   because the divider changed. */
220static ssize_t set_fan_div(struct device *dev, const char *buf,
221		size_t count, int nr)
222{
223	struct i2c_client *client = to_i2c_client(dev);
224	struct smsc47m1_data *data = i2c_get_clientdata(client);
225
226	long new_div = simple_strtol(buf, NULL, 10), tmp;
227	u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
228
229	if (new_div == old_div) /* No change */
230		return count;
231
232	down(&data->update_lock);
233	switch (new_div) {
234	case 1: data->fan_div[nr] = 0; break;
235	case 2: data->fan_div[nr] = 1; break;
236	case 4: data->fan_div[nr] = 2; break;
237	case 8: data->fan_div[nr] = 3; break;
238	default:
239		up(&data->update_lock);
240		return -EINVAL;
241	}
242
243	tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
244	tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
245	smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
246
247	/* Preserve fan min */
248	tmp = 192 - (old_div * (192 - data->fan_preload[nr])
249		     + new_div / 2) / new_div;
250	data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
251	smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
252			     data->fan_preload[nr]);
253	up(&data->update_lock);
254
255	return count;
256}
257
258static ssize_t set_pwm(struct device *dev, const char *buf,
259		size_t count, int nr)
260{
261	struct i2c_client *client = to_i2c_client(dev);
262	struct smsc47m1_data *data = i2c_get_clientdata(client);
263
264	long val = simple_strtol(buf, NULL, 10);
265
266	if (val < 0 || val > 255)
267		return -EINVAL;
268
269	down(&data->update_lock);
270	data->pwm[nr] &= 0x81; /* Preserve additional bits */
271	data->pwm[nr] |= PWM_TO_REG(val);
272	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
273			     data->pwm[nr]);
274	up(&data->update_lock);
275
276	return count;
277}
278
279static ssize_t set_pwm_en(struct device *dev, const char *buf,
280		size_t count, int nr)
281{
282	struct i2c_client *client = to_i2c_client(dev);
283	struct smsc47m1_data *data = i2c_get_clientdata(client);
284
285	long val = simple_strtol(buf, NULL, 10);
286
287	if (val != 0 && val != 1)
288		return -EINVAL;
289
290	down(&data->update_lock);
291	data->pwm[nr] &= 0xFE; /* preserve the other bits */
292	data->pwm[nr] |= !val;
293	smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
294			     data->pwm[nr]);
295	up(&data->update_lock);
296
297	return count;
298}
299
300#define fan_present(offset)						\
301static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
302{									\
303	return get_fan(dev, buf, offset - 1);				\
304}									\
305static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)	\
306{									\
307	return get_fan_min(dev, buf, offset - 1);			\
308}									\
309static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr,		\
310		const char *buf, size_t count)				\
311{									\
312	return set_fan_min(dev, buf, count, offset - 1);		\
313}									\
314static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)	\
315{									\
316	return get_fan_div(dev, buf, offset - 1);			\
317}									\
318static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr,		\
319		const char *buf, size_t count)				\
320{									\
321	return set_fan_div(dev, buf, count, offset - 1);		\
322}									\
323static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf)		\
324{									\
325	return get_pwm(dev, buf, offset - 1);				\
326}									\
327static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr,			\
328		const char *buf, size_t count)				\
329{									\
330	return set_pwm(dev, buf, count, offset - 1);			\
331}									\
332static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf)	\
333{									\
334	return get_pwm_en(dev, buf, offset - 1);			\
335}									\
336static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr,		\
337		const char *buf, size_t count)				\
338{									\
339	return set_pwm_en(dev, buf, count, offset - 1);			\
340}									\
341static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset,	\
342		NULL);							\
343static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
344		get_fan##offset##_min, set_fan##offset##_min);		\
345static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
346		get_fan##offset##_div, set_fan##offset##_div);		\
347static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,			\
348		get_pwm##offset, set_pwm##offset);			\
349static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,		\
350		get_pwm##offset##_en, set_pwm##offset##_en);
351
352fan_present(1);
353fan_present(2);
354
355static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
356
357static int smsc47m1_attach_adapter(struct i2c_adapter *adapter)
358{
359	if (!(adapter->class & I2C_CLASS_HWMON))
360		return 0;
361	return i2c_detect(adapter, &addr_data, smsc47m1_detect);
362}
363
364static int smsc47m1_find(int *address)
365{
366	u8 val;
367
368	superio_enter();
369	val = superio_inb(SUPERIO_REG_DEVID);
370
371	/*
372	 * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
373	 * 0x5F) and LPC47B27x (device id 0x51) have fan control.
374	 * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
375	 * can do much more besides (device id 0x60).
376	 */
377	if (val == 0x51)
378		printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
379	else if (val == 0x59)
380		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n");
381	else if (val == 0x5F)
382		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
383	else if (val == 0x60)
384		printk(KERN_INFO "smsc47m1: Found SMSC LPC47M15x/LPC47M192\n");
385	else {
386		superio_exit();
387		return -ENODEV;
388	}
389
390	superio_select();
391	*address = (superio_inb(SUPERIO_REG_BASE) << 8)
392		 |  superio_inb(SUPERIO_REG_BASE + 1);
393	val = superio_inb(SUPERIO_REG_ACT);
394	if (*address == 0 || (val & 0x01) == 0) {
395		printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
396		superio_exit();
397		return -ENODEV;
398	}
399
400	superio_exit();
401	return 0;
402}
403
404static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
405{
406	struct i2c_client *new_client;
407	struct smsc47m1_data *data;
408	int err = 0;
409	int fan1, fan2, pwm1, pwm2;
410
411	if (!i2c_is_isa_adapter(adapter)) {
412		return 0;
413	}
414
415	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
416		dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
417		return -EBUSY;
418	}
419
420	if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
421		err = -ENOMEM;
422		goto error_release;
423	}
424	memset(data, 0x00, sizeof(struct smsc47m1_data));
425
426	new_client = &data->client;
427	i2c_set_clientdata(new_client, data);
428	new_client->addr = address;
429	init_MUTEX(&data->lock);
430	new_client->adapter = adapter;
431	new_client->driver = &smsc47m1_driver;
432	new_client->flags = 0;
433
434	strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
435	init_MUTEX(&data->update_lock);
436
437	/* If no function is properly configured, there's no point in
438	   actually registering the chip. */
439	fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
440	       == 0x05;
441	fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
442	       == 0x05;
443	pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
444	       == 0x04;
445	pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
446	       == 0x04;
447	if (!(fan1 || fan2 || pwm1 || pwm2)) {
448		dev_warn(&new_client->dev, "Device is not configured, will not use\n");
449		err = -ENODEV;
450		goto error_free;
451	}
452
453	if ((err = i2c_attach_client(new_client)))
454		goto error_free;
455
456	/* Some values (fan min, clock dividers, pwm registers) may be
457	   needed before any update is triggered, so we better read them
458	   at least once here. We don't usually do it that way, but in
459	   this particular case, manually reading 5 registers out of 8
460	   doesn't make much sense and we're better using the existing
461	   function. */
462	smsc47m1_update_device(&new_client->dev, 1);
463
464	if (fan1) {
465		device_create_file(&new_client->dev, &dev_attr_fan1_input);
466		device_create_file(&new_client->dev, &dev_attr_fan1_min);
467		device_create_file(&new_client->dev, &dev_attr_fan1_div);
468	} else
469		dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
470			"skipping\n");
471
472	if (fan2) {
473		device_create_file(&new_client->dev, &dev_attr_fan2_input);
474		device_create_file(&new_client->dev, &dev_attr_fan2_min);
475		device_create_file(&new_client->dev, &dev_attr_fan2_div);
476	} else
477		dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
478			"skipping\n");
479
480	if (pwm1) {
481		device_create_file(&new_client->dev, &dev_attr_pwm1);
482		device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
483	} else
484		dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
485			"skipping\n");
486	if (pwm2) {
487		device_create_file(&new_client->dev, &dev_attr_pwm2);
488		device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
489	} else
490		dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
491			"skipping\n");
492
493	device_create_file(&new_client->dev, &dev_attr_alarms);
494
495	return 0;
496
497error_free:
498	kfree(new_client);
499error_release:
500	release_region(address, SMSC_EXTENT);
501	return err;
502}
503
504static int smsc47m1_detach_client(struct i2c_client *client)
505{
506	int err;
507
508	if ((err = i2c_detach_client(client))) {
509		dev_err(&client->dev, "Client deregistration failed, "
510			"client not detached.\n");
511		return err;
512	}
513
514	release_region(client->addr, SMSC_EXTENT);
515	kfree(i2c_get_clientdata(client));
516
517	return 0;
518}
519
520static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
521{
522	int res;
523
524	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
525	res = inb_p(client->addr + reg);
526	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
527	return res;
528}
529
530static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
531{
532	down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
533	outb_p(value, client->addr + reg);
534	up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
535}
536
537static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
538		int init)
539{
540 	struct i2c_client *client = to_i2c_client(dev);
541	struct smsc47m1_data *data = i2c_get_clientdata(client);
542
543	down(&data->update_lock);
544
545	if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
546		int i;
547
548		for (i = 0; i < 2; i++) {
549			data->fan[i] = smsc47m1_read_value(client,
550				       SMSC47M1_REG_FAN(i));
551			data->fan_preload[i] = smsc47m1_read_value(client,
552					       SMSC47M1_REG_FAN_PRELOAD(i));
553			data->pwm[i] = smsc47m1_read_value(client,
554				       SMSC47M1_REG_PWM(i));
555		}
556
557		i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
558		data->fan_div[0] = (i >> 4) & 0x03;
559		data->fan_div[1] = i >> 6;
560
561		data->alarms = smsc47m1_read_value(client,
562			       SMSC47M1_REG_ALARM) >> 6;
563		/* Clear alarms if needed */
564		if (data->alarms)
565			smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
566
567		data->last_updated = jiffies;
568	}
569
570	up(&data->update_lock);
571	return data;
572}
573
574static int __init sm_smsc47m1_init(void)
575{
576	if (smsc47m1_find(normal_isa)) {
577		return -ENODEV;
578	}
579
580	return i2c_add_driver(&smsc47m1_driver);
581}
582
583static void __exit sm_smsc47m1_exit(void)
584{
585	i2c_del_driver(&smsc47m1_driver);
586}
587
588MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
589MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
590MODULE_LICENSE("GPL");
591
592module_init(sm_smsc47m1_init);
593module_exit(sm_smsc47m1_exit);
594