1 /*
2  * Device driver for the i2c thermostat found on the iBook G4, Albook G4
3  *
4  * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt
5  *
6  * Documentation from
7  * http://www.analog.com/UploadedFiles/Data_Sheets/115254175ADT7467_pra.pdf
8  * http://www.analog.com/UploadedFiles/Data_Sheets/3686221171167ADT7460_b.pdf
9  *
10  */
11 
12 #include <linux/config.h>
13 #include <linux/types.h>
14 #include <linux/module.h>
15 #include <linux/errno.h>
16 #include <linux/kernel.h>
17 #include <linux/delay.h>
18 #include <linux/sched.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/init.h>
22 #include <linux/spinlock.h>
23 #include <linux/smp_lock.h>
24 #include <linux/wait.h>
25 #include <linux/suspend.h>
26 #include <linux/kthread.h>
27 #include <linux/moduleparam.h>
28 
29 #include <asm/prom.h>
30 #include <asm/machdep.h>
31 #include <asm/io.h>
32 #include <asm/system.h>
33 #include <asm/sections.h>
34 #include <asm/of_device.h>
35 
36 #undef DEBUG
37 
38 #define CONFIG_REG   0x40
39 #define MANUAL_MASK  0xe0
40 #define AUTO_MASK    0x20
41 
42 static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, cpu, gpu */
43 static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, cpu, gpu */
44 static u8 MANUAL_MODE[2] = {0x5c, 0x5d};
45 static u8 REM_CONTROL[2] = {0x00, 0x40};
46 static u8 FAN_SPEED[2]   = {0x28, 0x2a};
47 static u8 FAN_SPD_SET[2] = {0x30, 0x31};
48 
49 static u8 default_limits_local[3] = {70, 50, 70};    /* local, cpu, gpu */
50 static u8 default_limits_chip[3] = {80, 65, 80};    /* local, cpu, gpu */
51 
52 static int limit_adjust = 0;
53 static int fan_speed = -1;
54 
55 MODULE_AUTHOR("Colin Leroy <colin@colino.net>");
56 MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and "
57 		   "Powerbook G4 Alu");
58 MODULE_LICENSE("GPL");
59 
60 module_param(limit_adjust, int, 0644);
61 MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 cpu, 70 gpu) "
62 		 "by N degrees.");
63 
64 module_param(fan_speed, int, 0644);
65 MODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) "
66 		 "(default 64)");
67 
68 struct thermostat {
69 	struct i2c_client	clt;
70 	u8			temps[3];
71 	u8			cached_temp[3];
72 	u8			initial_limits[3];
73 	u8			limits[3];
74 	int			last_speed[2];
75 	int			last_var[2];
76 };
77 
78 static enum {ADT7460, ADT7467} therm_type;
79 static int therm_bus, therm_address;
80 static struct of_device * of_dev;
81 static struct thermostat* thermostat;
82 static struct task_struct *thread_therm = NULL;
83 
84 static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
85 				 int busno);
86 
87 static void write_both_fan_speed(struct thermostat *th, int speed);
88 static void write_fan_speed(struct thermostat *th, int speed, int fan);
89 
90 static int
91 write_reg(struct thermostat* th, int reg, u8 data)
92 {
93 	u8 tmp[2];
94 	int rc;
95 
96 	tmp[0] = reg;
97 	tmp[1] = data;
98 	rc = i2c_master_send(&th->clt, (const char *)tmp, 2);
99 	if (rc < 0)
100 		return rc;
101 	if (rc != 2)
102 		return -ENODEV;
103 	return 0;
104 }
105 
106 static int
107 read_reg(struct thermostat* th, int reg)
108 {
109 	u8 reg_addr, data;
110 	int rc;
111 
112 	reg_addr = (u8)reg;
113 	rc = i2c_master_send(&th->clt, &reg_addr, 1);
114 	if (rc < 0)
115 		return rc;
116 	if (rc != 1)
117 		return -ENODEV;
118 	rc = i2c_master_recv(&th->clt, (char *)&data, 1);
119 	if (rc < 0)
120 		return rc;
121 	return data;
122 }
123 
124 static int
125 attach_thermostat(struct i2c_adapter *adapter)
126 {
127 	unsigned long bus_no;
128 
129 	if (strncmp(adapter->name, "uni-n", 5))
130 		return -ENODEV;
131 	bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
132 	if (bus_no != therm_bus)
133 		return -ENODEV;
134 	return attach_one_thermostat(adapter, therm_address, bus_no);
135 }
136 
137 static int
138 detach_thermostat(struct i2c_adapter *adapter)
139 {
140 	struct thermostat* th;
141 	int i;
142 
143 	if (thermostat == NULL)
144 		return 0;
145 
146 	th = thermostat;
147 
148 	if (thread_therm != NULL) {
149 		kthread_stop(thread_therm);
150 	}
151 
152 	printk(KERN_INFO "adt746x: Putting max temperatures back from "
153 			 "%d, %d, %d to %d, %d, %d\n",
154 		th->limits[0], th->limits[1], th->limits[2],
155 		th->initial_limits[0], th->initial_limits[1],
156 		th->initial_limits[2]);
157 
158 	for (i = 0; i < 3; i++)
159 		write_reg(th, LIMIT_REG[i], th->initial_limits[i]);
160 
161 	write_both_fan_speed(th, -1);
162 
163 	i2c_detach_client(&th->clt);
164 
165 	thermostat = NULL;
166 
167 	kfree(th);
168 
169 	return 0;
170 }
171 
172 static struct i2c_driver thermostat_driver = {
173 	.owner		= THIS_MODULE,
174 	.name		= "therm_adt746x",
175 	.flags		= I2C_DF_NOTIFY,
176 	.attach_adapter	= attach_thermostat,
177 	.detach_adapter	= detach_thermostat,
178 };
179 
180 static int read_fan_speed(struct thermostat *th, u8 addr)
181 {
182 	u8 tmp[2];
183 	u16 res;
184 
185 	/* should start with low byte */
186 	tmp[1] = read_reg(th, addr);
187 	tmp[0] = read_reg(th, addr + 1);
188 
189 	res = tmp[1] + (tmp[0] << 8);
190 	/* "a value of 0xffff means that the fan has stopped" */
191 	return (res == 0xffff ? 0 : (90000*60)/res);
192 }
193 
194 static void write_both_fan_speed(struct thermostat *th, int speed)
195 {
196 	write_fan_speed(th, speed, 0);
197 	if (therm_type == ADT7460)
198 		write_fan_speed(th, speed, 1);
199 }
200 
201 static void write_fan_speed(struct thermostat *th, int speed, int fan)
202 {
203 	u8 manual;
204 
205 	if (speed > 0xff)
206 		speed = 0xff;
207 	else if (speed < -1)
208 		speed = 0;
209 
210 	if (therm_type == ADT7467 && fan == 1)
211 		return;
212 
213 	if (th->last_speed[fan] != speed) {
214 		if (speed == -1)
215 			printk(KERN_DEBUG "adt746x: Setting speed to automatic "
216 				"for %s fan.\n", fan?"GPU":"CPU");
217 		else
218 			printk(KERN_DEBUG "adt746x: Setting speed to %d "
219 				"for %s fan.\n", speed, fan?"GPU":"CPU");
220 	} else
221 		return;
222 
223 	if (speed >= 0) {
224 		manual = read_reg(th, MANUAL_MODE[fan]);
225 		write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
226 		write_reg(th, FAN_SPD_SET[fan], speed);
227 	} else {
228 		/* back to automatic */
229 		if(therm_type == ADT7460) {
230 			manual = read_reg(th,
231 				MANUAL_MODE[fan]) & (~MANUAL_MASK);
232 
233 			write_reg(th,
234 				MANUAL_MODE[fan], manual|REM_CONTROL[fan]);
235 		} else {
236 			manual = read_reg(th, MANUAL_MODE[fan]);
237 			write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK));
238 		}
239 	}
240 
241 	th->last_speed[fan] = speed;
242 }
243 
244 static void read_sensors(struct thermostat *th)
245 {
246 	int i = 0;
247 
248 	for (i = 0; i < 3; i++)
249 		th->temps[i]  = read_reg(th, TEMP_REG[i]);
250 }
251 
252 #ifdef DEBUG
253 static void display_stats(struct thermostat *th)
254 {
255 	if (th->temps[0] != th->cached_temp[0]
256 	||  th->temps[1] != th->cached_temp[1]
257 	||  th->temps[2] != th->cached_temp[2]) {
258 		printk(KERN_INFO "adt746x: Temperature infos:"
259 				 " thermostats: %d,%d,%d;"
260 				 " limits: %d,%d,%d;"
261 				 " fan speed: %d RPM\n",
262 				 th->temps[0], th->temps[1], th->temps[2],
263 				 th->limits[0],  th->limits[1],  th->limits[2],
264 				 read_fan_speed(th, FAN_SPEED[0]));
265 	}
266 	th->cached_temp[0] = th->temps[0];
267 	th->cached_temp[1] = th->temps[1];
268 	th->cached_temp[2] = th->temps[2];
269 }
270 #endif
271 
272 static void update_fans_speed (struct thermostat *th)
273 {
274 	int lastvar = 0; /* last variation, for iBook */
275 	int i = 0;
276 
277 	/* we don't care about local sensor, so we start at sensor 1 */
278 	for (i = 1; i < 3; i++) {
279 		int started = 0;
280 		int fan_number = (therm_type == ADT7460 && i == 2);
281 		int var = th->temps[i] - th->limits[i];
282 
283 		if (var > -1) {
284 			int step = (255 - fan_speed) / 7;
285 			int new_speed = 0;
286 
287 			/* hysteresis : change fan speed only if variation is
288 			 * more than two degrees */
289 			if (abs(var - th->last_var[fan_number]) < 2)
290 				continue;
291 
292 			started = 1;
293 			new_speed = fan_speed + ((var-1)*step);
294 
295 			if (new_speed < fan_speed)
296 				new_speed = fan_speed;
297 			if (new_speed > 255)
298 				new_speed = 255;
299 
300 			printk(KERN_DEBUG "adt746x: setting fans speed to %d "
301 					 "(limit exceeded by %d on %s) \n",
302 					new_speed, var,
303 					fan_number?"GPU/pwr":"CPU");
304 			write_both_fan_speed(th, new_speed);
305 			th->last_var[fan_number] = var;
306 		} else if (var < -2) {
307 			/* don't stop fan if GPU/power is cold and CPU is not
308 			 * so cold (lastvar >= -1) */
309 			if (i == 2 && lastvar < -1) {
310 				if (th->last_speed[fan_number] != 0)
311 					printk(KERN_DEBUG "adt746x: Stopping "
312 						"fans.\n");
313 				write_both_fan_speed(th, 0);
314 			}
315 		}
316 
317 		lastvar = var;
318 
319 		if (started)
320 			return; /* we don't want to re-stop the fan
321 				* if CPU is heating and GPU/power is not */
322 	}
323 }
324 
325 static int monitor_task(void *arg)
326 {
327 	struct thermostat* th = arg;
328 
329 	while(!kthread_should_stop()) {
330 		if (current->flags & PF_FREEZE)
331 			refrigerator(PF_FREEZE);
332 
333 		msleep_interruptible(2000);
334 
335 #ifndef DEBUG
336 		if (fan_speed != -1)
337 			read_sensors(th);
338 #else
339 		read_sensors(th);
340 #endif
341 
342 		if (fan_speed != -1)
343 			update_fans_speed(th);
344 
345 #ifdef DEBUG
346 		display_stats(th);
347 #endif
348 
349 	}
350 
351 	return 0;
352 }
353 
354 static void set_limit(struct thermostat *th, int i)
355 {
356 		/* Set CPU limit higher to avoid powerdowns */
357 		th->limits[i] = default_limits_chip[i] + limit_adjust;
358 		write_reg(th, LIMIT_REG[i], th->limits[i]);
359 
360 		/* set our limits to normal */
361 		th->limits[i] = default_limits_local[i] + limit_adjust;
362 }
363 
364 static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
365 				 int busno)
366 {
367 	struct thermostat* th;
368 	int rc;
369 	int i;
370 
371 	if (thermostat)
372 		return 0;
373 
374 	th = (struct thermostat *)
375 		kmalloc(sizeof(struct thermostat), GFP_KERNEL);
376 
377 	if (!th)
378 		return -ENOMEM;
379 
380 	memset(th, 0, sizeof(*th));
381 	th->clt.addr = addr;
382 	th->clt.adapter = adapter;
383 	th->clt.driver = &thermostat_driver;
384 	strcpy(th->clt.name, "thermostat");
385 
386 	rc = read_reg(th, 0);
387 	if (rc < 0) {
388 		printk(KERN_ERR "adt746x: Thermostat failed to read config "
389 				"from bus %d !\n",
390 				busno);
391 		kfree(th);
392 		return -ENODEV;
393 	}
394 
395 	/* force manual control to start the fan quieter */
396 	if (fan_speed == -1)
397 		fan_speed = 64;
398 
399 	if(therm_type == ADT7460) {
400 		printk(KERN_INFO "adt746x: ADT7460 initializing\n");
401 		/* The 7460 needs to be started explicitly */
402 		write_reg(th, CONFIG_REG, 1);
403 	} else
404 		printk(KERN_INFO "adt746x: ADT7467 initializing\n");
405 
406 	for (i = 0; i < 3; i++) {
407 		th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
408 		set_limit(th, i);
409 	}
410 
411 	printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
412 			 " to %d, %d, %d\n",
413 			 th->initial_limits[0], th->initial_limits[1],
414 			 th->initial_limits[2], th->limits[0], th->limits[1],
415 			 th->limits[2]);
416 
417 	thermostat = th;
418 
419 	if (i2c_attach_client(&th->clt)) {
420 		printk(KERN_INFO "adt746x: Thermostat failed to attach "
421 				 "client !\n");
422 		thermostat = NULL;
423 		kfree(th);
424 		return -ENODEV;
425 	}
426 
427 	/* be sure to really write fan speed the first time */
428 	th->last_speed[0] = -2;
429 	th->last_speed[1] = -2;
430 	th->last_var[0] = -80;
431 	th->last_var[1] = -80;
432 
433 	if (fan_speed != -1) {
434 		/* manual mode, stop fans */
435 		write_both_fan_speed(th, 0);
436 	} else {
437 		/* automatic mode */
438 		write_both_fan_speed(th, -1);
439 	}
440 
441 	thread_therm = kthread_run(monitor_task, th, "kfand");
442 
443 	if (thread_therm == ERR_PTR(-ENOMEM)) {
444 		printk(KERN_INFO "adt746x: Kthread creation failed\n");
445 		thread_therm = NULL;
446 		return -ENOMEM;
447 	}
448 
449 	return 0;
450 }
451 
452 /*
453  * Now, unfortunately, sysfs doesn't give us a nice void * we could
454  * pass around to the attribute functions, so we don't really have
455  * choice but implement a bunch of them...
456  *
457  */
458 #define BUILD_SHOW_FUNC_INT(name, data)				\
459 static ssize_t show_##name(struct device *dev, char *buf)	\
460 {								\
461 	return sprintf(buf, "%d\n", data);			\
462 }
463 
464 #define BUILD_SHOW_FUNC_FAN(name, data)				\
465 static ssize_t show_##name(struct device *dev, char *buf)       \
466 {								\
467 	return sprintf(buf, "%d (%d rpm)\n", 			\
468 		thermostat->last_speed[data],			\
469 		read_fan_speed(thermostat, FAN_SPEED[data])	\
470 		);						\
471 }
472 
473 #define BUILD_STORE_FUNC_DEG(name, data)			\
474 static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
475 {								\
476 	int val;						\
477 	int i;							\
478 	val = simple_strtol(buf, NULL, 10);			\
479 	printk(KERN_INFO "Adjusting limits by %d�C\n", val);	\
480 	limit_adjust = val;					\
481 	for (i=0; i < 3; i++)					\
482 		set_limit(thermostat, i);			\
483 	return n;						\
484 }
485 
486 #define BUILD_STORE_FUNC_INT(name, data)			\
487 static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \
488 {								\
489 	u32 val;						\
490 	val = simple_strtoul(buf, NULL, 10);			\
491 	if (val < 0 || val > 255)				\
492 		return -EINVAL;					\
493 	printk(KERN_INFO "Setting specified fan speed to %d\n", val);	\
494 	data = val;						\
495 	return n;						\
496 }
497 
498 BUILD_SHOW_FUNC_INT(cpu_temperature,	 (read_reg(thermostat, TEMP_REG[1])))
499 BUILD_SHOW_FUNC_INT(gpu_temperature,	 (read_reg(thermostat, TEMP_REG[2])))
500 BUILD_SHOW_FUNC_INT(cpu_limit,		 thermostat->limits[1])
501 BUILD_SHOW_FUNC_INT(gpu_limit,		 thermostat->limits[2])
502 
503 BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed)
504 BUILD_SHOW_FUNC_FAN(cpu_fan_speed,	 0)
505 BUILD_SHOW_FUNC_FAN(gpu_fan_speed,	 1)
506 
507 BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed)
508 BUILD_SHOW_FUNC_INT(limit_adjust,	 limit_adjust)
509 BUILD_STORE_FUNC_DEG(limit_adjust,	 thermostat)
510 
511 static DEVICE_ATTR(cpu_temperature,	S_IRUGO,
512 		   show_cpu_temperature,NULL);
513 static DEVICE_ATTR(gpu_temperature,	S_IRUGO,
514 		   show_gpu_temperature,NULL);
515 static DEVICE_ATTR(cpu_limit,		S_IRUGO,
516 		   show_cpu_limit,	NULL);
517 static DEVICE_ATTR(gpu_limit,		S_IRUGO,
518 		   show_gpu_limit,	NULL);
519 
520 static DEVICE_ATTR(specified_fan_speed,	S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
521 		   show_specified_fan_speed,store_specified_fan_speed);
522 
523 static DEVICE_ATTR(cpu_fan_speed,	S_IRUGO,
524 		   show_cpu_fan_speed,	NULL);
525 static DEVICE_ATTR(gpu_fan_speed,	S_IRUGO,
526 		   show_gpu_fan_speed,	NULL);
527 
528 static DEVICE_ATTR(limit_adjust,	S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH,
529 		   show_limit_adjust,	store_limit_adjust);
530 
531 
532 static int __init
533 thermostat_init(void)
534 {
535 	struct device_node* np;
536 	u32 *prop;
537 
538 	np = of_find_node_by_name(NULL, "fan");
539 	if (!np)
540 		return -ENODEV;
541 	if (device_is_compatible(np, "adt7460"))
542 		therm_type = ADT7460;
543 	else if (device_is_compatible(np, "adt7467"))
544 		therm_type = ADT7467;
545 	else
546 		return -ENODEV;
547 
548 	prop = (u32 *)get_property(np, "reg", NULL);
549 	if (!prop)
550 		return -ENODEV;
551 
552 	/* look for bus either by path or using "reg" */
553 	if (strstr(np->full_name, "/i2c-bus@") != NULL) {
554 		const char *tmp_bus = (strstr(np->full_name, "/i2c-bus@") + 9);
555 		therm_bus = tmp_bus[0]-'0';
556 	} else {
557 		therm_bus = ((*prop) >> 8) & 0x0f;
558 	}
559 
560 	therm_address = ((*prop) & 0xff) >> 1;
561 
562 	printk(KERN_INFO "adt746x: Thermostat bus: %d, address: 0x%02x, "
563 			 "limit_adjust: %d, fan_speed: %d\n",
564 			 therm_bus, therm_address, limit_adjust, fan_speed);
565 
566 	of_dev = of_platform_device_create(np, "temperatures");
567 
568 	if (of_dev == NULL) {
569 		printk(KERN_ERR "Can't register temperatures device !\n");
570 		return -ENODEV;
571 	}
572 
573 	device_create_file(&of_dev->dev, &dev_attr_cpu_temperature);
574 	device_create_file(&of_dev->dev, &dev_attr_gpu_temperature);
575 	device_create_file(&of_dev->dev, &dev_attr_cpu_limit);
576 	device_create_file(&of_dev->dev, &dev_attr_gpu_limit);
577 	device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
578 	device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
579 	device_create_file(&of_dev->dev, &dev_attr_cpu_fan_speed);
580 	if(therm_type == ADT7460)
581 		device_create_file(&of_dev->dev, &dev_attr_gpu_fan_speed);
582 
583 #ifndef CONFIG_I2C_KEYWEST
584 	request_module("i2c-keywest");
585 #endif
586 
587 	return i2c_add_driver(&thermostat_driver);
588 }
589 
590 static void __exit
591 thermostat_exit(void)
592 {
593 	if (of_dev) {
594 		device_remove_file(&of_dev->dev, &dev_attr_cpu_temperature);
595 		device_remove_file(&of_dev->dev, &dev_attr_gpu_temperature);
596 		device_remove_file(&of_dev->dev, &dev_attr_cpu_limit);
597 		device_remove_file(&of_dev->dev, &dev_attr_gpu_limit);
598 		device_remove_file(&of_dev->dev, &dev_attr_limit_adjust);
599 		device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed);
600 		device_remove_file(&of_dev->dev, &dev_attr_cpu_fan_speed);
601 
602 		if(therm_type == ADT7460)
603 			device_remove_file(&of_dev->dev,
604 					   &dev_attr_gpu_fan_speed);
605 
606 		of_device_unregister(of_dev);
607 	}
608 	i2c_del_driver(&thermostat_driver);
609 }
610 
611 module_init(thermostat_init);
612 module_exit(thermostat_exit);
613