therm_adt746x.c 17 KB

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