1169695Skan// SPDX-License-Identifier: GPL-2.0-only 2169695Skan/* 3169695Skan * Device driver for the i2c thermostat found on the iBook G4, Albook G4 4169695Skan * 5169695Skan * Copyright (C) 2003, 2004 Colin Leroy, Rasmus Rohde, Benjamin Herrenschmidt 6169695Skan * 7169695Skan * Documentation from 115254175ADT7467_pra.pdf and 3686221171167ADT7460_b.pdf 8169695Skan * https://www.onsemi.com/PowerSolutions/product.do?id=ADT7467 9169695Skan * https://www.onsemi.com/PowerSolutions/product.do?id=ADT7460 10169695Skan * 11169695Skan */ 12169695Skan 13169695Skan#include <linux/types.h> 14169695Skan#include <linux/module.h> 15169695Skan#include <linux/errno.h> 16169695Skan#include <linux/kernel.h> 17169695Skan#include <linux/delay.h> 18169695Skan#include <linux/sched.h> 19169695Skan#include <linux/i2c.h> 20169695Skan#include <linux/slab.h> 21169695Skan#include <linux/init.h> 22169695Skan#include <linux/spinlock.h> 23169695Skan#include <linux/wait.h> 24169695Skan#include <linux/suspend.h> 25169695Skan#include <linux/kthread.h> 26169695Skan#include <linux/moduleparam.h> 27169695Skan#include <linux/freezer.h> 28169695Skan#include <linux/of.h> 29169695Skan#include <linux/of_platform.h> 30169695Skan#include <linux/platform_device.h> 31169695Skan 32169695Skan#include <asm/machdep.h> 33169695Skan#include <asm/io.h> 34169695Skan#include <asm/sections.h> 35169695Skan 36169695Skan#undef DEBUG 37169695Skan 38169695Skan#define CONFIG_REG 0x40 39169695Skan#define MANUAL_MASK 0xe0 40169695Skan#define AUTO_MASK 0x20 41169695Skan#define INVERT_MASK 0x10 42169695Skan 43169695Skanstatic u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ 44169695Skanstatic u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ 45169695Skanstatic u8 MANUAL_MODE[2] = {0x5c, 0x5d}; 46169695Skanstatic u8 REM_CONTROL[2] = {0x00, 0x40}; 47169695Skanstatic u8 FAN_SPEED[2] = {0x28, 0x2a}; 48169695Skanstatic u8 FAN_SPD_SET[2] = {0x30, 0x31}; 49169695Skan 50169695Skanstatic u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ 51169695Skanstatic u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ 52169695Skanstatic const char *sensor_location[3] = { "?", "?", "?" }; 53169695Skan 54169695Skanstatic int limit_adjust; 55169695Skanstatic int fan_speed = -1; 56169695Skanstatic bool verbose; 57169695Skan 58169695SkanMODULE_AUTHOR("Colin Leroy <colin@colino.net>"); 59169695SkanMODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " 60169695Skan "Powerbook G4 Alu"); 61169695SkanMODULE_LICENSE("GPL"); 62169695Skan 63169695Skanmodule_param(limit_adjust, int, 0644); 64169695SkanMODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) " 65169695Skan "by N degrees."); 66169695Skan 67169695Skanmodule_param(fan_speed, int, 0644); 68169695SkanMODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) " 69169695Skan "(default 64)"); 70169695Skan 71169695Skanmodule_param(verbose, bool, 0); 72169695SkanMODULE_PARM_DESC(verbose,"Verbose log operations " 73169695Skan "(default 0)"); 74169695Skan 75169695Skanstruct thermostat { 76169695Skan struct i2c_client *clt; 77169695Skan u8 temps[3]; 78169695Skan u8 cached_temp[3]; 79169695Skan u8 initial_limits[3]; 80169695Skan u8 limits[3]; 81169695Skan int last_speed[2]; 82169695Skan int last_var[2]; 83169695Skan int pwm_inv[2]; 84169695Skan struct task_struct *thread; 85169695Skan struct platform_device *pdev; 86169695Skan enum { 87169695Skan ADT7460, 88169695Skan ADT7467 89169695Skan } type; 90169695Skan}; 91169695Skan 92169695Skanstatic void write_both_fan_speed(struct thermostat *th, int speed); 93169695Skanstatic void write_fan_speed(struct thermostat *th, int speed, int fan); 94169695Skan 95169695Skanstatic int 96169695Skanwrite_reg(struct thermostat* th, int reg, u8 data) 97169695Skan{ 98169695Skan u8 tmp[2]; 99169695Skan int rc; 100169695Skan 101169695Skan tmp[0] = reg; 102169695Skan tmp[1] = data; 103169695Skan rc = i2c_master_send(th->clt, (const char *)tmp, 2); 104169695Skan if (rc < 0) 105169695Skan return rc; 106169695Skan if (rc != 2) 107169695Skan return -ENODEV; 108169695Skan return 0; 109169695Skan} 110169695Skan 111169695Skanstatic int 112169695Skanread_reg(struct thermostat* th, int reg) 113169695Skan{ 114169695Skan u8 reg_addr, data; 115169695Skan int rc; 116169695Skan 117169695Skan reg_addr = (u8)reg; 118169695Skan rc = i2c_master_send(th->clt, ®_addr, 1); 119169695Skan if (rc < 0) 120169695Skan return rc; 121169695Skan if (rc != 1) 122169695Skan return -ENODEV; 123169695Skan rc = i2c_master_recv(th->clt, (char *)&data, 1); 124169695Skan if (rc < 0) 125169695Skan return rc; 126169695Skan return data; 127169695Skan} 128169695Skan 129169695Skanstatic int read_fan_speed(struct thermostat *th, u8 addr) 130169695Skan{ 131169695Skan u8 tmp[2]; 132169695Skan u16 res; 133169695Skan 134169695Skan /* should start with low byte */ 135169695Skan tmp[1] = read_reg(th, addr); 136169695Skan tmp[0] = read_reg(th, addr + 1); 137169695Skan 138169695Skan res = tmp[1] + (tmp[0] << 8); 139169695Skan /* "a value of 0xffff means that the fan has stopped" */ 140169695Skan return (res == 0xffff ? 0 : (90000*60)/res); 141169695Skan} 142169695Skan 143169695Skanstatic void write_both_fan_speed(struct thermostat *th, int speed) 144169695Skan{ 145169695Skan write_fan_speed(th, speed, 0); 146169695Skan if (th->type == ADT7460) 147169695Skan write_fan_speed(th, speed, 1); 148169695Skan} 149169695Skan 150169695Skanstatic void write_fan_speed(struct thermostat *th, int speed, int fan) 151169695Skan{ 152169695Skan u8 manual; 153169695Skan 154169695Skan if (speed > 0xff) 155169695Skan speed = 0xff; 156169695Skan else if (speed < -1) 157169695Skan speed = 0; 158169695Skan 159169695Skan if (th->type == ADT7467 && fan == 1) 160169695Skan return; 161169695Skan 162169695Skan if (th->last_speed[fan] != speed) { 163169695Skan if (verbose) { 164169695Skan if (speed == -1) 165169695Skan printk(KERN_DEBUG "adt746x: Setting speed to automatic " 166169695Skan "for %s fan.\n", sensor_location[fan+1]); 167169695Skan else 168169695Skan printk(KERN_DEBUG "adt746x: Setting speed to %d " 169169695Skan "for %s fan.\n", speed, sensor_location[fan+1]); 170169695Skan } 171169695Skan } else 172169695Skan return; 173169695Skan 174169695Skan if (speed >= 0) { 175169695Skan manual = read_reg(th, MANUAL_MODE[fan]); 176169695Skan manual &= ~INVERT_MASK; 177169695Skan write_reg(th, MANUAL_MODE[fan], 178169695Skan manual | MANUAL_MASK | th->pwm_inv[fan]); 179169695Skan write_reg(th, FAN_SPD_SET[fan], speed); 180169695Skan } else { 181169695Skan /* back to automatic */ 182169695Skan if(th->type == ADT7460) { 183169695Skan manual = read_reg(th, 184169695Skan MANUAL_MODE[fan]) & (~MANUAL_MASK); 185169695Skan manual &= ~INVERT_MASK; 186169695Skan manual |= th->pwm_inv[fan]; 187169695Skan write_reg(th, 188169695Skan MANUAL_MODE[fan], manual|REM_CONTROL[fan]); 189169695Skan } else { 190169695Skan manual = read_reg(th, MANUAL_MODE[fan]); 191169695Skan manual &= ~INVERT_MASK; 192169695Skan manual |= th->pwm_inv[fan]; 193169695Skan write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); 194169695Skan } 195169695Skan } 196169695Skan 197169695Skan th->last_speed[fan] = speed; 198169695Skan} 199169695Skan 200169695Skanstatic void read_sensors(struct thermostat *th) 201169695Skan{ 202169695Skan int i = 0; 203169695Skan 204169695Skan for (i = 0; i < 3; i++) 205169695Skan th->temps[i] = read_reg(th, TEMP_REG[i]); 206169695Skan} 207169695Skan 208169695Skan#ifdef DEBUG 209169695Skanstatic void display_stats(struct thermostat *th) 210169695Skan{ 211169695Skan if (th->temps[0] != th->cached_temp[0] 212169695Skan || th->temps[1] != th->cached_temp[1] 213169695Skan || th->temps[2] != th->cached_temp[2]) { 214169695Skan printk(KERN_INFO "adt746x: Temperature infos:" 215169695Skan " thermostats: %d,%d,%d;" 216169695Skan " limits: %d,%d,%d;" 217169695Skan " fan speed: %d RPM\n", 218169695Skan th->temps[0], th->temps[1], th->temps[2], 219169695Skan th->limits[0], th->limits[1], th->limits[2], 220169695Skan read_fan_speed(th, FAN_SPEED[0])); 221169695Skan } 222169695Skan th->cached_temp[0] = th->temps[0]; 223169695Skan th->cached_temp[1] = th->temps[1]; 224169695Skan th->cached_temp[2] = th->temps[2]; 225169695Skan} 226169695Skan#endif 227169695Skan 228169695Skanstatic void update_fans_speed (struct thermostat *th) 229169695Skan{ 230169695Skan int lastvar = 0; /* last variation, for iBook */ 231169695Skan int i = 0; 232169695Skan 233169695Skan /* we don't care about local sensor, so we start at sensor 1 */ 234169695Skan for (i = 1; i < 3; i++) { 235169695Skan bool started = false; 236169695Skan int fan_number = (th->type == ADT7460 && i == 2); 237169695Skan int var = th->temps[i] - th->limits[i]; 238169695Skan 239169695Skan if (var > -1) { 240169695Skan int step = (255 - fan_speed) / 7; 241169695Skan int new_speed = 0; 242169695Skan 243169695Skan /* hysteresis : change fan speed only if variation is 244169695Skan * more than two degrees */ 245169695Skan if (abs(var - th->last_var[fan_number]) < 2) 246169695Skan continue; 247169695Skan 248169695Skan started = true; 249169695Skan new_speed = fan_speed + ((var-1)*step); 250169695Skan 251169695Skan if (new_speed < fan_speed) 252169695Skan new_speed = fan_speed; 253169695Skan if (new_speed > 255) 254169695Skan new_speed = 255; 255169695Skan 256169695Skan if (verbose) 257169695Skan printk(KERN_DEBUG "adt746x: Setting fans speed to %d " 258169695Skan "(limit exceeded by %d on %s)\n", 259169695Skan new_speed, var, 260169695Skan sensor_location[fan_number+1]); 261169695Skan write_both_fan_speed(th, new_speed); 262169695Skan th->last_var[fan_number] = var; 263169695Skan } else if (var < -2) { 264169695Skan /* don't stop fan if sensor2 is cold and sensor1 is not 265169695Skan * so cold (lastvar >= -1) */ 266169695Skan if (i == 2 && lastvar < -1) { 267169695Skan if (th->last_speed[fan_number] != 0) 268169695Skan if (verbose) 269169695Skan printk(KERN_DEBUG "adt746x: Stopping " 270169695Skan "fans.\n"); 271169695Skan write_both_fan_speed(th, 0); 272169695Skan } 273169695Skan } 274169695Skan 275169695Skan lastvar = var; 276169695Skan 277169695Skan if (started) 278169695Skan return; /* we don't want to re-stop the fan 279169695Skan * if sensor1 is heating and sensor2 is not */ 280169695Skan } 281169695Skan} 282169695Skan 283169695Skanstatic int monitor_task(void *arg) 284169695Skan{ 285169695Skan struct thermostat* th = arg; 286169695Skan 287169695Skan set_freezable(); 288169695Skan while(!kthread_should_stop()) { 289169695Skan try_to_freeze(); 290169695Skan msleep_interruptible(2000); 291169695Skan 292169695Skan#ifndef DEBUG 293169695Skan if (fan_speed != -1) 294169695Skan read_sensors(th); 295169695Skan#else 296169695Skan read_sensors(th); 297169695Skan#endif 298169695Skan 299169695Skan if (fan_speed != -1) 300169695Skan update_fans_speed(th); 301169695Skan 302169695Skan#ifdef DEBUG 303169695Skan display_stats(th); 304#endif 305 306 } 307 308 return 0; 309} 310 311static 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) \ 322static 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) \ 329static 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) \ 335static 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) \ 341static 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) \ 351static 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) \ 365static 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 376BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(th, TEMP_REG[1]))) 377BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(th, TEMP_REG[2]))) 378BUILD_SHOW_FUNC_INT(sensor1_limit, th->limits[1]) 379BUILD_SHOW_FUNC_INT(sensor2_limit, th->limits[2]) 380BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) 381BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) 382 383BUILD_SHOW_FUNC_INT_LITE(specified_fan_speed, fan_speed) 384BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) 385 386BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) 387BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) 388 389BUILD_SHOW_FUNC_INT_LITE(limit_adjust, limit_adjust) 390BUILD_STORE_FUNC_DEG(limit_adjust, th) 391 392static DEVICE_ATTR(sensor1_temperature, S_IRUGO, 393 show_sensor1_temperature,NULL); 394static DEVICE_ATTR(sensor2_temperature, S_IRUGO, 395 show_sensor2_temperature,NULL); 396static DEVICE_ATTR(sensor1_limit, S_IRUGO, 397 show_sensor1_limit, NULL); 398static DEVICE_ATTR(sensor2_limit, S_IRUGO, 399 show_sensor2_limit, NULL); 400static DEVICE_ATTR(sensor1_location, S_IRUGO, 401 show_sensor1_location, NULL); 402static DEVICE_ATTR(sensor2_location, S_IRUGO, 403 show_sensor2_location, NULL); 404 405static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 406 show_specified_fan_speed,store_specified_fan_speed); 407 408static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO, 409 show_sensor1_fan_speed, NULL); 410static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO, 411 show_sensor2_fan_speed, NULL); 412 413static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 414 show_limit_adjust, store_limit_adjust); 415 416static 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 447static 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 469static 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 568static 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 592static const struct i2c_device_id therm_adt746x_id[] = { 593 { "MAC,adt7460", ADT7460 }, 594 { "MAC,adt7467", ADT7467 }, 595 { } 596}; 597MODULE_DEVICE_TABLE(i2c, therm_adt746x_id); 598 599static 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 608static 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 617static void __exit thermostat_exit(void) 618{ 619 i2c_del_driver(&thermostat_driver); 620} 621 622module_init(thermostat_init); 623module_exit(thermostat_exit); 624