f71882fg.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761
  1. /***************************************************************************
  2. * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
  3. * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include <linux/module.h>
  21. #include <linux/init.h>
  22. #include <linux/slab.h>
  23. #include <linux/jiffies.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/hwmon.h>
  26. #include <linux/hwmon-sysfs.h>
  27. #include <linux/err.h>
  28. #include <linux/mutex.h>
  29. #include <linux/io.h>
  30. #define DRVNAME "f71882fg"
  31. #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
  32. #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
  33. #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
  34. #define SIO_REG_LDSEL 0x07 /* Logical device select */
  35. #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
  36. #define SIO_REG_DEVREV 0x22 /* Device revision */
  37. #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
  38. #define SIO_REG_ENABLE 0x30 /* Logical device enable */
  39. #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
  40. #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
  41. #define SIO_F71862_ID 0x0601 /* Chipset ID */
  42. #define SIO_F71882_ID 0x0541 /* Chipset ID */
  43. #define REGION_LENGTH 8
  44. #define ADDR_REG_OFFSET 5
  45. #define DATA_REG_OFFSET 6
  46. #define F71882FG_REG_PECI 0x0A
  47. #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
  48. #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
  49. #define F71882FG_REG_IN(nr) (0x20 + (nr))
  50. #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
  51. #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
  52. #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
  53. #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
  54. #define F71882FG_REG_FAN_STATUS 0x92
  55. #define F71882FG_REG_FAN_BEEP 0x93
  56. #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
  57. #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
  58. #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
  59. #define F71882FG_REG_TEMP_STATUS 0x62
  60. #define F71882FG_REG_TEMP_BEEP 0x63
  61. #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
  62. #define F71882FG_REG_TEMP_TYPE 0x6B
  63. #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
  64. #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
  65. #define F71882FG_REG_PWM_TYPE 0x94
  66. #define F71882FG_REG_PWM_ENABLE 0x96
  67. #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
  68. #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
  69. #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
  70. #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
  71. #define F71882FG_REG_START 0x01
  72. #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
  73. static unsigned short force_id;
  74. module_param(force_id, ushort, 0);
  75. MODULE_PARM_DESC(force_id, "Override the detected device ID");
  76. static int fan_mode[4] = { 0, 0, 0, 0 };
  77. module_param_array(fan_mode, int, NULL, 0644);
  78. MODULE_PARM_DESC(fan_mode, "List of fan control modes (f71882fg only) "
  79. "(0=don't change, 1=pwm, 2=rpm)\n"
  80. "Note: this needs a write to pwm#_enable to take effect");
  81. enum chips { f71862fg, f71882fg };
  82. static const char *f71882fg_names[] = {
  83. "f71862fg",
  84. "f71882fg",
  85. };
  86. static struct platform_device *f71882fg_pdev;
  87. /* Super-I/O Function prototypes */
  88. static inline int superio_inb(int base, int reg);
  89. static inline int superio_inw(int base, int reg);
  90. static inline void superio_enter(int base);
  91. static inline void superio_select(int base, int ld);
  92. static inline void superio_exit(int base);
  93. struct f71882fg_sio_data {
  94. enum chips type;
  95. };
  96. struct f71882fg_data {
  97. unsigned short addr;
  98. enum chips type;
  99. struct device *hwmon_dev;
  100. struct mutex update_lock;
  101. char valid; /* !=0 if following fields are valid */
  102. unsigned long last_updated; /* In jiffies */
  103. unsigned long last_limits; /* In jiffies */
  104. /* Register Values */
  105. u8 in[9];
  106. u8 in1_max;
  107. u8 in_status;
  108. u8 in_beep;
  109. u16 fan[4];
  110. u16 fan_target[4];
  111. u16 fan_full_speed[4];
  112. u8 fan_status;
  113. u8 fan_beep;
  114. /* Note: all models have only 3 temperature channels, but on some
  115. they are addressed as 0-2 and on others as 1-3, so for coding
  116. convenience we reserve space for 4 channels */
  117. u8 temp[4];
  118. u8 temp_ovt[4];
  119. u8 temp_high[4];
  120. u8 temp_hyst[2]; /* 2 hysts stored per reg */
  121. u8 temp_type[4];
  122. u8 temp_status;
  123. u8 temp_beep;
  124. u8 temp_diode_open;
  125. u8 pwm[4];
  126. u8 pwm_enable;
  127. u8 pwm_auto_point_hyst[2];
  128. u8 pwm_auto_point_mapping[4];
  129. u8 pwm_auto_point_pwm[4][5];
  130. u8 pwm_auto_point_temp[4][4];
  131. };
  132. /* Sysfs in */
  133. static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
  134. char *buf);
  135. static ssize_t show_in_max(struct device *dev, struct device_attribute
  136. *devattr, char *buf);
  137. static ssize_t store_in_max(struct device *dev, struct device_attribute
  138. *devattr, const char *buf, size_t count);
  139. static ssize_t show_in_beep(struct device *dev, struct device_attribute
  140. *devattr, char *buf);
  141. static ssize_t store_in_beep(struct device *dev, struct device_attribute
  142. *devattr, const char *buf, size_t count);
  143. static ssize_t show_in_alarm(struct device *dev, struct device_attribute
  144. *devattr, char *buf);
  145. /* Sysfs Fan */
  146. static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
  147. char *buf);
  148. static ssize_t show_fan_full_speed(struct device *dev,
  149. struct device_attribute *devattr, char *buf);
  150. static ssize_t store_fan_full_speed(struct device *dev,
  151. struct device_attribute *devattr, const char *buf, size_t count);
  152. static ssize_t show_fan_beep(struct device *dev, struct device_attribute
  153. *devattr, char *buf);
  154. static ssize_t store_fan_beep(struct device *dev, struct device_attribute
  155. *devattr, const char *buf, size_t count);
  156. static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
  157. *devattr, char *buf);
  158. /* Sysfs Temp */
  159. static ssize_t show_temp(struct device *dev, struct device_attribute
  160. *devattr, char *buf);
  161. static ssize_t show_temp_max(struct device *dev, struct device_attribute
  162. *devattr, char *buf);
  163. static ssize_t store_temp_max(struct device *dev, struct device_attribute
  164. *devattr, const char *buf, size_t count);
  165. static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
  166. *devattr, char *buf);
  167. static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
  168. *devattr, const char *buf, size_t count);
  169. static ssize_t show_temp_crit(struct device *dev, struct device_attribute
  170. *devattr, char *buf);
  171. static ssize_t store_temp_crit(struct device *dev, struct device_attribute
  172. *devattr, const char *buf, size_t count);
  173. static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
  174. *devattr, char *buf);
  175. static ssize_t show_temp_type(struct device *dev, struct device_attribute
  176. *devattr, char *buf);
  177. static ssize_t show_temp_beep(struct device *dev, struct device_attribute
  178. *devattr, char *buf);
  179. static ssize_t store_temp_beep(struct device *dev, struct device_attribute
  180. *devattr, const char *buf, size_t count);
  181. static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
  182. *devattr, char *buf);
  183. static ssize_t show_temp_fault(struct device *dev, struct device_attribute
  184. *devattr, char *buf);
  185. /* PWM and Auto point control */
  186. static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
  187. char *buf);
  188. static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
  189. const char *buf, size_t count);
  190. static ssize_t show_pwm_enable(struct device *dev,
  191. struct device_attribute *devattr, char *buf);
  192. static ssize_t store_pwm_enable(struct device *dev,
  193. struct device_attribute *devattr, const char *buf, size_t count);
  194. static ssize_t show_pwm_interpolate(struct device *dev,
  195. struct device_attribute *devattr, char *buf);
  196. static ssize_t store_pwm_interpolate(struct device *dev,
  197. struct device_attribute *devattr, const char *buf, size_t count);
  198. static ssize_t show_pwm_auto_point_channel(struct device *dev,
  199. struct device_attribute *devattr, char *buf);
  200. static ssize_t store_pwm_auto_point_channel(struct device *dev,
  201. struct device_attribute *devattr, const char *buf, size_t count);
  202. static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
  203. struct device_attribute *devattr, char *buf);
  204. static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
  205. struct device_attribute *devattr, const char *buf, size_t count);
  206. static ssize_t show_pwm_auto_point_pwm(struct device *dev,
  207. struct device_attribute *devattr, char *buf);
  208. static ssize_t store_pwm_auto_point_pwm(struct device *dev,
  209. struct device_attribute *devattr, const char *buf, size_t count);
  210. static ssize_t show_pwm_auto_point_temp(struct device *dev,
  211. struct device_attribute *devattr, char *buf);
  212. static ssize_t store_pwm_auto_point_temp(struct device *dev,
  213. struct device_attribute *devattr, const char *buf, size_t count);
  214. /* Sysfs misc */
  215. static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
  216. char *buf);
  217. static int __devinit f71882fg_probe(struct platform_device * pdev);
  218. static int f71882fg_remove(struct platform_device *pdev);
  219. static struct platform_driver f71882fg_driver = {
  220. .driver = {
  221. .owner = THIS_MODULE,
  222. .name = DRVNAME,
  223. },
  224. .probe = f71882fg_probe,
  225. .remove = __devexit_p(f71882fg_remove),
  226. };
  227. static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
  228. static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
  229. SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
  230. SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
  231. SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
  232. SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
  233. SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
  234. SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
  235. SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
  236. SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
  237. SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
  238. SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
  239. SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
  240. store_temp_max, 0, 1),
  241. SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  242. store_temp_max_hyst, 0, 1),
  243. /* Should really be temp1_max_alarm, but older versions did not handle
  244. the max and crit alarms separately and lm_sensors v2 depends on the
  245. presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
  246. SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
  247. SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  248. store_temp_beep, 0, 1),
  249. SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  250. store_temp_crit, 0, 1),
  251. SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  252. 0, 1),
  253. SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
  254. SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  255. store_temp_beep, 0, 5),
  256. SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
  257. SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
  258. SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
  259. SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
  260. store_temp_max, 0, 2),
  261. SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  262. store_temp_max_hyst, 0, 2),
  263. /* Should be temp2_max_alarm, see temp1_alarm note */
  264. SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
  265. SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  266. store_temp_beep, 0, 2),
  267. SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  268. store_temp_crit, 0, 2),
  269. SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  270. 0, 2),
  271. SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
  272. SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  273. store_temp_beep, 0, 6),
  274. SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
  275. SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
  276. SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
  277. SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
  278. store_temp_max, 0, 3),
  279. SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  280. store_temp_max_hyst, 0, 3),
  281. /* Should be temp3_max_alarm, see temp1_alarm note */
  282. SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
  283. SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  284. store_temp_beep, 0, 3),
  285. SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  286. store_temp_crit, 0, 3),
  287. SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  288. 0, 3),
  289. SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
  290. SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  291. store_temp_beep, 0, 7),
  292. SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
  293. SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
  294. };
  295. static struct sensor_device_attribute_2 f71882fg_in_temp_attr[] = {
  296. SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
  297. 0, 1),
  298. SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
  299. 0, 1),
  300. SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
  301. };
  302. static struct sensor_device_attribute_2 f718x2fg_fan_attr[] = {
  303. SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
  304. SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
  305. show_fan_full_speed,
  306. store_fan_full_speed, 0, 0),
  307. SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  308. store_fan_beep, 0, 0),
  309. SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
  310. SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
  311. SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
  312. show_fan_full_speed,
  313. store_fan_full_speed, 0, 1),
  314. SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  315. store_fan_beep, 0, 1),
  316. SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
  317. SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
  318. SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
  319. show_fan_full_speed,
  320. store_fan_full_speed, 0, 2),
  321. SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  322. store_fan_beep, 0, 2),
  323. SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
  324. SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
  325. SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  326. store_pwm_enable, 0, 0),
  327. SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
  328. show_pwm_interpolate, store_pwm_interpolate, 0, 0),
  329. SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
  330. show_pwm_auto_point_channel,
  331. store_pwm_auto_point_channel, 0, 0),
  332. SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
  333. SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  334. store_pwm_enable, 0, 1),
  335. SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
  336. show_pwm_interpolate, store_pwm_interpolate, 0, 1),
  337. SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
  338. show_pwm_auto_point_channel,
  339. store_pwm_auto_point_channel, 0, 1),
  340. SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
  341. SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  342. store_pwm_enable, 0, 2),
  343. SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
  344. show_pwm_interpolate, store_pwm_interpolate, 0, 2),
  345. SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
  346. show_pwm_auto_point_channel,
  347. store_pwm_auto_point_channel, 0, 2),
  348. };
  349. static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
  350. SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
  351. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  352. 1, 0),
  353. SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
  354. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  355. 4, 0),
  356. SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
  357. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  358. 0, 0),
  359. SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
  360. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  361. 3, 0),
  362. SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  363. show_pwm_auto_point_temp_hyst,
  364. store_pwm_auto_point_temp_hyst,
  365. 0, 0),
  366. SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
  367. show_pwm_auto_point_temp_hyst, NULL, 3, 0),
  368. SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
  369. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  370. 1, 1),
  371. SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
  372. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  373. 4, 1),
  374. SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
  375. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  376. 0, 1),
  377. SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
  378. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  379. 3, 1),
  380. SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  381. show_pwm_auto_point_temp_hyst,
  382. store_pwm_auto_point_temp_hyst,
  383. 0, 1),
  384. SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
  385. show_pwm_auto_point_temp_hyst, NULL, 3, 1),
  386. };
  387. static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
  388. SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
  389. SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
  390. show_fan_full_speed,
  391. store_fan_full_speed, 0, 3),
  392. SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  393. store_fan_beep, 0, 3),
  394. SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
  395. SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
  396. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  397. 0, 0),
  398. SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
  399. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  400. 1, 0),
  401. SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
  402. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  403. 2, 0),
  404. SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
  405. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  406. 3, 0),
  407. SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
  408. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  409. 4, 0),
  410. SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
  411. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  412. 0, 0),
  413. SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
  414. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  415. 1, 0),
  416. SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
  417. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  418. 2, 0),
  419. SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
  420. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  421. 3, 0),
  422. SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  423. show_pwm_auto_point_temp_hyst,
  424. store_pwm_auto_point_temp_hyst,
  425. 0, 0),
  426. SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
  427. show_pwm_auto_point_temp_hyst, NULL, 1, 0),
  428. SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
  429. show_pwm_auto_point_temp_hyst, NULL, 2, 0),
  430. SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
  431. show_pwm_auto_point_temp_hyst, NULL, 3, 0),
  432. SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
  433. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  434. 0, 1),
  435. SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
  436. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  437. 1, 1),
  438. SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
  439. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  440. 2, 1),
  441. SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
  442. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  443. 3, 1),
  444. SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
  445. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  446. 4, 1),
  447. SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
  448. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  449. 0, 1),
  450. SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
  451. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  452. 1, 1),
  453. SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
  454. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  455. 2, 1),
  456. SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
  457. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  458. 3, 1),
  459. SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  460. show_pwm_auto_point_temp_hyst,
  461. store_pwm_auto_point_temp_hyst,
  462. 0, 1),
  463. SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
  464. show_pwm_auto_point_temp_hyst, NULL, 1, 1),
  465. SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
  466. show_pwm_auto_point_temp_hyst, NULL, 2, 1),
  467. SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
  468. show_pwm_auto_point_temp_hyst, NULL, 3, 1),
  469. SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
  470. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  471. 0, 2),
  472. SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
  473. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  474. 1, 2),
  475. SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
  476. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  477. 2, 2),
  478. SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
  479. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  480. 3, 2),
  481. SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
  482. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  483. 4, 2),
  484. SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
  485. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  486. 0, 2),
  487. SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
  488. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  489. 1, 2),
  490. SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
  491. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  492. 2, 2),
  493. SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
  494. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  495. 3, 2),
  496. SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  497. show_pwm_auto_point_temp_hyst,
  498. store_pwm_auto_point_temp_hyst,
  499. 0, 2),
  500. SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
  501. show_pwm_auto_point_temp_hyst, NULL, 1, 2),
  502. SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
  503. show_pwm_auto_point_temp_hyst, NULL, 2, 2),
  504. SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
  505. show_pwm_auto_point_temp_hyst, NULL, 3, 2),
  506. SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
  507. SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  508. store_pwm_enable, 0, 3),
  509. SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
  510. show_pwm_interpolate, store_pwm_interpolate, 0, 3),
  511. SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
  512. show_pwm_auto_point_channel,
  513. store_pwm_auto_point_channel, 0, 3),
  514. SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
  515. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  516. 0, 3),
  517. SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
  518. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  519. 1, 3),
  520. SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
  521. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  522. 2, 3),
  523. SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
  524. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  525. 3, 3),
  526. SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
  527. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  528. 4, 3),
  529. SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
  530. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  531. 0, 3),
  532. SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
  533. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  534. 1, 3),
  535. SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
  536. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  537. 2, 3),
  538. SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
  539. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  540. 3, 3),
  541. SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  542. show_pwm_auto_point_temp_hyst,
  543. store_pwm_auto_point_temp_hyst,
  544. 0, 3),
  545. SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
  546. show_pwm_auto_point_temp_hyst, NULL, 1, 3),
  547. SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
  548. show_pwm_auto_point_temp_hyst, NULL, 2, 3),
  549. SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
  550. show_pwm_auto_point_temp_hyst, NULL, 3, 3),
  551. };
  552. /* Super I/O functions */
  553. static inline int superio_inb(int base, int reg)
  554. {
  555. outb(reg, base);
  556. return inb(base + 1);
  557. }
  558. static int superio_inw(int base, int reg)
  559. {
  560. int val;
  561. outb(reg++, base);
  562. val = inb(base + 1) << 8;
  563. outb(reg, base);
  564. val |= inb(base + 1);
  565. return val;
  566. }
  567. static inline void superio_enter(int base)
  568. {
  569. /* according to the datasheet the key must be send twice! */
  570. outb( SIO_UNLOCK_KEY, base);
  571. outb( SIO_UNLOCK_KEY, base);
  572. }
  573. static inline void superio_select( int base, int ld)
  574. {
  575. outb(SIO_REG_LDSEL, base);
  576. outb(ld, base + 1);
  577. }
  578. static inline void superio_exit(int base)
  579. {
  580. outb(SIO_LOCK_KEY, base);
  581. }
  582. static inline u16 fan_from_reg(u16 reg)
  583. {
  584. return reg ? (1500000 / reg) : 0;
  585. }
  586. static inline u16 fan_to_reg(u16 fan)
  587. {
  588. return fan ? (1500000 / fan) : 0;
  589. }
  590. static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
  591. {
  592. u8 val;
  593. outb(reg, data->addr + ADDR_REG_OFFSET);
  594. val = inb(data->addr + DATA_REG_OFFSET);
  595. return val;
  596. }
  597. static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
  598. {
  599. u16 val;
  600. outb(reg++, data->addr + ADDR_REG_OFFSET);
  601. val = inb(data->addr + DATA_REG_OFFSET) << 8;
  602. outb(reg, data->addr + ADDR_REG_OFFSET);
  603. val |= inb(data->addr + DATA_REG_OFFSET);
  604. return val;
  605. }
  606. static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
  607. {
  608. outb(reg, data->addr + ADDR_REG_OFFSET);
  609. outb(val, data->addr + DATA_REG_OFFSET);
  610. }
  611. static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
  612. {
  613. outb(reg++, data->addr + ADDR_REG_OFFSET);
  614. outb(val >> 8, data->addr + DATA_REG_OFFSET);
  615. outb(reg, data->addr + ADDR_REG_OFFSET);
  616. outb(val & 255, data->addr + DATA_REG_OFFSET);
  617. }
  618. static struct f71882fg_data *f71882fg_update_device(struct device *dev)
  619. {
  620. struct f71882fg_data *data = dev_get_drvdata(dev);
  621. int nr, reg, reg2;
  622. int nr_fans = (data->type == f71862fg) ? 3 : 4;
  623. mutex_lock(&data->update_lock);
  624. /* Update once every 60 seconds */
  625. if ( time_after(jiffies, data->last_limits + 60 * HZ ) ||
  626. !data->valid) {
  627. if (data->type == f71882fg) {
  628. data->in1_max =
  629. f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
  630. data->in_beep =
  631. f71882fg_read8(data, F71882FG_REG_IN_BEEP);
  632. }
  633. /* Get High & boundary temps*/
  634. for (nr = 1; nr < 4; nr++) {
  635. data->temp_ovt[nr] = f71882fg_read8(data,
  636. F71882FG_REG_TEMP_OVT(nr));
  637. data->temp_high[nr] = f71882fg_read8(data,
  638. F71882FG_REG_TEMP_HIGH(nr));
  639. }
  640. /* hyst */
  641. data->temp_hyst[0] =
  642. f71882fg_read8(data, F71882FG_REG_TEMP_HYST(0));
  643. data->temp_hyst[1] =
  644. f71882fg_read8(data, F71882FG_REG_TEMP_HYST(1));
  645. /* Have to hardcode type, because temp1 is special */
  646. reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
  647. reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
  648. if ((reg2 & 0x03) == 0x01)
  649. data->temp_type[1] = 6 /* PECI */;
  650. else if ((reg2 & 0x03) == 0x02)
  651. data->temp_type[1] = 5 /* AMDSI */;
  652. else
  653. data->temp_type[1] = (reg & 0x02) ? 2 : 4;
  654. data->temp_type[2] = (reg & 0x04) ? 2 : 4;
  655. data->temp_type[3] = (reg & 0x08) ? 2 : 4;
  656. data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
  657. data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
  658. data->pwm_enable = f71882fg_read8(data,
  659. F71882FG_REG_PWM_ENABLE);
  660. data->pwm_auto_point_hyst[0] =
  661. f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
  662. data->pwm_auto_point_hyst[1] =
  663. f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
  664. for (nr = 0; nr < nr_fans; nr++) {
  665. data->pwm_auto_point_mapping[nr] =
  666. f71882fg_read8(data,
  667. F71882FG_REG_POINT_MAPPING(nr));
  668. if (data->type == f71882fg) {
  669. int point;
  670. for (point = 0; point < 5; point++) {
  671. data->pwm_auto_point_pwm[nr][point] =
  672. f71882fg_read8(data,
  673. F71882FG_REG_POINT_PWM
  674. (nr, point));
  675. }
  676. for (point = 0; point < 4; point++) {
  677. data->pwm_auto_point_temp[nr][point] =
  678. f71882fg_read8(data,
  679. F71882FG_REG_POINT_TEMP
  680. (nr, point));
  681. }
  682. } else {
  683. data->pwm_auto_point_pwm[nr][1] =
  684. f71882fg_read8(data,
  685. F71882FG_REG_POINT_PWM
  686. (nr, 1));
  687. data->pwm_auto_point_pwm[nr][4] =
  688. f71882fg_read8(data,
  689. F71882FG_REG_POINT_PWM
  690. (nr, 4));
  691. data->pwm_auto_point_temp[nr][0] =
  692. f71882fg_read8(data,
  693. F71882FG_REG_POINT_TEMP
  694. (nr, 0));
  695. data->pwm_auto_point_temp[nr][3] =
  696. f71882fg_read8(data,
  697. F71882FG_REG_POINT_TEMP
  698. (nr, 3));
  699. }
  700. }
  701. data->last_limits = jiffies;
  702. }
  703. /* Update every second */
  704. if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
  705. data->temp_status = f71882fg_read8(data,
  706. F71882FG_REG_TEMP_STATUS);
  707. data->temp_diode_open = f71882fg_read8(data,
  708. F71882FG_REG_TEMP_DIODE_OPEN);
  709. for (nr = 1; nr < 4; nr++)
  710. data->temp[nr] = f71882fg_read8(data,
  711. F71882FG_REG_TEMP(nr));
  712. data->fan_status = f71882fg_read8(data,
  713. F71882FG_REG_FAN_STATUS);
  714. for (nr = 0; nr < nr_fans; nr++) {
  715. data->fan[nr] = f71882fg_read16(data,
  716. F71882FG_REG_FAN(nr));
  717. data->fan_target[nr] =
  718. f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
  719. data->fan_full_speed[nr] =
  720. f71882fg_read16(data,
  721. F71882FG_REG_FAN_FULL_SPEED(nr));
  722. data->pwm[nr] =
  723. f71882fg_read8(data, F71882FG_REG_PWM(nr));
  724. }
  725. if (data->type == f71882fg)
  726. data->in_status = f71882fg_read8(data,
  727. F71882FG_REG_IN_STATUS);
  728. for (nr = 0; nr < 9; nr++)
  729. data->in[nr] = f71882fg_read8(data,
  730. F71882FG_REG_IN(nr));
  731. data->last_updated = jiffies;
  732. data->valid = 1;
  733. }
  734. mutex_unlock(&data->update_lock);
  735. return data;
  736. }
  737. /* Sysfs Interface */
  738. static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
  739. char *buf)
  740. {
  741. struct f71882fg_data *data = f71882fg_update_device(dev);
  742. int nr = to_sensor_dev_attr_2(devattr)->index;
  743. int speed = fan_from_reg(data->fan[nr]);
  744. if (speed == FAN_MIN_DETECT)
  745. speed = 0;
  746. return sprintf(buf, "%d\n", speed);
  747. }
  748. static ssize_t show_fan_full_speed(struct device *dev,
  749. struct device_attribute *devattr, char *buf)
  750. {
  751. struct f71882fg_data *data = f71882fg_update_device(dev);
  752. int nr = to_sensor_dev_attr_2(devattr)->index;
  753. int speed = fan_from_reg(data->fan_full_speed[nr]);
  754. return sprintf(buf, "%d\n", speed);
  755. }
  756. static ssize_t store_fan_full_speed(struct device *dev,
  757. struct device_attribute *devattr,
  758. const char *buf, size_t count)
  759. {
  760. struct f71882fg_data *data = dev_get_drvdata(dev);
  761. int nr = to_sensor_dev_attr_2(devattr)->index;
  762. long val = simple_strtol(buf, NULL, 10);
  763. val = SENSORS_LIMIT(val, 23, 1500000);
  764. val = fan_to_reg(val);
  765. mutex_lock(&data->update_lock);
  766. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  767. if (data->pwm_enable & (1 << (2 * nr)))
  768. /* PWM mode */
  769. count = -EINVAL;
  770. else {
  771. /* RPM mode */
  772. f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
  773. data->fan_full_speed[nr] = val;
  774. }
  775. mutex_unlock(&data->update_lock);
  776. return count;
  777. }
  778. static ssize_t show_fan_beep(struct device *dev, struct device_attribute
  779. *devattr, char *buf)
  780. {
  781. struct f71882fg_data *data = f71882fg_update_device(dev);
  782. int nr = to_sensor_dev_attr_2(devattr)->index;
  783. if (data->fan_beep & (1 << nr))
  784. return sprintf(buf, "1\n");
  785. else
  786. return sprintf(buf, "0\n");
  787. }
  788. static ssize_t store_fan_beep(struct device *dev, struct device_attribute
  789. *devattr, const char *buf, size_t count)
  790. {
  791. struct f71882fg_data *data = dev_get_drvdata(dev);
  792. int nr = to_sensor_dev_attr_2(devattr)->index;
  793. unsigned long val = simple_strtoul(buf, NULL, 10);
  794. mutex_lock(&data->update_lock);
  795. data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
  796. if (val)
  797. data->fan_beep |= 1 << nr;
  798. else
  799. data->fan_beep &= ~(1 << nr);
  800. f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
  801. mutex_unlock(&data->update_lock);
  802. return count;
  803. }
  804. static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
  805. *devattr, char *buf)
  806. {
  807. struct f71882fg_data *data = f71882fg_update_device(dev);
  808. int nr = to_sensor_dev_attr_2(devattr)->index;
  809. if (data->fan_status & (1 << nr))
  810. return sprintf(buf, "1\n");
  811. else
  812. return sprintf(buf, "0\n");
  813. }
  814. static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
  815. char *buf)
  816. {
  817. struct f71882fg_data *data = f71882fg_update_device(dev);
  818. int nr = to_sensor_dev_attr_2(devattr)->index;
  819. return sprintf(buf, "%d\n", data->in[nr] * 8);
  820. }
  821. static ssize_t show_in_max(struct device *dev, struct device_attribute
  822. *devattr, char *buf)
  823. {
  824. struct f71882fg_data *data = f71882fg_update_device(dev);
  825. return sprintf(buf, "%d\n", data->in1_max * 8);
  826. }
  827. static ssize_t store_in_max(struct device *dev, struct device_attribute
  828. *devattr, const char *buf, size_t count)
  829. {
  830. struct f71882fg_data *data = dev_get_drvdata(dev);
  831. long val = simple_strtol(buf, NULL, 10) / 8;
  832. val = SENSORS_LIMIT(val, 0, 255);
  833. mutex_lock(&data->update_lock);
  834. f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
  835. data->in1_max = val;
  836. mutex_unlock(&data->update_lock);
  837. return count;
  838. }
  839. static ssize_t show_in_beep(struct device *dev, struct device_attribute
  840. *devattr, char *buf)
  841. {
  842. struct f71882fg_data *data = f71882fg_update_device(dev);
  843. int nr = to_sensor_dev_attr_2(devattr)->index;
  844. if (data->in_beep & (1 << nr))
  845. return sprintf(buf, "1\n");
  846. else
  847. return sprintf(buf, "0\n");
  848. }
  849. static ssize_t store_in_beep(struct device *dev, struct device_attribute
  850. *devattr, const char *buf, size_t count)
  851. {
  852. struct f71882fg_data *data = dev_get_drvdata(dev);
  853. int nr = to_sensor_dev_attr_2(devattr)->index;
  854. unsigned long val = simple_strtoul(buf, NULL, 10);
  855. mutex_lock(&data->update_lock);
  856. data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
  857. if (val)
  858. data->in_beep |= 1 << nr;
  859. else
  860. data->in_beep &= ~(1 << nr);
  861. f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
  862. mutex_unlock(&data->update_lock);
  863. return count;
  864. }
  865. static ssize_t show_in_alarm(struct device *dev, struct device_attribute
  866. *devattr, char *buf)
  867. {
  868. struct f71882fg_data *data = f71882fg_update_device(dev);
  869. int nr = to_sensor_dev_attr_2(devattr)->index;
  870. if (data->in_status & (1 << nr))
  871. return sprintf(buf, "1\n");
  872. else
  873. return sprintf(buf, "0\n");
  874. }
  875. static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
  876. char *buf)
  877. {
  878. struct f71882fg_data *data = f71882fg_update_device(dev);
  879. int nr = to_sensor_dev_attr_2(devattr)->index;
  880. return sprintf(buf, "%d\n", data->temp[nr] * 1000);
  881. }
  882. static ssize_t show_temp_max(struct device *dev, struct device_attribute
  883. *devattr, char *buf)
  884. {
  885. struct f71882fg_data *data = f71882fg_update_device(dev);
  886. int nr = to_sensor_dev_attr_2(devattr)->index;
  887. return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
  888. }
  889. static ssize_t store_temp_max(struct device *dev, struct device_attribute
  890. *devattr, const char *buf, size_t count)
  891. {
  892. struct f71882fg_data *data = dev_get_drvdata(dev);
  893. int nr = to_sensor_dev_attr_2(devattr)->index;
  894. long val = simple_strtol(buf, NULL, 10) / 1000;
  895. val = SENSORS_LIMIT(val, 0, 255);
  896. mutex_lock(&data->update_lock);
  897. f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
  898. data->temp_high[nr] = val;
  899. mutex_unlock(&data->update_lock);
  900. return count;
  901. }
  902. static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
  903. *devattr, char *buf)
  904. {
  905. struct f71882fg_data *data = f71882fg_update_device(dev);
  906. int nr = to_sensor_dev_attr_2(devattr)->index;
  907. int temp_max_hyst;
  908. mutex_lock(&data->update_lock);
  909. if (nr & 1)
  910. temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
  911. else
  912. temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
  913. temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
  914. mutex_unlock(&data->update_lock);
  915. return sprintf(buf, "%d\n", temp_max_hyst);
  916. }
  917. static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
  918. *devattr, const char *buf, size_t count)
  919. {
  920. struct f71882fg_data *data = dev_get_drvdata(dev);
  921. int nr = to_sensor_dev_attr_2(devattr)->index;
  922. long val = simple_strtol(buf, NULL, 10) / 1000;
  923. ssize_t ret = count;
  924. u8 reg;
  925. mutex_lock(&data->update_lock);
  926. /* convert abs to relative and check */
  927. data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
  928. val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
  929. data->temp_high[nr]);
  930. val = data->temp_high[nr] - val;
  931. /* convert value to register contents */
  932. reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
  933. if (nr & 1)
  934. reg = (reg & 0x0f) | (val << 4);
  935. else
  936. reg = (reg & 0xf0) | val;
  937. f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
  938. data->temp_hyst[nr / 2] = reg;
  939. mutex_unlock(&data->update_lock);
  940. return ret;
  941. }
  942. static ssize_t show_temp_crit(struct device *dev, struct device_attribute
  943. *devattr, char *buf)
  944. {
  945. struct f71882fg_data *data = f71882fg_update_device(dev);
  946. int nr = to_sensor_dev_attr_2(devattr)->index;
  947. return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
  948. }
  949. static ssize_t store_temp_crit(struct device *dev, struct device_attribute
  950. *devattr, const char *buf, size_t count)
  951. {
  952. struct f71882fg_data *data = dev_get_drvdata(dev);
  953. int nr = to_sensor_dev_attr_2(devattr)->index;
  954. long val = simple_strtol(buf, NULL, 10) / 1000;
  955. val = SENSORS_LIMIT(val, 0, 255);
  956. mutex_lock(&data->update_lock);
  957. f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
  958. data->temp_ovt[nr] = val;
  959. mutex_unlock(&data->update_lock);
  960. return count;
  961. }
  962. static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
  963. *devattr, char *buf)
  964. {
  965. struct f71882fg_data *data = f71882fg_update_device(dev);
  966. int nr = to_sensor_dev_attr_2(devattr)->index;
  967. int temp_crit_hyst;
  968. mutex_lock(&data->update_lock);
  969. if (nr & 1)
  970. temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
  971. else
  972. temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
  973. temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
  974. mutex_unlock(&data->update_lock);
  975. return sprintf(buf, "%d\n", temp_crit_hyst);
  976. }
  977. static ssize_t show_temp_type(struct device *dev, struct device_attribute
  978. *devattr, char *buf)
  979. {
  980. struct f71882fg_data *data = f71882fg_update_device(dev);
  981. int nr = to_sensor_dev_attr_2(devattr)->index;
  982. return sprintf(buf, "%d\n", data->temp_type[nr]);
  983. }
  984. static ssize_t show_temp_beep(struct device *dev, struct device_attribute
  985. *devattr, char *buf)
  986. {
  987. struct f71882fg_data *data = f71882fg_update_device(dev);
  988. int nr = to_sensor_dev_attr_2(devattr)->index;
  989. if (data->temp_beep & (1 << nr))
  990. return sprintf(buf, "1\n");
  991. else
  992. return sprintf(buf, "0\n");
  993. }
  994. static ssize_t store_temp_beep(struct device *dev, struct device_attribute
  995. *devattr, const char *buf, size_t count)
  996. {
  997. struct f71882fg_data *data = dev_get_drvdata(dev);
  998. int nr = to_sensor_dev_attr_2(devattr)->index;
  999. unsigned long val = simple_strtoul(buf, NULL, 10);
  1000. mutex_lock(&data->update_lock);
  1001. data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
  1002. if (val)
  1003. data->temp_beep |= 1 << nr;
  1004. else
  1005. data->temp_beep &= ~(1 << nr);
  1006. f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
  1007. mutex_unlock(&data->update_lock);
  1008. return count;
  1009. }
  1010. static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
  1011. *devattr, char *buf)
  1012. {
  1013. struct f71882fg_data *data = f71882fg_update_device(dev);
  1014. int nr = to_sensor_dev_attr_2(devattr)->index;
  1015. if (data->temp_status & (1 << nr))
  1016. return sprintf(buf, "1\n");
  1017. else
  1018. return sprintf(buf, "0\n");
  1019. }
  1020. static ssize_t show_temp_fault(struct device *dev, struct device_attribute
  1021. *devattr, char *buf)
  1022. {
  1023. struct f71882fg_data *data = f71882fg_update_device(dev);
  1024. int nr = to_sensor_dev_attr_2(devattr)->index;
  1025. if (data->temp_diode_open & (1 << nr))
  1026. return sprintf(buf, "1\n");
  1027. else
  1028. return sprintf(buf, "0\n");
  1029. }
  1030. static ssize_t show_pwm(struct device *dev,
  1031. struct device_attribute *devattr, char *buf)
  1032. {
  1033. struct f71882fg_data *data = f71882fg_update_device(dev);
  1034. int val, nr = to_sensor_dev_attr_2(devattr)->index;
  1035. mutex_lock(&data->update_lock);
  1036. if (data->pwm_enable & (1 << (2 * nr)))
  1037. /* PWM mode */
  1038. val = data->pwm[nr];
  1039. else {
  1040. /* RPM mode */
  1041. val = 255 * fan_from_reg(data->fan_target[nr])
  1042. / fan_from_reg(data->fan_full_speed[nr]);
  1043. }
  1044. mutex_unlock(&data->update_lock);
  1045. return sprintf(buf, "%d\n", val);
  1046. }
  1047. static ssize_t store_pwm(struct device *dev,
  1048. struct device_attribute *devattr, const char *buf,
  1049. size_t count)
  1050. {
  1051. struct f71882fg_data *data = dev_get_drvdata(dev);
  1052. int nr = to_sensor_dev_attr_2(devattr)->index;
  1053. long val = simple_strtol(buf, NULL, 10);
  1054. val = SENSORS_LIMIT(val, 0, 255);
  1055. mutex_lock(&data->update_lock);
  1056. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1057. if (data->pwm_enable & (1 << (2 * nr))) {
  1058. /* PWM mode */
  1059. f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
  1060. data->pwm[nr] = val;
  1061. } else {
  1062. /* RPM mode */
  1063. int target, full_speed;
  1064. full_speed = f71882fg_read16(data,
  1065. F71882FG_REG_FAN_FULL_SPEED(nr));
  1066. target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
  1067. f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
  1068. data->fan_target[nr] = target;
  1069. data->fan_full_speed[nr] = full_speed;
  1070. }
  1071. mutex_unlock(&data->update_lock);
  1072. return count;
  1073. }
  1074. static ssize_t show_pwm_enable(struct device *dev,
  1075. struct device_attribute *devattr, char *buf)
  1076. {
  1077. int result;
  1078. struct f71882fg_data *data = f71882fg_update_device(dev);
  1079. int nr = to_sensor_dev_attr_2(devattr)->index;
  1080. if (data->pwm_enable & (2 << (2 * nr)))
  1081. result = 1;
  1082. else
  1083. result = 2;
  1084. return sprintf(buf, "%d\n", result);
  1085. }
  1086. static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
  1087. *devattr, const char *buf, size_t count)
  1088. {
  1089. struct f71882fg_data *data = dev_get_drvdata(dev);
  1090. int nr = to_sensor_dev_attr_2(devattr)->index;
  1091. long val = simple_strtol(buf, NULL, 10);
  1092. if (val < 1 || val > 2)
  1093. return -EINVAL;
  1094. mutex_lock(&data->update_lock);
  1095. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1096. switch (val) {
  1097. case 1:
  1098. data->pwm_enable |= 2 << (2 * nr);
  1099. break; /* Manual */
  1100. case 2:
  1101. data->pwm_enable &= ~(2 << (2 * nr));
  1102. break; /* Temperature ctrl */
  1103. }
  1104. if (data->type == f71882fg) {
  1105. switch (fan_mode[nr]) {
  1106. case 1:
  1107. data->pwm_enable |= 1 << (2 * nr);
  1108. break; /* Duty cycle mode */
  1109. case 2:
  1110. data->pwm_enable &= ~(1 << (2 * nr));
  1111. break; /* RPM mode */
  1112. }
  1113. }
  1114. f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
  1115. mutex_unlock(&data->update_lock);
  1116. return count;
  1117. }
  1118. static ssize_t show_pwm_auto_point_pwm(struct device *dev,
  1119. struct device_attribute *devattr,
  1120. char *buf)
  1121. {
  1122. int result;
  1123. struct f71882fg_data *data = f71882fg_update_device(dev);
  1124. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1125. int point = to_sensor_dev_attr_2(devattr)->nr;
  1126. mutex_lock(&data->update_lock);
  1127. if (data->pwm_enable & (1 << (2 * pwm))) {
  1128. /* PWM mode */
  1129. result = data->pwm_auto_point_pwm[pwm][point];
  1130. } else {
  1131. /* RPM mode */
  1132. result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
  1133. }
  1134. mutex_unlock(&data->update_lock);
  1135. return sprintf(buf, "%d\n", result);
  1136. }
  1137. static ssize_t store_pwm_auto_point_pwm(struct device *dev,
  1138. struct device_attribute *devattr,
  1139. const char *buf, size_t count)
  1140. {
  1141. struct f71882fg_data *data = dev_get_drvdata(dev);
  1142. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1143. int point = to_sensor_dev_attr_2(devattr)->nr;
  1144. long val = simple_strtol(buf, NULL, 10);
  1145. val = SENSORS_LIMIT(val, 0, 255);
  1146. mutex_lock(&data->update_lock);
  1147. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1148. if (data->pwm_enable & (1 << (2 * pwm))) {
  1149. /* PWM mode */
  1150. } else {
  1151. /* RPM mode */
  1152. if (val < 29) /* Prevent negative numbers */
  1153. val = 255;
  1154. else
  1155. val = (255 - val) * 32 / val;
  1156. }
  1157. f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
  1158. data->pwm_auto_point_pwm[pwm][point] = val;
  1159. mutex_unlock(&data->update_lock);
  1160. return count;
  1161. }
  1162. static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
  1163. struct device_attribute *devattr,
  1164. char *buf)
  1165. {
  1166. int result = 0;
  1167. struct f71882fg_data *data = f71882fg_update_device(dev);
  1168. int nr = to_sensor_dev_attr_2(devattr)->index;
  1169. int point = to_sensor_dev_attr_2(devattr)->nr;
  1170. mutex_lock(&data->update_lock);
  1171. if (nr & 1)
  1172. result = data->pwm_auto_point_hyst[nr / 2] >> 4;
  1173. else
  1174. result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
  1175. result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
  1176. mutex_unlock(&data->update_lock);
  1177. return sprintf(buf, "%d\n", result);
  1178. }
  1179. static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
  1180. struct device_attribute *devattr,
  1181. const char *buf, size_t count)
  1182. {
  1183. struct f71882fg_data *data = dev_get_drvdata(dev);
  1184. int nr = to_sensor_dev_attr_2(devattr)->index;
  1185. int point = to_sensor_dev_attr_2(devattr)->nr;
  1186. long val = simple_strtol(buf, NULL, 10) / 1000;
  1187. u8 reg;
  1188. mutex_lock(&data->update_lock);
  1189. data->pwm_auto_point_temp[nr][point] =
  1190. f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
  1191. val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
  1192. data->pwm_auto_point_temp[nr][point]);
  1193. val = data->pwm_auto_point_temp[nr][point] - val;
  1194. reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
  1195. if (nr & 1)
  1196. reg = (reg & 0x0f) | (val << 4);
  1197. else
  1198. reg = (reg & 0xf0) | val;
  1199. f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
  1200. data->pwm_auto_point_hyst[nr / 2] = reg;
  1201. mutex_unlock(&data->update_lock);
  1202. return count;
  1203. }
  1204. static ssize_t show_pwm_interpolate(struct device *dev,
  1205. struct device_attribute *devattr, char *buf)
  1206. {
  1207. int result;
  1208. struct f71882fg_data *data = f71882fg_update_device(dev);
  1209. int nr = to_sensor_dev_attr_2(devattr)->index;
  1210. result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
  1211. return sprintf(buf, "%d\n", result);
  1212. }
  1213. static ssize_t store_pwm_interpolate(struct device *dev,
  1214. struct device_attribute *devattr,
  1215. const char *buf, size_t count)
  1216. {
  1217. struct f71882fg_data *data = dev_get_drvdata(dev);
  1218. int nr = to_sensor_dev_attr_2(devattr)->index;
  1219. unsigned long val = simple_strtoul(buf, NULL, 10);
  1220. mutex_lock(&data->update_lock);
  1221. data->pwm_auto_point_mapping[nr] =
  1222. f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
  1223. if (val)
  1224. val = data->pwm_auto_point_mapping[nr] | (1 << 4);
  1225. else
  1226. val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
  1227. f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
  1228. data->pwm_auto_point_mapping[nr] = val;
  1229. mutex_unlock(&data->update_lock);
  1230. return count;
  1231. }
  1232. static ssize_t show_pwm_auto_point_channel(struct device *dev,
  1233. struct device_attribute *devattr,
  1234. char *buf)
  1235. {
  1236. int result;
  1237. struct f71882fg_data *data = f71882fg_update_device(dev);
  1238. int nr = to_sensor_dev_attr_2(devattr)->index;
  1239. result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - 1);
  1240. return sprintf(buf, "%d\n", result);
  1241. }
  1242. static ssize_t store_pwm_auto_point_channel(struct device *dev,
  1243. struct device_attribute *devattr,
  1244. const char *buf, size_t count)
  1245. {
  1246. struct f71882fg_data *data = dev_get_drvdata(dev);
  1247. int nr = to_sensor_dev_attr_2(devattr)->index;
  1248. long val = simple_strtol(buf, NULL, 10);
  1249. switch (val) {
  1250. case 1:
  1251. val = 1;
  1252. break;
  1253. case 2:
  1254. val = 2;
  1255. break;
  1256. case 4:
  1257. val = 3;
  1258. break;
  1259. default:
  1260. return -EINVAL;
  1261. }
  1262. mutex_lock(&data->update_lock);
  1263. data->pwm_auto_point_mapping[nr] =
  1264. f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
  1265. val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
  1266. f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
  1267. data->pwm_auto_point_mapping[nr] = val;
  1268. mutex_unlock(&data->update_lock);
  1269. return count;
  1270. }
  1271. static ssize_t show_pwm_auto_point_temp(struct device *dev,
  1272. struct device_attribute *devattr,
  1273. char *buf)
  1274. {
  1275. int result;
  1276. struct f71882fg_data *data = f71882fg_update_device(dev);
  1277. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1278. int point = to_sensor_dev_attr_2(devattr)->nr;
  1279. result = data->pwm_auto_point_temp[pwm][point];
  1280. return sprintf(buf, "%d\n", 1000 * result);
  1281. }
  1282. static ssize_t store_pwm_auto_point_temp(struct device *dev,
  1283. struct device_attribute *devattr,
  1284. const char *buf, size_t count)
  1285. {
  1286. struct f71882fg_data *data = dev_get_drvdata(dev);
  1287. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1288. int point = to_sensor_dev_attr_2(devattr)->nr;
  1289. long val = simple_strtol(buf, NULL, 10) / 1000;
  1290. val = SENSORS_LIMIT(val, 0, 255);
  1291. mutex_lock(&data->update_lock);
  1292. f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
  1293. data->pwm_auto_point_temp[pwm][point] = val;
  1294. mutex_unlock(&data->update_lock);
  1295. return count;
  1296. }
  1297. static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
  1298. char *buf)
  1299. {
  1300. struct f71882fg_data *data = dev_get_drvdata(dev);
  1301. return sprintf(buf, "%s\n", f71882fg_names[data->type]);
  1302. }
  1303. static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
  1304. struct sensor_device_attribute_2 *attr, int count)
  1305. {
  1306. int err, i;
  1307. for (i = 0; i < count; i++) {
  1308. err = device_create_file(&pdev->dev, &attr[i].dev_attr);
  1309. if (err)
  1310. return err;
  1311. }
  1312. return 0;
  1313. }
  1314. static int __devinit f71882fg_probe(struct platform_device *pdev)
  1315. {
  1316. struct f71882fg_data *data;
  1317. struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
  1318. int err;
  1319. u8 start_reg;
  1320. data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
  1321. if (!data)
  1322. return -ENOMEM;
  1323. data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
  1324. data->type = sio_data->type;
  1325. mutex_init(&data->update_lock);
  1326. platform_set_drvdata(pdev, data);
  1327. start_reg = f71882fg_read8(data, F71882FG_REG_START);
  1328. if (start_reg & 0x04) {
  1329. dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
  1330. err = -ENODEV;
  1331. goto exit_free;
  1332. }
  1333. if (!(start_reg & 0x03)) {
  1334. dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
  1335. err = -ENODEV;
  1336. goto exit_free;
  1337. }
  1338. /* If it is a 71862 and the fan / pwm part is enabled sanity check
  1339. the pwm settings */
  1340. if (data->type == f71862fg && (start_reg & 0x02)) {
  1341. u8 reg = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1342. if ((reg & 0x15) != 0x15) {
  1343. dev_err(&pdev->dev,
  1344. "Invalid (reserved) pwm settings: 0x%02x\n",
  1345. (unsigned int)reg);
  1346. err = -ENODEV;
  1347. goto exit_free;
  1348. }
  1349. }
  1350. /* Register sysfs interface files */
  1351. err = device_create_file(&pdev->dev, &dev_attr_name);
  1352. if (err)
  1353. goto exit_unregister_sysfs;
  1354. if (start_reg & 0x01) {
  1355. err = f71882fg_create_sysfs_files(pdev, f718x2fg_in_temp_attr,
  1356. ARRAY_SIZE(f718x2fg_in_temp_attr));
  1357. if (err)
  1358. goto exit_unregister_sysfs;
  1359. if (data->type == f71882fg) {
  1360. err = f71882fg_create_sysfs_files(pdev,
  1361. f71882fg_in_temp_attr,
  1362. ARRAY_SIZE(f71882fg_in_temp_attr));
  1363. if (err)
  1364. goto exit_unregister_sysfs;
  1365. }
  1366. }
  1367. if (start_reg & 0x02) {
  1368. err = f71882fg_create_sysfs_files(pdev, f718x2fg_fan_attr,
  1369. ARRAY_SIZE(f718x2fg_fan_attr));
  1370. if (err)
  1371. goto exit_unregister_sysfs;
  1372. if (data->type == f71862fg) {
  1373. err = f71882fg_create_sysfs_files(pdev,
  1374. f71862fg_fan_attr,
  1375. ARRAY_SIZE(f71862fg_fan_attr));
  1376. } else {
  1377. err = f71882fg_create_sysfs_files(pdev,
  1378. f71882fg_fan_attr,
  1379. ARRAY_SIZE(f71882fg_fan_attr));
  1380. }
  1381. if (err)
  1382. goto exit_unregister_sysfs;
  1383. }
  1384. data->hwmon_dev = hwmon_device_register(&pdev->dev);
  1385. if (IS_ERR(data->hwmon_dev)) {
  1386. err = PTR_ERR(data->hwmon_dev);
  1387. data->hwmon_dev = NULL;
  1388. goto exit_unregister_sysfs;
  1389. }
  1390. return 0;
  1391. exit_unregister_sysfs:
  1392. f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
  1393. return err; /* f71882fg_remove() also frees our data */
  1394. exit_free:
  1395. kfree(data);
  1396. return err;
  1397. }
  1398. static int f71882fg_remove(struct platform_device *pdev)
  1399. {
  1400. int i;
  1401. struct f71882fg_data *data = platform_get_drvdata(pdev);
  1402. platform_set_drvdata(pdev, NULL);
  1403. if (data->hwmon_dev)
  1404. hwmon_device_unregister(data->hwmon_dev);
  1405. device_remove_file(&pdev->dev, &dev_attr_name);
  1406. for (i = 0; i < ARRAY_SIZE(f718x2fg_in_temp_attr); i++)
  1407. device_remove_file(&pdev->dev,
  1408. &f718x2fg_in_temp_attr[i].dev_attr);
  1409. for (i = 0; i < ARRAY_SIZE(f71882fg_in_temp_attr); i++)
  1410. device_remove_file(&pdev->dev,
  1411. &f71882fg_in_temp_attr[i].dev_attr);
  1412. for (i = 0; i < ARRAY_SIZE(f718x2fg_fan_attr); i++)
  1413. device_remove_file(&pdev->dev, &f718x2fg_fan_attr[i].dev_attr);
  1414. for (i = 0; i < ARRAY_SIZE(f71862fg_fan_attr); i++)
  1415. device_remove_file(&pdev->dev, &f71862fg_fan_attr[i].dev_attr);
  1416. for (i = 0; i < ARRAY_SIZE(f71882fg_fan_attr); i++)
  1417. device_remove_file(&pdev->dev, &f71882fg_fan_attr[i].dev_attr);
  1418. kfree(data);
  1419. return 0;
  1420. }
  1421. static int __init f71882fg_find(int sioaddr, unsigned short *address,
  1422. struct f71882fg_sio_data *sio_data)
  1423. {
  1424. int err = -ENODEV;
  1425. u16 devid;
  1426. superio_enter(sioaddr);
  1427. devid = superio_inw(sioaddr, SIO_REG_MANID);
  1428. if (devid != SIO_FINTEK_ID) {
  1429. printk(KERN_INFO DRVNAME ": Not a Fintek device\n");
  1430. goto exit;
  1431. }
  1432. devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
  1433. switch (devid) {
  1434. case SIO_F71862_ID:
  1435. sio_data->type = f71862fg;
  1436. break;
  1437. case SIO_F71882_ID:
  1438. sio_data->type = f71882fg;
  1439. break;
  1440. default:
  1441. printk(KERN_INFO DRVNAME ": Unsupported Fintek device\n");
  1442. goto exit;
  1443. }
  1444. superio_select(sioaddr, SIO_F71882FG_LD_HWM);
  1445. if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
  1446. printk(KERN_WARNING DRVNAME ": Device not activated\n");
  1447. goto exit;
  1448. }
  1449. *address = superio_inw(sioaddr, SIO_REG_ADDR);
  1450. if (*address == 0)
  1451. {
  1452. printk(KERN_WARNING DRVNAME ": Base address not set\n");
  1453. goto exit;
  1454. }
  1455. *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
  1456. err = 0;
  1457. printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
  1458. f71882fg_names[sio_data->type], (unsigned int)*address,
  1459. (int)superio_inb(sioaddr, SIO_REG_DEVREV));
  1460. exit:
  1461. superio_exit(sioaddr);
  1462. return err;
  1463. }
  1464. static int __init f71882fg_device_add(unsigned short address,
  1465. const struct f71882fg_sio_data *sio_data)
  1466. {
  1467. struct resource res = {
  1468. .start = address,
  1469. .end = address + REGION_LENGTH - 1,
  1470. .flags = IORESOURCE_IO,
  1471. };
  1472. int err;
  1473. f71882fg_pdev = platform_device_alloc(DRVNAME, address);
  1474. if (!f71882fg_pdev)
  1475. return -ENOMEM;
  1476. res.name = f71882fg_pdev->name;
  1477. err = platform_device_add_resources(f71882fg_pdev, &res, 1);
  1478. if (err) {
  1479. printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
  1480. goto exit_device_put;
  1481. }
  1482. err = platform_device_add_data(f71882fg_pdev, sio_data,
  1483. sizeof(struct f71882fg_sio_data));
  1484. if (err) {
  1485. printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
  1486. goto exit_device_put;
  1487. }
  1488. err = platform_device_add(f71882fg_pdev);
  1489. if (err) {
  1490. printk(KERN_ERR DRVNAME ": Device addition failed\n");
  1491. goto exit_device_put;
  1492. }
  1493. return 0;
  1494. exit_device_put:
  1495. platform_device_put(f71882fg_pdev);
  1496. return err;
  1497. }
  1498. static int __init f71882fg_init(void)
  1499. {
  1500. int err = -ENODEV;
  1501. unsigned short address;
  1502. struct f71882fg_sio_data sio_data;
  1503. memset(&sio_data, 0, sizeof(sio_data));
  1504. if (f71882fg_find(0x2e, &address, &sio_data) &&
  1505. f71882fg_find(0x4e, &address, &sio_data))
  1506. goto exit;
  1507. err = platform_driver_register(&f71882fg_driver);
  1508. if (err)
  1509. goto exit;
  1510. err = f71882fg_device_add(address, &sio_data);
  1511. if (err)
  1512. goto exit_driver;
  1513. return 0;
  1514. exit_driver:
  1515. platform_driver_unregister(&f71882fg_driver);
  1516. exit:
  1517. return err;
  1518. }
  1519. static void __exit f71882fg_exit(void)
  1520. {
  1521. platform_device_unregister(f71882fg_pdev);
  1522. platform_driver_unregister(&f71882fg_driver);
  1523. }
  1524. MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
  1525. MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
  1526. MODULE_LICENSE("GPL");
  1527. module_init(f71882fg_init);
  1528. module_exit(f71882fg_exit);