therm_adt746x.c 16 KB

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