pc87360.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348
  1. /*
  2. * pc87360.c - Part of lm_sensors, Linux kernel modules
  3. * for hardware monitoring
  4. * Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
  5. *
  6. * Copied from smsc47m1.c:
  7. * Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. *
  23. * Supports the following chips:
  24. *
  25. * Chip #vin #fan #pwm #temp devid
  26. * PC87360 - 2 2 - 0xE1
  27. * PC87363 - 2 2 - 0xE8
  28. * PC87364 - 3 3 - 0xE4
  29. * PC87365 11 3 3 2 0xE5
  30. * PC87366 11 3 3 3-4 0xE9
  31. *
  32. * This driver assumes that no more than one chip is present, and one of
  33. * the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
  34. */
  35. #include <linux/module.h>
  36. #include <linux/init.h>
  37. #include <linux/slab.h>
  38. #include <linux/jiffies.h>
  39. #include <linux/i2c.h>
  40. #include <linux/i2c-sensor.h>
  41. #include <linux/i2c-vid.h>
  42. #include <asm/io.h>
  43. static unsigned short normal_i2c[] = { I2C_CLIENT_END };
  44. static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
  45. static struct i2c_force_data forces[] = {{ NULL }};
  46. static u8 devid;
  47. static unsigned int extra_isa[3];
  48. static u8 confreg[4];
  49. enum chips { any_chip, pc87360, pc87363, pc87364, pc87365, pc87366 };
  50. static struct i2c_address_data addr_data = {
  51. .normal_i2c = normal_i2c,
  52. .normal_isa = normal_isa,
  53. .forces = forces,
  54. };
  55. static int init = 1;
  56. module_param(init, int, 0);
  57. MODULE_PARM_DESC(init,
  58. "Chip initialization level:\n"
  59. " 0: None\n"
  60. "*1: Forcibly enable internal voltage and temperature channels, except in9\n"
  61. " 2: Forcibly enable all voltage and temperature channels, except in9\n"
  62. " 3: Forcibly enable all voltage and temperature channels, including in9");
  63. /*
  64. * Super-I/O registers and operations
  65. */
  66. #define DEV 0x07 /* Register: Logical device select */
  67. #define DEVID 0x20 /* Register: Device ID */
  68. #define ACT 0x30 /* Register: Device activation */
  69. #define BASE 0x60 /* Register: Base address */
  70. #define FSCM 0x09 /* Logical device: fans */
  71. #define VLM 0x0d /* Logical device: voltages */
  72. #define TMS 0x0e /* Logical device: temperatures */
  73. static const u8 logdev[3] = { FSCM, VLM, TMS };
  74. #define LD_FAN 0
  75. #define LD_IN 1
  76. #define LD_TEMP 2
  77. static inline void superio_outb(int sioaddr, int reg, int val)
  78. {
  79. outb(reg, sioaddr);
  80. outb(val, sioaddr+1);
  81. }
  82. static inline int superio_inb(int sioaddr, int reg)
  83. {
  84. outb(reg, sioaddr);
  85. return inb(sioaddr+1);
  86. }
  87. static inline void superio_exit(int sioaddr)
  88. {
  89. outb(0x02, sioaddr);
  90. outb(0x02, sioaddr+1);
  91. }
  92. /*
  93. * Logical devices
  94. */
  95. #define PC87360_EXTENT 0x10
  96. #define PC87365_REG_BANK 0x09
  97. #define NO_BANK 0xff
  98. /*
  99. * Fan registers and conversions
  100. */
  101. /* nr has to be 0 or 1 (PC87360/87363) or 2 (PC87364/87365/87366) */
  102. #define PC87360_REG_PRESCALE(nr) (0x00 + 2 * (nr))
  103. #define PC87360_REG_PWM(nr) (0x01 + 2 * (nr))
  104. #define PC87360_REG_FAN_MIN(nr) (0x06 + 3 * (nr))
  105. #define PC87360_REG_FAN(nr) (0x07 + 3 * (nr))
  106. #define PC87360_REG_FAN_STATUS(nr) (0x08 + 3 * (nr))
  107. #define FAN_FROM_REG(val,div) ((val) == 0 ? 0: \
  108. 480000 / ((val)*(div)))
  109. #define FAN_TO_REG(val,div) ((val) <= 100 ? 0 : \
  110. 480000 / ((val)*(div)))
  111. #define FAN_DIV_FROM_REG(val) (1 << ((val >> 5) & 0x03))
  112. #define FAN_STATUS_FROM_REG(val) ((val) & 0x07)
  113. #define FAN_CONFIG_MONITOR(val,nr) (((val) >> (2 + nr * 3)) & 1)
  114. #define FAN_CONFIG_CONTROL(val,nr) (((val) >> (3 + nr * 3)) & 1)
  115. #define FAN_CONFIG_INVERT(val,nr) (((val) >> (4 + nr * 3)) & 1)
  116. #define PWM_FROM_REG(val,inv) ((inv) ? 255 - (val) : (val))
  117. static inline u8 PWM_TO_REG(int val, int inv)
  118. {
  119. if (inv)
  120. val = 255 - val;
  121. if (val < 0)
  122. return 0;
  123. if (val > 255)
  124. return 255;
  125. return val;
  126. }
  127. /*
  128. * Voltage registers and conversions
  129. */
  130. #define PC87365_REG_IN_CONVRATE 0x07
  131. #define PC87365_REG_IN_CONFIG 0x08
  132. #define PC87365_REG_IN 0x0B
  133. #define PC87365_REG_IN_MIN 0x0D
  134. #define PC87365_REG_IN_MAX 0x0C
  135. #define PC87365_REG_IN_STATUS 0x0A
  136. #define PC87365_REG_IN_ALARMS1 0x00
  137. #define PC87365_REG_IN_ALARMS2 0x01
  138. #define PC87365_REG_VID 0x06
  139. #define IN_FROM_REG(val,ref) (((val) * (ref) + 128) / 256)
  140. #define IN_TO_REG(val,ref) ((val) < 0 ? 0 : \
  141. (val)*256 >= (ref)*255 ? 255: \
  142. ((val) * 256 + (ref)/2) / (ref))
  143. /*
  144. * Temperature registers and conversions
  145. */
  146. #define PC87365_REG_TEMP_CONFIG 0x08
  147. #define PC87365_REG_TEMP 0x0B
  148. #define PC87365_REG_TEMP_MIN 0x0D
  149. #define PC87365_REG_TEMP_MAX 0x0C
  150. #define PC87365_REG_TEMP_CRIT 0x0E
  151. #define PC87365_REG_TEMP_STATUS 0x0A
  152. #define PC87365_REG_TEMP_ALARMS 0x00
  153. #define TEMP_FROM_REG(val) ((val) * 1000)
  154. #define TEMP_TO_REG(val) ((val) < -55000 ? -55 : \
  155. (val) > 127000 ? 127 : \
  156. (val) < 0 ? ((val) - 500) / 1000 : \
  157. ((val) + 500) / 1000)
  158. /*
  159. * Client data (each client gets its own)
  160. */
  161. struct pc87360_data {
  162. struct i2c_client client;
  163. struct semaphore lock;
  164. struct semaphore update_lock;
  165. char valid; /* !=0 if following fields are valid */
  166. unsigned long last_updated; /* In jiffies */
  167. int address[3];
  168. u8 fannr, innr, tempnr;
  169. u8 fan[3]; /* Register value */
  170. u8 fan_min[3]; /* Register value */
  171. u8 fan_status[3]; /* Register value */
  172. u8 pwm[3]; /* Register value */
  173. u16 fan_conf; /* Configuration register values, combined */
  174. u16 in_vref; /* 1 mV/bit */
  175. u8 in[14]; /* Register value */
  176. u8 in_min[14]; /* Register value */
  177. u8 in_max[14]; /* Register value */
  178. u8 in_crit[3]; /* Register value */
  179. u8 in_status[14]; /* Register value */
  180. u16 in_alarms; /* Register values, combined, masked */
  181. u8 vid_conf; /* Configuration register value */
  182. u8 vrm;
  183. u8 vid; /* Register value */
  184. s8 temp[3]; /* Register value */
  185. s8 temp_min[3]; /* Register value */
  186. s8 temp_max[3]; /* Register value */
  187. s8 temp_crit[3]; /* Register value */
  188. u8 temp_status[3]; /* Register value */
  189. u8 temp_alarms; /* Register value, masked */
  190. };
  191. /*
  192. * Functions declaration
  193. */
  194. static int pc87360_attach_adapter(struct i2c_adapter *adapter);
  195. static int pc87360_detect(struct i2c_adapter *adapter, int address, int kind);
  196. static int pc87360_detach_client(struct i2c_client *client);
  197. static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
  198. u8 reg);
  199. static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
  200. u8 reg, u8 value);
  201. static void pc87360_init_client(struct i2c_client *client, int use_thermistors);
  202. static struct pc87360_data *pc87360_update_device(struct device *dev);
  203. /*
  204. * Driver data (common to all clients)
  205. */
  206. static struct i2c_driver pc87360_driver = {
  207. .owner = THIS_MODULE,
  208. .name = "pc87360",
  209. .flags = I2C_DF_NOTIFY,
  210. .attach_adapter = pc87360_attach_adapter,
  211. .detach_client = pc87360_detach_client,
  212. };
  213. /*
  214. * Sysfs stuff
  215. */
  216. static ssize_t set_fan_min(struct device *dev, const char *buf,
  217. size_t count, int nr)
  218. {
  219. struct i2c_client *client = to_i2c_client(dev);
  220. struct pc87360_data *data = i2c_get_clientdata(client);
  221. long fan_min = simple_strtol(buf, NULL, 10);
  222. down(&data->update_lock);
  223. fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[nr]));
  224. /* If it wouldn't fit, change clock divisor */
  225. while (fan_min > 255
  226. && (data->fan_status[nr] & 0x60) != 0x60) {
  227. fan_min >>= 1;
  228. data->fan[nr] >>= 1;
  229. data->fan_status[nr] += 0x20;
  230. }
  231. data->fan_min[nr] = fan_min > 255 ? 255 : fan_min;
  232. pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_MIN(nr),
  233. data->fan_min[nr]);
  234. /* Write new divider, preserve alarm bits */
  235. pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(nr),
  236. data->fan_status[nr] & 0xF9);
  237. up(&data->update_lock);
  238. return count;
  239. }
  240. #define show_and_set_fan(offset) \
  241. static ssize_t show_fan##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
  242. { \
  243. struct pc87360_data *data = pc87360_update_device(dev); \
  244. return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan[offset-1], \
  245. FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
  246. } \
  247. static ssize_t show_fan##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
  248. { \
  249. struct pc87360_data *data = pc87360_update_device(dev); \
  250. return sprintf(buf, "%u\n", FAN_FROM_REG(data->fan_min[offset-1], \
  251. FAN_DIV_FROM_REG(data->fan_status[offset-1]))); \
  252. } \
  253. static ssize_t show_fan##offset##_div(struct device *dev, struct device_attribute *attr, char *buf) \
  254. { \
  255. struct pc87360_data *data = pc87360_update_device(dev); \
  256. return sprintf(buf, "%u\n", \
  257. FAN_DIV_FROM_REG(data->fan_status[offset-1])); \
  258. } \
  259. static ssize_t show_fan##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
  260. { \
  261. struct pc87360_data *data = pc87360_update_device(dev); \
  262. return sprintf(buf, "%u\n", \
  263. FAN_STATUS_FROM_REG(data->fan_status[offset-1])); \
  264. } \
  265. static ssize_t set_fan##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
  266. size_t count) \
  267. { \
  268. return set_fan_min(dev, buf, count, offset-1); \
  269. } \
  270. static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
  271. show_fan##offset##_input, NULL); \
  272. static DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \
  273. show_fan##offset##_min, set_fan##offset##_min); \
  274. static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
  275. show_fan##offset##_div, NULL); \
  276. static DEVICE_ATTR(fan##offset##_status, S_IRUGO, \
  277. show_fan##offset##_status, NULL);
  278. show_and_set_fan(1)
  279. show_and_set_fan(2)
  280. show_and_set_fan(3)
  281. #define show_and_set_pwm(offset) \
  282. static ssize_t show_pwm##offset(struct device *dev, struct device_attribute *attr, char *buf) \
  283. { \
  284. struct pc87360_data *data = pc87360_update_device(dev); \
  285. return sprintf(buf, "%u\n", \
  286. PWM_FROM_REG(data->pwm[offset-1], \
  287. FAN_CONFIG_INVERT(data->fan_conf, \
  288. offset-1))); \
  289. } \
  290. static ssize_t set_pwm##offset(struct device *dev, struct device_attribute *attr, const char *buf, \
  291. size_t count) \
  292. { \
  293. struct i2c_client *client = to_i2c_client(dev); \
  294. struct pc87360_data *data = i2c_get_clientdata(client); \
  295. long val = simple_strtol(buf, NULL, 10); \
  296. \
  297. down(&data->update_lock); \
  298. data->pwm[offset-1] = PWM_TO_REG(val, \
  299. FAN_CONFIG_INVERT(data->fan_conf, offset-1)); \
  300. pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(offset-1), \
  301. data->pwm[offset-1]); \
  302. up(&data->update_lock); \
  303. return count; \
  304. } \
  305. static DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \
  306. show_pwm##offset, set_pwm##offset);
  307. show_and_set_pwm(1)
  308. show_and_set_pwm(2)
  309. show_and_set_pwm(3)
  310. #define show_and_set_in(offset) \
  311. static ssize_t show_in##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
  312. { \
  313. struct pc87360_data *data = pc87360_update_device(dev); \
  314. return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
  315. data->in_vref)); \
  316. } \
  317. static ssize_t show_in##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
  318. { \
  319. struct pc87360_data *data = pc87360_update_device(dev); \
  320. return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
  321. data->in_vref)); \
  322. } \
  323. static ssize_t show_in##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
  324. { \
  325. struct pc87360_data *data = pc87360_update_device(dev); \
  326. return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
  327. data->in_vref)); \
  328. } \
  329. static ssize_t show_in##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
  330. { \
  331. struct pc87360_data *data = pc87360_update_device(dev); \
  332. return sprintf(buf, "%u\n", data->in_status[offset]); \
  333. } \
  334. static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
  335. size_t count) \
  336. { \
  337. struct i2c_client *client = to_i2c_client(dev); \
  338. struct pc87360_data *data = i2c_get_clientdata(client); \
  339. long val = simple_strtol(buf, NULL, 10); \
  340. \
  341. down(&data->update_lock); \
  342. data->in_min[offset] = IN_TO_REG(val, data->in_vref); \
  343. pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MIN, \
  344. data->in_min[offset]); \
  345. up(&data->update_lock); \
  346. return count; \
  347. } \
  348. static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
  349. size_t count) \
  350. { \
  351. struct i2c_client *client = to_i2c_client(dev); \
  352. struct pc87360_data *data = i2c_get_clientdata(client); \
  353. long val = simple_strtol(buf, NULL, 10); \
  354. \
  355. down(&data->update_lock); \
  356. data->in_max[offset] = IN_TO_REG(val, \
  357. data->in_vref); \
  358. pc87360_write_value(data, LD_IN, offset, PC87365_REG_IN_MAX, \
  359. data->in_max[offset]); \
  360. up(&data->update_lock); \
  361. return count; \
  362. } \
  363. static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
  364. show_in##offset##_input, NULL); \
  365. static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
  366. show_in##offset##_min, set_in##offset##_min); \
  367. static DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
  368. show_in##offset##_max, set_in##offset##_max); \
  369. static DEVICE_ATTR(in##offset##_status, S_IRUGO, \
  370. show_in##offset##_status, NULL);
  371. show_and_set_in(0)
  372. show_and_set_in(1)
  373. show_and_set_in(2)
  374. show_and_set_in(3)
  375. show_and_set_in(4)
  376. show_and_set_in(5)
  377. show_and_set_in(6)
  378. show_and_set_in(7)
  379. show_and_set_in(8)
  380. show_and_set_in(9)
  381. show_and_set_in(10)
  382. #define show_and_set_therm(offset) \
  383. static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
  384. { \
  385. struct pc87360_data *data = pc87360_update_device(dev); \
  386. return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset+7], \
  387. data->in_vref)); \
  388. } \
  389. static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
  390. { \
  391. struct pc87360_data *data = pc87360_update_device(dev); \
  392. return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset+7], \
  393. data->in_vref)); \
  394. } \
  395. static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
  396. { \
  397. struct pc87360_data *data = pc87360_update_device(dev); \
  398. return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset+7], \
  399. data->in_vref)); \
  400. } \
  401. static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
  402. { \
  403. struct pc87360_data *data = pc87360_update_device(dev); \
  404. return sprintf(buf, "%u\n", IN_FROM_REG(data->in_crit[offset-4], \
  405. data->in_vref)); \
  406. } \
  407. static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
  408. { \
  409. struct pc87360_data *data = pc87360_update_device(dev); \
  410. return sprintf(buf, "%u\n", data->in_status[offset+7]); \
  411. } \
  412. static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
  413. size_t count) \
  414. { \
  415. struct i2c_client *client = to_i2c_client(dev); \
  416. struct pc87360_data *data = i2c_get_clientdata(client); \
  417. long val = simple_strtol(buf, NULL, 10); \
  418. \
  419. down(&data->update_lock); \
  420. data->in_min[offset+7] = IN_TO_REG(val, data->in_vref); \
  421. pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MIN, \
  422. data->in_min[offset+7]); \
  423. up(&data->update_lock); \
  424. return count; \
  425. } \
  426. static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
  427. size_t count) \
  428. { \
  429. struct i2c_client *client = to_i2c_client(dev); \
  430. struct pc87360_data *data = i2c_get_clientdata(client); \
  431. long val = simple_strtol(buf, NULL, 10); \
  432. \
  433. down(&data->update_lock); \
  434. data->in_max[offset+7] = IN_TO_REG(val, data->in_vref); \
  435. pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_MAX, \
  436. data->in_max[offset+7]); \
  437. up(&data->update_lock); \
  438. return count; \
  439. } \
  440. static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
  441. size_t count) \
  442. { \
  443. struct i2c_client *client = to_i2c_client(dev); \
  444. struct pc87360_data *data = i2c_get_clientdata(client); \
  445. long val = simple_strtol(buf, NULL, 10); \
  446. \
  447. down(&data->update_lock); \
  448. data->in_crit[offset-4] = IN_TO_REG(val, data->in_vref); \
  449. pc87360_write_value(data, LD_IN, offset+7, PC87365_REG_TEMP_CRIT, \
  450. data->in_crit[offset-4]); \
  451. up(&data->update_lock); \
  452. return count; \
  453. } \
  454. static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
  455. show_temp##offset##_input, NULL); \
  456. static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
  457. show_temp##offset##_min, set_temp##offset##_min); \
  458. static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
  459. show_temp##offset##_max, set_temp##offset##_max); \
  460. static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
  461. show_temp##offset##_crit, set_temp##offset##_crit); \
  462. static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
  463. show_temp##offset##_status, NULL);
  464. show_and_set_therm(4)
  465. show_and_set_therm(5)
  466. show_and_set_therm(6)
  467. static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
  468. {
  469. struct pc87360_data *data = pc87360_update_device(dev);
  470. return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
  471. }
  472. static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
  473. static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
  474. {
  475. struct pc87360_data *data = pc87360_update_device(dev);
  476. return sprintf(buf, "%u\n", data->vrm);
  477. }
  478. static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  479. {
  480. struct i2c_client *client = to_i2c_client(dev);
  481. struct pc87360_data *data = i2c_get_clientdata(client);
  482. data->vrm = simple_strtoul(buf, NULL, 10);
  483. return count;
  484. }
  485. static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
  486. static ssize_t show_in_alarms(struct device *dev, struct device_attribute *attr, char *buf)
  487. {
  488. struct pc87360_data *data = pc87360_update_device(dev);
  489. return sprintf(buf, "%u\n", data->in_alarms);
  490. }
  491. static DEVICE_ATTR(alarms_in, S_IRUGO, show_in_alarms, NULL);
  492. #define show_and_set_temp(offset) \
  493. static ssize_t show_temp##offset##_input(struct device *dev, struct device_attribute *attr, char *buf) \
  494. { \
  495. struct pc87360_data *data = pc87360_update_device(dev); \
  496. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
  497. } \
  498. static ssize_t show_temp##offset##_min(struct device *dev, struct device_attribute *attr, char *buf) \
  499. { \
  500. struct pc87360_data *data = pc87360_update_device(dev); \
  501. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[offset-1])); \
  502. } \
  503. static ssize_t show_temp##offset##_max(struct device *dev, struct device_attribute *attr, char *buf) \
  504. { \
  505. struct pc87360_data *data = pc87360_update_device(dev); \
  506. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[offset-1])); \
  507. }\
  508. static ssize_t show_temp##offset##_crit(struct device *dev, struct device_attribute *attr, char *buf) \
  509. { \
  510. struct pc87360_data *data = pc87360_update_device(dev); \
  511. return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[offset-1])); \
  512. }\
  513. static ssize_t show_temp##offset##_status(struct device *dev, struct device_attribute *attr, char *buf) \
  514. { \
  515. struct pc87360_data *data = pc87360_update_device(dev); \
  516. return sprintf(buf, "%d\n", data->temp_status[offset-1]); \
  517. }\
  518. static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribute *attr, const char *buf, \
  519. size_t count) \
  520. { \
  521. struct i2c_client *client = to_i2c_client(dev); \
  522. struct pc87360_data *data = i2c_get_clientdata(client); \
  523. long val = simple_strtol(buf, NULL, 10); \
  524. \
  525. down(&data->update_lock); \
  526. data->temp_min[offset-1] = TEMP_TO_REG(val); \
  527. pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MIN, \
  528. data->temp_min[offset-1]); \
  529. up(&data->update_lock); \
  530. return count; \
  531. } \
  532. static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
  533. size_t count) \
  534. { \
  535. struct i2c_client *client = to_i2c_client(dev); \
  536. struct pc87360_data *data = i2c_get_clientdata(client); \
  537. long val = simple_strtol(buf, NULL, 10); \
  538. \
  539. down(&data->update_lock); \
  540. data->temp_max[offset-1] = TEMP_TO_REG(val); \
  541. pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_MAX, \
  542. data->temp_max[offset-1]); \
  543. up(&data->update_lock); \
  544. return count; \
  545. } \
  546. static ssize_t set_temp##offset##_crit(struct device *dev, struct device_attribute *attr, const char *buf, \
  547. size_t count) \
  548. { \
  549. struct i2c_client *client = to_i2c_client(dev); \
  550. struct pc87360_data *data = i2c_get_clientdata(client); \
  551. long val = simple_strtol(buf, NULL, 10); \
  552. \
  553. down(&data->update_lock); \
  554. data->temp_crit[offset-1] = TEMP_TO_REG(val); \
  555. pc87360_write_value(data, LD_TEMP, offset-1, PC87365_REG_TEMP_CRIT, \
  556. data->temp_crit[offset-1]); \
  557. up(&data->update_lock); \
  558. return count; \
  559. } \
  560. static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
  561. show_temp##offset##_input, NULL); \
  562. static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
  563. show_temp##offset##_min, set_temp##offset##_min); \
  564. static DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
  565. show_temp##offset##_max, set_temp##offset##_max); \
  566. static DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
  567. show_temp##offset##_crit, set_temp##offset##_crit); \
  568. static DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
  569. show_temp##offset##_status, NULL);
  570. show_and_set_temp(1)
  571. show_and_set_temp(2)
  572. show_and_set_temp(3)
  573. static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
  574. {
  575. struct pc87360_data *data = pc87360_update_device(dev);
  576. return sprintf(buf, "%u\n", data->temp_alarms);
  577. }
  578. static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
  579. /*
  580. * Device detection, registration and update
  581. */
  582. static int pc87360_attach_adapter(struct i2c_adapter *adapter)
  583. {
  584. return i2c_detect(adapter, &addr_data, pc87360_detect);
  585. }
  586. static int pc87360_find(int sioaddr, u8 *devid, int *address)
  587. {
  588. u16 val;
  589. int i;
  590. int nrdev; /* logical device count */
  591. /* No superio_enter */
  592. /* Identify device */
  593. val = superio_inb(sioaddr, DEVID);
  594. switch (val) {
  595. case 0xE1: /* PC87360 */
  596. case 0xE8: /* PC87363 */
  597. case 0xE4: /* PC87364 */
  598. nrdev = 1;
  599. break;
  600. case 0xE5: /* PC87365 */
  601. case 0xE9: /* PC87366 */
  602. nrdev = 3;
  603. break;
  604. default:
  605. superio_exit(sioaddr);
  606. return -ENODEV;
  607. }
  608. /* Remember the device id */
  609. *devid = val;
  610. for (i = 0; i < nrdev; i++) {
  611. /* select logical device */
  612. superio_outb(sioaddr, DEV, logdev[i]);
  613. val = superio_inb(sioaddr, ACT);
  614. if (!(val & 0x01)) {
  615. printk(KERN_INFO "pc87360: Device 0x%02x not "
  616. "activated\n", logdev[i]);
  617. continue;
  618. }
  619. val = (superio_inb(sioaddr, BASE) << 8)
  620. | superio_inb(sioaddr, BASE + 1);
  621. if (!val) {
  622. printk(KERN_INFO "pc87360: Base address not set for "
  623. "device 0x%02x\n", logdev[i]);
  624. continue;
  625. }
  626. address[i] = val;
  627. if (i==0) { /* Fans */
  628. confreg[0] = superio_inb(sioaddr, 0xF0);
  629. confreg[1] = superio_inb(sioaddr, 0xF1);
  630. #ifdef DEBUG
  631. printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
  632. "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
  633. (confreg[0]>>3)&1, (confreg[0]>>4)&1);
  634. printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
  635. "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
  636. (confreg[0]>>6)&1, (confreg[0]>>7)&1);
  637. printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
  638. "ctrl=%d inv=%d\n", confreg[1]&1,
  639. (confreg[1]>>1)&1, (confreg[1]>>2)&1);
  640. #endif
  641. } else if (i==1) { /* Voltages */
  642. /* Are we using thermistors? */
  643. if (*devid == 0xE9) { /* PC87366 */
  644. /* These registers are not logical-device
  645. specific, just that we won't need them if
  646. we don't use the VLM device */
  647. confreg[2] = superio_inb(sioaddr, 0x2B);
  648. confreg[3] = superio_inb(sioaddr, 0x25);
  649. if (confreg[2] & 0x40) {
  650. printk(KERN_INFO "pc87360: Using "
  651. "thermistors for temperature "
  652. "monitoring\n");
  653. }
  654. if (confreg[3] & 0xE0) {
  655. printk(KERN_INFO "pc87360: VID "
  656. "inputs routed (mode %u)\n",
  657. confreg[3] >> 5);
  658. }
  659. }
  660. }
  661. }
  662. superio_exit(sioaddr);
  663. return 0;
  664. }
  665. /* We don't really care about the address.
  666. Read from extra_isa instead. */
  667. int pc87360_detect(struct i2c_adapter *adapter, int address, int kind)
  668. {
  669. int i;
  670. struct i2c_client *new_client;
  671. struct pc87360_data *data;
  672. int err = 0;
  673. const char *name = "pc87360";
  674. int use_thermistors = 0;
  675. if (!i2c_is_isa_adapter(adapter))
  676. return -ENODEV;
  677. if (!(data = kmalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
  678. return -ENOMEM;
  679. memset(data, 0x00, sizeof(struct pc87360_data));
  680. new_client = &data->client;
  681. i2c_set_clientdata(new_client, data);
  682. new_client->addr = address;
  683. init_MUTEX(&data->lock);
  684. new_client->adapter = adapter;
  685. new_client->driver = &pc87360_driver;
  686. new_client->flags = 0;
  687. data->fannr = 2;
  688. data->innr = 0;
  689. data->tempnr = 0;
  690. switch (devid) {
  691. case 0xe8:
  692. name = "pc87363";
  693. break;
  694. case 0xe4:
  695. name = "pc87364";
  696. data->fannr = 3;
  697. break;
  698. case 0xe5:
  699. name = "pc87365";
  700. data->fannr = extra_isa[0] ? 3 : 0;
  701. data->innr = extra_isa[1] ? 11 : 0;
  702. data->tempnr = extra_isa[2] ? 2 : 0;
  703. break;
  704. case 0xe9:
  705. name = "pc87366";
  706. data->fannr = extra_isa[0] ? 3 : 0;
  707. data->innr = extra_isa[1] ? 14 : 0;
  708. data->tempnr = extra_isa[2] ? 3 : 0;
  709. break;
  710. }
  711. strcpy(new_client->name, name);
  712. data->valid = 0;
  713. init_MUTEX(&data->update_lock);
  714. for (i = 0; i < 3; i++) {
  715. if (((data->address[i] = extra_isa[i]))
  716. && !request_region(extra_isa[i], PC87360_EXTENT,
  717. pc87360_driver.name)) {
  718. dev_err(&new_client->dev, "Region 0x%x-0x%x already "
  719. "in use!\n", extra_isa[i],
  720. extra_isa[i]+PC87360_EXTENT-1);
  721. for (i--; i >= 0; i--)
  722. release_region(extra_isa[i], PC87360_EXTENT);
  723. err = -EBUSY;
  724. goto ERROR1;
  725. }
  726. }
  727. /* Retrieve the fans configuration from Super-I/O space */
  728. if (data->fannr)
  729. data->fan_conf = confreg[0] | (confreg[1] << 8);
  730. if ((err = i2c_attach_client(new_client)))
  731. goto ERROR2;
  732. /* Use the correct reference voltage
  733. Unless both the VLM and the TMS logical devices agree to
  734. use an external Vref, the internal one is used. */
  735. if (data->innr) {
  736. i = pc87360_read_value(data, LD_IN, NO_BANK,
  737. PC87365_REG_IN_CONFIG);
  738. if (data->tempnr) {
  739. i &= pc87360_read_value(data, LD_TEMP, NO_BANK,
  740. PC87365_REG_TEMP_CONFIG);
  741. }
  742. data->in_vref = (i&0x02) ? 3025 : 2966;
  743. dev_dbg(&new_client->dev, "Using %s reference voltage\n",
  744. (i&0x02) ? "external" : "internal");
  745. data->vid_conf = confreg[3];
  746. data->vrm = 90;
  747. }
  748. /* Fan clock dividers may be needed before any data is read */
  749. for (i = 0; i < data->fannr; i++) {
  750. if (FAN_CONFIG_MONITOR(data->fan_conf, i))
  751. data->fan_status[i] = pc87360_read_value(data,
  752. LD_FAN, NO_BANK,
  753. PC87360_REG_FAN_STATUS(i));
  754. }
  755. if (init > 0) {
  756. if (devid == 0xe9 && data->address[1]) /* PC87366 */
  757. use_thermistors = confreg[2] & 0x40;
  758. pc87360_init_client(new_client, use_thermistors);
  759. }
  760. /* Register sysfs hooks */
  761. if (data->innr) {
  762. device_create_file(&new_client->dev, &dev_attr_in0_input);
  763. device_create_file(&new_client->dev, &dev_attr_in1_input);
  764. device_create_file(&new_client->dev, &dev_attr_in2_input);
  765. device_create_file(&new_client->dev, &dev_attr_in3_input);
  766. device_create_file(&new_client->dev, &dev_attr_in4_input);
  767. device_create_file(&new_client->dev, &dev_attr_in5_input);
  768. device_create_file(&new_client->dev, &dev_attr_in6_input);
  769. device_create_file(&new_client->dev, &dev_attr_in7_input);
  770. device_create_file(&new_client->dev, &dev_attr_in8_input);
  771. device_create_file(&new_client->dev, &dev_attr_in9_input);
  772. device_create_file(&new_client->dev, &dev_attr_in10_input);
  773. device_create_file(&new_client->dev, &dev_attr_in0_min);
  774. device_create_file(&new_client->dev, &dev_attr_in1_min);
  775. device_create_file(&new_client->dev, &dev_attr_in2_min);
  776. device_create_file(&new_client->dev, &dev_attr_in3_min);
  777. device_create_file(&new_client->dev, &dev_attr_in4_min);
  778. device_create_file(&new_client->dev, &dev_attr_in5_min);
  779. device_create_file(&new_client->dev, &dev_attr_in6_min);
  780. device_create_file(&new_client->dev, &dev_attr_in7_min);
  781. device_create_file(&new_client->dev, &dev_attr_in8_min);
  782. device_create_file(&new_client->dev, &dev_attr_in9_min);
  783. device_create_file(&new_client->dev, &dev_attr_in10_min);
  784. device_create_file(&new_client->dev, &dev_attr_in0_max);
  785. device_create_file(&new_client->dev, &dev_attr_in1_max);
  786. device_create_file(&new_client->dev, &dev_attr_in2_max);
  787. device_create_file(&new_client->dev, &dev_attr_in3_max);
  788. device_create_file(&new_client->dev, &dev_attr_in4_max);
  789. device_create_file(&new_client->dev, &dev_attr_in5_max);
  790. device_create_file(&new_client->dev, &dev_attr_in6_max);
  791. device_create_file(&new_client->dev, &dev_attr_in7_max);
  792. device_create_file(&new_client->dev, &dev_attr_in8_max);
  793. device_create_file(&new_client->dev, &dev_attr_in9_max);
  794. device_create_file(&new_client->dev, &dev_attr_in10_max);
  795. device_create_file(&new_client->dev, &dev_attr_in0_status);
  796. device_create_file(&new_client->dev, &dev_attr_in1_status);
  797. device_create_file(&new_client->dev, &dev_attr_in2_status);
  798. device_create_file(&new_client->dev, &dev_attr_in3_status);
  799. device_create_file(&new_client->dev, &dev_attr_in4_status);
  800. device_create_file(&new_client->dev, &dev_attr_in5_status);
  801. device_create_file(&new_client->dev, &dev_attr_in6_status);
  802. device_create_file(&new_client->dev, &dev_attr_in7_status);
  803. device_create_file(&new_client->dev, &dev_attr_in8_status);
  804. device_create_file(&new_client->dev, &dev_attr_in9_status);
  805. device_create_file(&new_client->dev, &dev_attr_in10_status);
  806. device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
  807. device_create_file(&new_client->dev, &dev_attr_vrm);
  808. device_create_file(&new_client->dev, &dev_attr_alarms_in);
  809. }
  810. if (data->tempnr) {
  811. device_create_file(&new_client->dev, &dev_attr_temp1_input);
  812. device_create_file(&new_client->dev, &dev_attr_temp2_input);
  813. device_create_file(&new_client->dev, &dev_attr_temp1_min);
  814. device_create_file(&new_client->dev, &dev_attr_temp2_min);
  815. device_create_file(&new_client->dev, &dev_attr_temp1_max);
  816. device_create_file(&new_client->dev, &dev_attr_temp2_max);
  817. device_create_file(&new_client->dev, &dev_attr_temp1_crit);
  818. device_create_file(&new_client->dev, &dev_attr_temp2_crit);
  819. device_create_file(&new_client->dev, &dev_attr_temp1_status);
  820. device_create_file(&new_client->dev, &dev_attr_temp2_status);
  821. device_create_file(&new_client->dev, &dev_attr_alarms_temp);
  822. }
  823. if (data->tempnr == 3) {
  824. device_create_file(&new_client->dev, &dev_attr_temp3_input);
  825. device_create_file(&new_client->dev, &dev_attr_temp3_min);
  826. device_create_file(&new_client->dev, &dev_attr_temp3_max);
  827. device_create_file(&new_client->dev, &dev_attr_temp3_crit);
  828. device_create_file(&new_client->dev, &dev_attr_temp3_status);
  829. }
  830. if (data->innr == 14) {
  831. device_create_file(&new_client->dev, &dev_attr_temp4_input);
  832. device_create_file(&new_client->dev, &dev_attr_temp5_input);
  833. device_create_file(&new_client->dev, &dev_attr_temp6_input);
  834. device_create_file(&new_client->dev, &dev_attr_temp4_min);
  835. device_create_file(&new_client->dev, &dev_attr_temp5_min);
  836. device_create_file(&new_client->dev, &dev_attr_temp6_min);
  837. device_create_file(&new_client->dev, &dev_attr_temp4_max);
  838. device_create_file(&new_client->dev, &dev_attr_temp5_max);
  839. device_create_file(&new_client->dev, &dev_attr_temp6_max);
  840. device_create_file(&new_client->dev, &dev_attr_temp4_crit);
  841. device_create_file(&new_client->dev, &dev_attr_temp5_crit);
  842. device_create_file(&new_client->dev, &dev_attr_temp6_crit);
  843. device_create_file(&new_client->dev, &dev_attr_temp4_status);
  844. device_create_file(&new_client->dev, &dev_attr_temp5_status);
  845. device_create_file(&new_client->dev, &dev_attr_temp6_status);
  846. }
  847. if (data->fannr) {
  848. if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) {
  849. device_create_file(&new_client->dev,
  850. &dev_attr_fan1_input);
  851. device_create_file(&new_client->dev,
  852. &dev_attr_fan1_min);
  853. device_create_file(&new_client->dev,
  854. &dev_attr_fan1_div);
  855. device_create_file(&new_client->dev,
  856. &dev_attr_fan1_status);
  857. }
  858. if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) {
  859. device_create_file(&new_client->dev,
  860. &dev_attr_fan2_input);
  861. device_create_file(&new_client->dev,
  862. &dev_attr_fan2_min);
  863. device_create_file(&new_client->dev,
  864. &dev_attr_fan2_div);
  865. device_create_file(&new_client->dev,
  866. &dev_attr_fan2_status);
  867. }
  868. if (FAN_CONFIG_CONTROL(data->fan_conf, 0))
  869. device_create_file(&new_client->dev, &dev_attr_pwm1);
  870. if (FAN_CONFIG_CONTROL(data->fan_conf, 1))
  871. device_create_file(&new_client->dev, &dev_attr_pwm2);
  872. }
  873. if (data->fannr == 3) {
  874. if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) {
  875. device_create_file(&new_client->dev,
  876. &dev_attr_fan3_input);
  877. device_create_file(&new_client->dev,
  878. &dev_attr_fan3_min);
  879. device_create_file(&new_client->dev,
  880. &dev_attr_fan3_div);
  881. device_create_file(&new_client->dev,
  882. &dev_attr_fan3_status);
  883. }
  884. if (FAN_CONFIG_CONTROL(data->fan_conf, 2))
  885. device_create_file(&new_client->dev, &dev_attr_pwm3);
  886. }
  887. return 0;
  888. ERROR2:
  889. for (i = 0; i < 3; i++) {
  890. if (data->address[i]) {
  891. release_region(data->address[i], PC87360_EXTENT);
  892. }
  893. }
  894. ERROR1:
  895. kfree(data);
  896. return err;
  897. }
  898. static int pc87360_detach_client(struct i2c_client *client)
  899. {
  900. struct pc87360_data *data = i2c_get_clientdata(client);
  901. int i;
  902. if ((i = i2c_detach_client(client))) {
  903. dev_err(&client->dev, "Client deregistration failed, "
  904. "client not detached.\n");
  905. return i;
  906. }
  907. for (i = 0; i < 3; i++) {
  908. if (data->address[i]) {
  909. release_region(data->address[i], PC87360_EXTENT);
  910. }
  911. }
  912. kfree(data);
  913. return 0;
  914. }
  915. /* ldi is the logical device index
  916. bank is for voltages and temperatures only */
  917. static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
  918. u8 reg)
  919. {
  920. int res;
  921. down(&(data->lock));
  922. if (bank != NO_BANK)
  923. outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
  924. res = inb_p(data->address[ldi] + reg);
  925. up(&(data->lock));
  926. return res;
  927. }
  928. static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
  929. u8 reg, u8 value)
  930. {
  931. down(&(data->lock));
  932. if (bank != NO_BANK)
  933. outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
  934. outb_p(value, data->address[ldi] + reg);
  935. up(&(data->lock));
  936. }
  937. static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
  938. {
  939. struct pc87360_data *data = i2c_get_clientdata(client);
  940. int i, nr;
  941. const u8 init_in[14] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 3, 1, 2, 2, 2 };
  942. const u8 init_temp[3] = { 2, 2, 1 };
  943. u8 reg;
  944. if (init >= 2 && data->innr) {
  945. reg = pc87360_read_value(data, LD_IN, NO_BANK,
  946. PC87365_REG_IN_CONVRATE);
  947. dev_info(&client->dev, "VLM conversion set to"
  948. "1s period, 160us delay\n");
  949. pc87360_write_value(data, LD_IN, NO_BANK,
  950. PC87365_REG_IN_CONVRATE,
  951. (reg & 0xC0) | 0x11);
  952. }
  953. nr = data->innr < 11 ? data->innr : 11;
  954. for (i=0; i<nr; i++) {
  955. if (init >= init_in[i]) {
  956. /* Forcibly enable voltage channel */
  957. reg = pc87360_read_value(data, LD_IN, i,
  958. PC87365_REG_IN_STATUS);
  959. if (!(reg & 0x01)) {
  960. dev_dbg(&client->dev, "Forcibly "
  961. "enabling in%d\n", i);
  962. pc87360_write_value(data, LD_IN, i,
  963. PC87365_REG_IN_STATUS,
  964. (reg & 0x68) | 0x87);
  965. }
  966. }
  967. }
  968. /* We can't blindly trust the Super-I/O space configuration bit,
  969. most BIOS won't set it properly */
  970. for (i=11; i<data->innr; i++) {
  971. reg = pc87360_read_value(data, LD_IN, i,
  972. PC87365_REG_TEMP_STATUS);
  973. use_thermistors = use_thermistors || (reg & 0x01);
  974. }
  975. i = use_thermistors ? 2 : 0;
  976. for (; i<data->tempnr; i++) {
  977. if (init >= init_temp[i]) {
  978. /* Forcibly enable temperature channel */
  979. reg = pc87360_read_value(data, LD_TEMP, i,
  980. PC87365_REG_TEMP_STATUS);
  981. if (!(reg & 0x01)) {
  982. dev_dbg(&client->dev, "Forcibly "
  983. "enabling temp%d\n", i+1);
  984. pc87360_write_value(data, LD_TEMP, i,
  985. PC87365_REG_TEMP_STATUS,
  986. 0xCF);
  987. }
  988. }
  989. }
  990. if (use_thermistors) {
  991. for (i=11; i<data->innr; i++) {
  992. if (init >= init_in[i]) {
  993. /* The pin may already be used by thermal
  994. diodes */
  995. reg = pc87360_read_value(data, LD_TEMP,
  996. (i-11)/2, PC87365_REG_TEMP_STATUS);
  997. if (reg & 0x01) {
  998. dev_dbg(&client->dev, "Skipping "
  999. "temp%d, pin already in use "
  1000. "by temp%d\n", i-7, (i-11)/2);
  1001. continue;
  1002. }
  1003. /* Forcibly enable thermistor channel */
  1004. reg = pc87360_read_value(data, LD_IN, i,
  1005. PC87365_REG_IN_STATUS);
  1006. if (!(reg & 0x01)) {
  1007. dev_dbg(&client->dev, "Forcibly "
  1008. "enabling temp%d\n", i-7);
  1009. pc87360_write_value(data, LD_IN, i,
  1010. PC87365_REG_TEMP_STATUS,
  1011. (reg & 0x60) | 0x8F);
  1012. }
  1013. }
  1014. }
  1015. }
  1016. if (data->innr) {
  1017. reg = pc87360_read_value(data, LD_IN, NO_BANK,
  1018. PC87365_REG_IN_CONFIG);
  1019. if (reg & 0x01) {
  1020. dev_dbg(&client->dev, "Forcibly "
  1021. "enabling monitoring (VLM)\n");
  1022. pc87360_write_value(data, LD_IN, NO_BANK,
  1023. PC87365_REG_IN_CONFIG,
  1024. reg & 0xFE);
  1025. }
  1026. }
  1027. if (data->tempnr) {
  1028. reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
  1029. PC87365_REG_TEMP_CONFIG);
  1030. if (reg & 0x01) {
  1031. dev_dbg(&client->dev, "Forcibly enabling "
  1032. "monitoring (TMS)\n");
  1033. pc87360_write_value(data, LD_TEMP, NO_BANK,
  1034. PC87365_REG_TEMP_CONFIG,
  1035. reg & 0xFE);
  1036. }
  1037. if (init >= 2) {
  1038. /* Chip config as documented by National Semi. */
  1039. pc87360_write_value(data, LD_TEMP, 0xF, 0xA, 0x08);
  1040. /* We voluntarily omit the bank here, in case the
  1041. sequence itself matters. It shouldn't be a problem,
  1042. since nobody else is supposed to access the
  1043. device at that point. */
  1044. pc87360_write_value(data, LD_TEMP, NO_BANK, 0xB, 0x04);
  1045. pc87360_write_value(data, LD_TEMP, NO_BANK, 0xC, 0x35);
  1046. pc87360_write_value(data, LD_TEMP, NO_BANK, 0xD, 0x05);
  1047. pc87360_write_value(data, LD_TEMP, NO_BANK, 0xE, 0x05);
  1048. }
  1049. }
  1050. }
  1051. static void pc87360_autodiv(struct i2c_client *client, int nr)
  1052. {
  1053. struct pc87360_data *data = i2c_get_clientdata(client);
  1054. u8 old_min = data->fan_min[nr];
  1055. /* Increase clock divider if needed and possible */
  1056. if ((data->fan_status[nr] & 0x04) /* overflow flag */
  1057. || (data->fan[nr] >= 224)) { /* next to overflow */
  1058. if ((data->fan_status[nr] & 0x60) != 0x60) {
  1059. data->fan_status[nr] += 0x20;
  1060. data->fan_min[nr] >>= 1;
  1061. data->fan[nr] >>= 1;
  1062. dev_dbg(&client->dev, "Increasing "
  1063. "clock divider to %d for fan %d\n",
  1064. FAN_DIV_FROM_REG(data->fan_status[nr]), nr+1);
  1065. }
  1066. } else {
  1067. /* Decrease clock divider if possible */
  1068. while (!(data->fan_min[nr] & 0x80) /* min "nails" divider */
  1069. && data->fan[nr] < 85 /* bad accuracy */
  1070. && (data->fan_status[nr] & 0x60) != 0x00) {
  1071. data->fan_status[nr] -= 0x20;
  1072. data->fan_min[nr] <<= 1;
  1073. data->fan[nr] <<= 1;
  1074. dev_dbg(&client->dev, "Decreasing "
  1075. "clock divider to %d for fan %d\n",
  1076. FAN_DIV_FROM_REG(data->fan_status[nr]),
  1077. nr+1);
  1078. }
  1079. }
  1080. /* Write new fan min if it changed */
  1081. if (old_min != data->fan_min[nr]) {
  1082. pc87360_write_value(data, LD_FAN, NO_BANK,
  1083. PC87360_REG_FAN_MIN(nr),
  1084. data->fan_min[nr]);
  1085. }
  1086. }
  1087. static struct pc87360_data *pc87360_update_device(struct device *dev)
  1088. {
  1089. struct i2c_client *client = to_i2c_client(dev);
  1090. struct pc87360_data *data = i2c_get_clientdata(client);
  1091. u8 i;
  1092. down(&data->update_lock);
  1093. if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
  1094. dev_dbg(&client->dev, "Data update\n");
  1095. /* Fans */
  1096. for (i = 0; i < data->fannr; i++) {
  1097. if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
  1098. data->fan_status[i] =
  1099. pc87360_read_value(data, LD_FAN,
  1100. NO_BANK, PC87360_REG_FAN_STATUS(i));
  1101. data->fan[i] = pc87360_read_value(data, LD_FAN,
  1102. NO_BANK, PC87360_REG_FAN(i));
  1103. data->fan_min[i] = pc87360_read_value(data,
  1104. LD_FAN, NO_BANK,
  1105. PC87360_REG_FAN_MIN(i));
  1106. /* Change clock divider if needed */
  1107. pc87360_autodiv(client, i);
  1108. /* Clear bits and write new divider */
  1109. pc87360_write_value(data, LD_FAN, NO_BANK,
  1110. PC87360_REG_FAN_STATUS(i),
  1111. data->fan_status[i]);
  1112. }
  1113. if (FAN_CONFIG_CONTROL(data->fan_conf, i))
  1114. data->pwm[i] = pc87360_read_value(data, LD_FAN,
  1115. NO_BANK, PC87360_REG_PWM(i));
  1116. }
  1117. /* Voltages */
  1118. for (i = 0; i < data->innr; i++) {
  1119. data->in_status[i] = pc87360_read_value(data, LD_IN, i,
  1120. PC87365_REG_IN_STATUS);
  1121. /* Clear bits */
  1122. pc87360_write_value(data, LD_IN, i,
  1123. PC87365_REG_IN_STATUS,
  1124. data->in_status[i]);
  1125. if ((data->in_status[i] & 0x81) == 0x81) {
  1126. data->in[i] = pc87360_read_value(data, LD_IN,
  1127. i, PC87365_REG_IN);
  1128. }
  1129. if (data->in_status[i] & 0x01) {
  1130. data->in_min[i] = pc87360_read_value(data,
  1131. LD_IN, i,
  1132. PC87365_REG_IN_MIN);
  1133. data->in_max[i] = pc87360_read_value(data,
  1134. LD_IN, i,
  1135. PC87365_REG_IN_MAX);
  1136. if (i >= 11)
  1137. data->in_crit[i-11] =
  1138. pc87360_read_value(data, LD_IN,
  1139. i, PC87365_REG_TEMP_CRIT);
  1140. }
  1141. }
  1142. if (data->innr) {
  1143. data->in_alarms = pc87360_read_value(data, LD_IN,
  1144. NO_BANK, PC87365_REG_IN_ALARMS1)
  1145. | ((pc87360_read_value(data, LD_IN,
  1146. NO_BANK, PC87365_REG_IN_ALARMS2)
  1147. & 0x07) << 8);
  1148. data->vid = (data->vid_conf & 0xE0) ?
  1149. pc87360_read_value(data, LD_IN,
  1150. NO_BANK, PC87365_REG_VID) : 0x1F;
  1151. }
  1152. /* Temperatures */
  1153. for (i = 0; i < data->tempnr; i++) {
  1154. data->temp_status[i] = pc87360_read_value(data,
  1155. LD_TEMP, i,
  1156. PC87365_REG_TEMP_STATUS);
  1157. /* Clear bits */
  1158. pc87360_write_value(data, LD_TEMP, i,
  1159. PC87365_REG_TEMP_STATUS,
  1160. data->temp_status[i]);
  1161. if ((data->temp_status[i] & 0x81) == 0x81) {
  1162. data->temp[i] = pc87360_read_value(data,
  1163. LD_TEMP, i,
  1164. PC87365_REG_TEMP);
  1165. }
  1166. if (data->temp_status[i] & 0x01) {
  1167. data->temp_min[i] = pc87360_read_value(data,
  1168. LD_TEMP, i,
  1169. PC87365_REG_TEMP_MIN);
  1170. data->temp_max[i] = pc87360_read_value(data,
  1171. LD_TEMP, i,
  1172. PC87365_REG_TEMP_MAX);
  1173. data->temp_crit[i] = pc87360_read_value(data,
  1174. LD_TEMP, i,
  1175. PC87365_REG_TEMP_CRIT);
  1176. }
  1177. }
  1178. if (data->tempnr) {
  1179. data->temp_alarms = pc87360_read_value(data, LD_TEMP,
  1180. NO_BANK, PC87365_REG_TEMP_ALARMS)
  1181. & 0x3F;
  1182. }
  1183. data->last_updated = jiffies;
  1184. data->valid = 1;
  1185. }
  1186. up(&data->update_lock);
  1187. return data;
  1188. }
  1189. static int __init pc87360_init(void)
  1190. {
  1191. int i;
  1192. if (pc87360_find(0x2e, &devid, extra_isa)
  1193. && pc87360_find(0x4e, &devid, extra_isa)) {
  1194. printk(KERN_WARNING "pc87360: PC8736x not detected, "
  1195. "module not inserted.\n");
  1196. return -ENODEV;
  1197. }
  1198. /* Arbitrarily pick one of the addresses */
  1199. for (i = 0; i < 3; i++) {
  1200. if (extra_isa[i] != 0x0000) {
  1201. normal_isa[0] = extra_isa[i];
  1202. break;
  1203. }
  1204. }
  1205. if (normal_isa[0] == 0x0000) {
  1206. printk(KERN_WARNING "pc87360: No active logical device, "
  1207. "module not inserted.\n");
  1208. return -ENODEV;
  1209. }
  1210. return i2c_add_driver(&pc87360_driver);
  1211. }
  1212. static void __exit pc87360_exit(void)
  1213. {
  1214. i2c_del_driver(&pc87360_driver);
  1215. }
  1216. MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
  1217. MODULE_DESCRIPTION("PC8736x hardware monitor");
  1218. MODULE_LICENSE("GPL");
  1219. module_init(pc87360_init);
  1220. module_exit(pc87360_exit);