1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Device driver for the i2c thermostat found on the iBook G4, Albook G4 4 * 5 * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt 6 * 7 * Documentation from 115254175ADT7467_pra.pdf and 3686221171167ADT7460_b.pdf 8 * https://www.onsemi.com/PowerSolutions/product.do?id=ADT7467 9 * https://www.onsemi.com/PowerSolutions/product.do?id=ADT7460 10 * 11 */ 12 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/wait.h> 24 #include <linux/suspend.h> 25 #include <linux/kthread.h> 26 #include <linux/moduleparam.h> 27 #include <linux/freezer.h> 28 #include <linux/of.h> 29 #include <linux/of_platform.h> 30 #include <linux/platform_device.h> 31 32 #include <asm/machdep.h> 33 #include <asm/io.h> 34 #include <asm/sections.h> 35 36 #undef DEBUG 37 38 #define CONFIG_REG 0x40 39 #define MANUAL_MASK 0xe0 40 #define AUTO_MASK 0x20 41 #define INVERT_MASK 0x10 42 43 static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ 44 static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ 45 static u8 MANUAL_MODE[2] = {0x5c, 0x5d}; 46 static u8 REM_CONTROL[2] = {0x00, 0x40}; 47 static u8 FAN_SPEED[2] = {0x28, 0x2a}; 48 static u8 FAN_SPD_SET[2] = {0x30, 0x31}; 49 50 static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ 51 static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ 52 static const char *sensor_location[3] = { "?", "?", "?" }; 53 54 static int limit_adjust; 55 static int fan_speed = -1; 56 static bool verbose; 57 58 MODULE_AUTHOR("Colin Leroy <colin@colino.net>"); 59 MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " 60 "Powerbook G4 Alu"); 61 MODULE_LICENSE("GPL"); 62 63 module_param(limit_adjust, int, 0644); 64 MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) " 65 "by N degrees."); 66 67 module_param(fan_speed, int, 0644); 68 MODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) " 69 "(default 64)"); 70 71 module_param(verbose, bool, 0); 72 MODULE_PARM_DESC(verbose,"Verbose log operations " 73 "(default 0)"); 74 75 struct thermostat { 76 struct i2c_client *clt; 77 u8 temps[3]; 78 u8 cached_temp[3]; 79 u8 initial_limits[3]; 80 u8 limits[3]; 81 int last_speed[2]; 82 int last_var[2]; 83 int pwm_inv[2]; 84 struct task_struct *thread; 85 struct platform_device *pdev; 86 enum { 87 ADT7460, 88 ADT7467 89 } type; 90 }; 91 92 static void write_both_fan_speed(struct thermostat *th, int speed); 93 static void write_fan_speed(struct thermostat *th, int speed, int fan); 94 95 static int 96 write_reg(struct thermostat* th, int reg, u8 data) 97 { 98 u8 tmp[2]; 99 int rc; 100 101 tmp[0] = reg; 102 tmp[1] = data; 103 rc = i2c_master_send(th->clt, (const char *)tmp, 2); 104 if (rc < 0) 105 return rc; 106 if (rc != 2) 107 return -ENODEV; 108 return 0; 109 } 110 111 static int 112 read_reg(struct thermostat* th, int reg) 113 { 114 u8 reg_addr, data; 115 int rc; 116 117 reg_addr = (u8)reg; 118 rc = i2c_master_send(th->clt, ®_addr, 1); 119 if (rc < 0) 120 return rc; 121 if (rc != 1) 122 return -ENODEV; 123 rc = i2c_master_recv(th->clt, (char *)&data, 1); 124 if (rc < 0) 125 return rc; 126 return data; 127 } 128 129 static int read_fan_speed(struct thermostat *th, u8 addr) 130 { 131 u8 tmp[2]; 132 u16 res; 133 134 /* should start with low byte */ 135 tmp[1] = read_reg(th, addr); 136 tmp[0] = read_reg(th, addr + 1); 137 138 res = tmp[1] + (tmp[0] << 8); 139 /* "a value of 0xffff means that the fan has stopped" */ 140 return (res == 0xffff ? 0 : (90000*60)/res); 141 } 142 143 static void write_both_fan_speed(struct thermostat *th, int speed) 144 { 145 write_fan_speed(th, speed, 0); 146 if (th->type == ADT7460) 147 write_fan_speed(th, speed, 1); 148 } 149 150 static void write_fan_speed(struct thermostat *th, int speed, int fan) 151 { 152 u8 manual; 153 154 if (speed > 0xff) 155 speed = 0xff; 156 else if (speed < -1) 157 speed = 0; 158 159 if (th->type == ADT7467 && fan == 1) 160 return; 161 162 if (th->last_speed[fan] != speed) { 163 if (verbose) { 164 if (speed == -1) 165 printk(KERN_DEBUG "adt746x: Setting speed to automatic " 166 "for %s fan.\n", sensor_location[fan+1]); 167 else 168 printk(KERN_DEBUG "adt746x: Setting speed to %d " 169 "for %s fan.\n", speed, sensor_location[fan+1]); 170 } 171 } else 172 return; 173 174 if (speed >= 0) { 175 manual = read_reg(th, MANUAL_MODE[fan]); 176 manual &= ~INVERT_MASK; 177 write_reg(th, MANUAL_MODE[fan], 178 manual | MANUAL_MASK | th->pwm_inv[fan]); 179 write_reg(th, FAN_SPD_SET[fan], speed); 180 } else { 181 /* back to automatic */ 182 if(th->type == ADT7460) { 183 manual = read_reg(th, 184 MANUAL_MODE[fan]) & (~MANUAL_MASK); 185 manual &= ~INVERT_MASK; 186 manual |= th->pwm_inv[fan]; 187 write_reg(th, 188 MANUAL_MODE[fan], manual|REM_CONTROL[fan]); 189 } else { 190 manual = read_reg(th, MANUAL_MODE[fan]); 191 manual &= ~INVERT_MASK; 192 manual |= th->pwm_inv[fan]; 193 write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); 194 } 195 } 196 197 th->last_speed[fan] = speed; 198 } 199 200 static void read_sensors(struct thermostat *th) 201 { 202 int i = 0; 203 204 for (i = 0; i < 3; i++) 205 th->temps[i] = read_reg(th, TEMP_REG[i]); 206 } 207 208 #ifdef DEBUG 209 static void display_stats(struct thermostat *th) 210 { 211 if (th->temps[0] != th->cached_temp[0] 212 || th->temps[1] != th->cached_temp[1] 213 || th->temps[2] != th->cached_temp[2]) { 214 printk(KERN_INFO "adt746x: Temperature infos:" 215 " thermostats: %d,%d,%d;" 216 " limits: %d,%d,%d;" 217 " fan speed: %d RPM\n", 218 th->temps[0], th->temps[1], th->temps[2], 219 th->limits[0], th->limits[1], th->limits[2], 220 read_fan_speed(th, FAN_SPEED[0])); 221 } 222 th->cached_temp[0] = th->temps[0]; 223 th->cached_temp[1] = th->temps[1]; 224 th->cached_temp[2] = th->temps[2]; 225 } 226 #endif 227 228 static void update_fans_speed (struct thermostat *th) 229 { 230 int lastvar = 0; /* last variation, for iBook */ 231 int i = 0; 232 233 /* we don't care about local sensor, so we start at sensor 1 */ 234 for (i = 1; i < 3; i++) { 235 bool started = false; 236 int fan_number = (th->type == ADT7460 && i == 2); 237 int var = th->temps[i] - th->limits[i]; 238 239 if (var > -1) { 240 int step = (255 - fan_speed) / 7; 241 int new_speed = 0; 242 243 /* hysteresis : change fan speed only if variation is 244 * more than two degrees */ 245 if (abs(var - th->last_var[fan_number]) < 2) 246 continue; 247 248 started = true; 249 new_speed = fan_speed + ((var-1)*step); 250 251 if (new_speed < fan_speed) 252 new_speed = fan_speed; 253 if (new_speed > 255) 254 new_speed = 255; 255 256 if (verbose) 257 printk(KERN_DEBUG "adt746x: Setting fans speed to %d " 258 "(limit exceeded by %d on %s)\n", 259 new_speed, var, 260 sensor_location[fan_number+1]); 261 write_both_fan_speed(th, new_speed); 262 th->last_var[fan_number] = var; 263 } else if (var < -2) { 264 /* don't stop fan if sensor2 is cold and sensor1 is not 265 * so cold (lastvar >= -1) */ 266 if (i == 2 && lastvar < -1) { 267 if (th->last_speed[fan_number] != 0) 268 if (verbose) 269 printk(KERN_DEBUG "adt746x: Stopping " 270 "fans.\n"); 271 write_both_fan_speed(th, 0); 272 } 273 } 274 275 lastvar = var; 276 277 if (started) 278 return; /* we don't want to re-stop the fan 279 * if sensor1 is heating and sensor2 is not */ 280 } 281 } 282 283 static int monitor_task(void *arg) 284 { 285 struct thermostat* th = arg; 286 287 set_freezable(); 288 while(!kthread_should_stop()) { 289 try_to_freeze(); 290 msleep_interruptible(2000); 291 292 #ifndef DEBUG 293 if (fan_speed != -1) 294 read_sensors(th); 295 #else 296 read_sensors(th); 297 #endif 298 299 if (fan_speed != -1) 300 update_fans_speed(th); 301 302 #ifdef DEBUG 303 display_stats(th); 304 #endif 305 306 } 307 308 return 0; 309 } 310 311 static void set_limit(struct thermostat *th, int i) 312 { 313 /* Set sensor1 limit higher to avoid powerdowns */ 314 th->limits[i] = default_limits_chip[i] + limit_adjust; 315 write_reg(th, LIMIT_REG[i], th->limits[i]); 316 317 /* set our limits to normal */ 318 th->limits[i] = default_limits_local[i] + limit_adjust; 319 } 320 321 #define BUILD_SHOW_FUNC_INT(name, data) \ 322 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 323 { \ 324 struct thermostat *th = dev_get_drvdata(dev); \ 325 return sprintf(buf, "%d\n", data); \ 326 } 327 328 #define BUILD_SHOW_FUNC_INT_LITE(name, data) \ 329 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 330 { \ 331 return sprintf(buf, "%d\n", data); \ 332 } 333 334 #define BUILD_SHOW_FUNC_STR(name, data) \ 335 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 336 { \ 337 return sprintf(buf, "%s\n", data); \ 338 } 339 340 #define BUILD_SHOW_FUNC_FAN(name, data) \ 341 static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ 342 { \ 343 struct thermostat *th = dev_get_drvdata(dev); \ 344 return sprintf(buf, "%d (%d rpm)\n", \ 345 th->last_speed[data], \ 346 read_fan_speed(th, FAN_SPEED[data]) \ 347 ); \ 348 } 349 350 #define BUILD_STORE_FUNC_DEG(name, data) \ 351 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ 352 { \ 353 struct thermostat *th = dev_get_drvdata(dev); \ 354 int val; \ 355 int i; \ 356 val = simple_strtol(buf, NULL, 10); \ 357 printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \ 358 limit_adjust = val; \ 359 for (i=0; i < 3; i++) \ 360 set_limit(th, i); \ 361 return n; \ 362 } 363 364 #define BUILD_STORE_FUNC_INT(name, data) \ 365 static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \ 366 { \ 367 int val; \ 368 val = simple_strtol(buf, NULL, 10); \ 369 if (val < 0 || val > 255) \ 370 return -EINVAL; \ 371 printk(KERN_INFO "Setting specified fan speed to %d\n", val); \ 372 data = val; \ 373 return n; \ 374 } 375 376 BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1]))) 377 BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2]))) 378 BUILD_SHOW_FUNC_INT(sensor1_limit, th->limits[1]) 379 BUILD_SHOW_FUNC_INT(sensor2_limit, th->limits[2]) 380 BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) 381 BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) 382 383 BUILD_SHOW_FUNC_INT_LITE(specified_fan_speed, fan_speed) 384 BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) 385 386 BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) 387 BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) 388 389 BUILD_SHOW_FUNC_INT_LITE(limit_adjust, limit_adjust) 390 BUILD_STORE_FUNC_DEG(limit_adjust, th) 391 392 static DEVICE_ATTR(sensor1_temperature, S_IRUGO, 393 show_sensor1_temperature,NULL); 394 static DEVICE_ATTR(sensor2_temperature, S_IRUGO, 395 show_sensor2_temperature,NULL); 396 static DEVICE_ATTR(sensor1_limit, S_IRUGO, 397 show_sensor1_limit, NULL); 398 static DEVICE_ATTR(sensor2_limit, S_IRUGO, 399 show_sensor2_limit, NULL); 400 static DEVICE_ATTR(sensor1_location, S_IRUGO, 401 show_sensor1_location, NULL); 402 static DEVICE_ATTR(sensor2_location, S_IRUGO, 403 show_sensor2_location, NULL); 404 405 static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 406 show_specified_fan_speed,store_specified_fan_speed); 407 408 static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO, 409 show_sensor1_fan_speed, NULL); 410 static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO, 411 show_sensor2_fan_speed, NULL); 412 413 static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 414 show_limit_adjust, store_limit_adjust); 415 416 static void thermostat_create_files(struct thermostat *th) 417 { 418 struct device_node *np = th->clt->dev.of_node; 419 struct device *dev; 420 int err; 421 422 /* To maintain ABI compatibility with userspace, create 423 * the old style platform driver and attach the attributes 424 * to it here 425 */ 426 th->pdev = of_platform_device_create(np, "temperatures", NULL); 427 if (!th->pdev) 428 return; 429 dev = &th->pdev->dev; 430 dev_set_drvdata(dev, th); 431 err = device_create_file(dev, &dev_attr_sensor1_temperature); 432 err |= device_create_file(dev, &dev_attr_sensor2_temperature); 433 err |= device_create_file(dev, &dev_attr_sensor1_limit); 434 err |= device_create_file(dev, &dev_attr_sensor2_limit); 435 err |= device_create_file(dev, &dev_attr_sensor1_location); 436 err |= device_create_file(dev, &dev_attr_sensor2_location); 437 err |= device_create_file(dev, &dev_attr_limit_adjust); 438 err |= device_create_file(dev, &dev_attr_specified_fan_speed); 439 err |= device_create_file(dev, &dev_attr_sensor1_fan_speed); 440 if(th->type == ADT7460) 441 err |= device_create_file(dev, &dev_attr_sensor2_fan_speed); 442 if (err) 443 printk(KERN_WARNING 444 "Failed to create temperature attribute file(s).\n"); 445 } 446 447 static void thermostat_remove_files(struct thermostat *th) 448 { 449 struct device *dev; 450 451 if (!th->pdev) 452 return; 453 dev = &th->pdev->dev; 454 device_remove_file(dev, &dev_attr_sensor1_temperature); 455 device_remove_file(dev, &dev_attr_sensor2_temperature); 456 device_remove_file(dev, &dev_attr_sensor1_limit); 457 device_remove_file(dev, &dev_attr_sensor2_limit); 458 device_remove_file(dev, &dev_attr_sensor1_location); 459 device_remove_file(dev, &dev_attr_sensor2_location); 460 device_remove_file(dev, &dev_attr_limit_adjust); 461 device_remove_file(dev, &dev_attr_specified_fan_speed); 462 device_remove_file(dev, &dev_attr_sensor1_fan_speed); 463 if (th->type == ADT7460) 464 device_remove_file(dev, &dev_attr_sensor2_fan_speed); 465 of_device_unregister(th->pdev); 466 467 } 468 469 static int probe_thermostat(struct i2c_client *client) 470 { 471 const struct i2c_device_id *id = i2c_client_get_device_id(client); 472 struct device_node *np = client->dev.of_node; 473 struct thermostat* th; 474 const __be32 *prop; 475 int i, rc, vers, offset = 0; 476 477 if (!np) 478 return -ENXIO; 479 prop = of_get_property(np, "hwsensor-params-version", NULL); 480 if (!prop) 481 return -ENXIO; 482 vers = be32_to_cpup(prop); 483 printk(KERN_INFO "adt746x: version %d (%ssupported)\n", 484 vers, vers == 1 ? "" : "un"); 485 if (vers != 1) 486 return -ENXIO; 487 488 if (of_property_present(np, "hwsensor-location")) { 489 for (i = 0; i < 3; i++) { 490 sensor_location[i] = of_get_property(np, 491 "hwsensor-location", NULL) + offset; 492 493 if (sensor_location[i] == NULL) 494 sensor_location[i] = ""; 495 496 printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]); 497 offset += strlen(sensor_location[i]) + 1; 498 } 499 } 500 501 th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); 502 if (!th) 503 return -ENOMEM; 504 505 i2c_set_clientdata(client, th); 506 th->clt = client; 507 th->type = id->driver_data; 508 509 rc = read_reg(th, CONFIG_REG); 510 if (rc < 0) { 511 dev_err(&client->dev, "Thermostat failed to read config!\n"); 512 kfree(th); 513 return -ENODEV; 514 } 515 516 /* force manual control to start the fan quieter */ 517 if (fan_speed == -1) 518 fan_speed = 64; 519 520 if (th->type == ADT7460) { 521 printk(KERN_INFO "adt746x: ADT7460 initializing\n"); 522 /* The 7460 needs to be started explicitly */ 523 write_reg(th, CONFIG_REG, 1); 524 } else 525 printk(KERN_INFO "adt746x: ADT7467 initializing\n"); 526 527 for (i = 0; i < 3; i++) { 528 th->initial_limits[i] = read_reg(th, LIMIT_REG[i]); 529 set_limit(th, i); 530 } 531 532 printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d" 533 " to %d, %d, %d\n", 534 th->initial_limits[0], th->initial_limits[1], 535 th->initial_limits[2], th->limits[0], th->limits[1], 536 th->limits[2]); 537 538 /* record invert bit status because fw can corrupt it after suspend */ 539 th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; 540 th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; 541 542 /* be sure to really write fan speed the first time */ 543 th->last_speed[0] = -2; 544 th->last_speed[1] = -2; 545 th->last_var[0] = -80; 546 th->last_var[1] = -80; 547 548 if (fan_speed != -1) { 549 /* manual mode, stop fans */ 550 write_both_fan_speed(th, 0); 551 } else { 552 /* automatic mode */ 553 write_both_fan_speed(th, -1); 554 } 555 556 th->thread = kthread_run(monitor_task, th, "kfand"); 557 if (th->thread == ERR_PTR(-ENOMEM)) { 558 printk(KERN_INFO "adt746x: Kthread creation failed\n"); 559 th->thread = NULL; 560 return -ENOMEM; 561 } 562 563 thermostat_create_files(th); 564 565 return 0; 566 } 567 568 static void remove_thermostat(struct i2c_client *client) 569 { 570 struct thermostat *th = i2c_get_clientdata(client); 571 int i; 572 573 thermostat_remove_files(th); 574 575 if (th->thread != NULL) 576 kthread_stop(th->thread); 577 578 printk(KERN_INFO "adt746x: Putting max temperatures back from " 579 "%d, %d, %d to %d, %d, %d\n", 580 th->limits[0], th->limits[1], th->limits[2], 581 th->initial_limits[0], th->initial_limits[1], 582 th->initial_limits[2]); 583 584 for (i = 0; i < 3; i++) 585 write_reg(th, LIMIT_REG[i], th->initial_limits[i]); 586 587 write_both_fan_speed(th, -1); 588 589 kfree(th); 590 } 591 592 static const struct i2c_device_id therm_adt746x_id[] = { 593 { "MAC,adt7460", ADT7460 }, 594 { "MAC,adt7467", ADT7467 }, 595 { } 596 }; 597 MODULE_DEVICE_TABLE(i2c, therm_adt746x_id); 598 599 static struct i2c_driver thermostat_driver = { 600 .driver = { 601 .name = "therm_adt746x", 602 }, 603 .probe = probe_thermostat, 604 .remove = remove_thermostat, 605 .id_table = therm_adt746x_id, 606 }; 607 608 static int __init thermostat_init(void) 609 { 610 #ifndef CONFIG_I2C_POWERMAC 611 request_module("i2c-powermac"); 612 #endif 613 614 return i2c_add_driver(&thermostat_driver); 615 } 616 617 static void __exit thermostat_exit(void) 618 { 619 i2c_del_driver(&thermostat_driver); 620 } 621 622 module_init(thermostat_init); 623 module_exit(thermostat_exit); 624