f71882fg.c 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398
  1. /***************************************************************************
  2. * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
  3. * Copyright (C) 2007-2009 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. #include <linux/acpi.h>
  31. #define DRVNAME "f71882fg"
  32. #define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */
  33. #define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
  34. #define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
  35. #define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
  36. #define SIO_REG_LDSEL 0x07 /* Logical device select */
  37. #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
  38. #define SIO_REG_DEVREV 0x22 /* Device revision */
  39. #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */
  40. #define SIO_REG_ENABLE 0x30 /* Logical device enable */
  41. #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
  42. #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
  43. #define SIO_F71808_ID 0x0901 /* Chipset ID */
  44. #define SIO_F71858_ID 0x0507 /* Chipset ID */
  45. #define SIO_F71862_ID 0x0601 /* Chipset ID */
  46. #define SIO_F71882_ID 0x0541 /* Chipset ID */
  47. #define SIO_F71889_ID 0x0723 /* Chipset ID */
  48. #define SIO_F8000_ID 0x0581 /* Chipset ID */
  49. #define REGION_LENGTH 8
  50. #define ADDR_REG_OFFSET 5
  51. #define DATA_REG_OFFSET 6
  52. #define F71882FG_REG_PECI 0x0A
  53. #define F71882FG_REG_IN_STATUS 0x12 /* f71882fg only */
  54. #define F71882FG_REG_IN_BEEP 0x13 /* f71882fg only */
  55. #define F71882FG_REG_IN(nr) (0x20 + (nr))
  56. #define F71882FG_REG_IN1_HIGH 0x32 /* f71882fg only */
  57. #define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr)))
  58. #define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr)))
  59. #define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr)))
  60. #define F71882FG_REG_FAN_STATUS 0x92
  61. #define F71882FG_REG_FAN_BEEP 0x93
  62. #define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr))
  63. #define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr))
  64. #define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
  65. #define F71882FG_REG_TEMP_STATUS 0x62
  66. #define F71882FG_REG_TEMP_BEEP 0x63
  67. #define F71882FG_REG_TEMP_CONFIG 0x69
  68. #define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
  69. #define F71882FG_REG_TEMP_TYPE 0x6B
  70. #define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
  71. #define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr)))
  72. #define F71882FG_REG_PWM_TYPE 0x94
  73. #define F71882FG_REG_PWM_ENABLE 0x96
  74. #define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr))
  75. #define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm)))
  76. #define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm)))
  77. #define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr))
  78. #define F71882FG_REG_START 0x01
  79. #define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */
  80. static unsigned short force_id;
  81. module_param(force_id, ushort, 0);
  82. MODULE_PARM_DESC(force_id, "Override the detected device ID");
  83. enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 };
  84. static const char *f71882fg_names[] = {
  85. "f71808fg",
  86. "f71858fg",
  87. "f71862fg",
  88. "f71882fg",
  89. "f71889fg",
  90. "f8000",
  91. };
  92. static struct platform_device *f71882fg_pdev;
  93. /* Super-I/O Function prototypes */
  94. static inline int superio_inb(int base, int reg);
  95. static inline int superio_inw(int base, int reg);
  96. static inline void superio_enter(int base);
  97. static inline void superio_select(int base, int ld);
  98. static inline void superio_exit(int base);
  99. struct f71882fg_sio_data {
  100. enum chips type;
  101. };
  102. struct f71882fg_data {
  103. unsigned short addr;
  104. enum chips type;
  105. struct device *hwmon_dev;
  106. struct mutex update_lock;
  107. int temp_start; /* temp numbering start (0 or 1) */
  108. char valid; /* !=0 if following fields are valid */
  109. unsigned long last_updated; /* In jiffies */
  110. unsigned long last_limits; /* In jiffies */
  111. /* Register Values */
  112. u8 in[9];
  113. u8 in1_max;
  114. u8 in_status;
  115. u8 in_beep;
  116. u16 fan[4];
  117. u16 fan_target[4];
  118. u16 fan_full_speed[4];
  119. u8 fan_status;
  120. u8 fan_beep;
  121. /* Note: all models have only 3 temperature channels, but on some
  122. they are addressed as 0-2 and on others as 1-3, so for coding
  123. convenience we reserve space for 4 channels */
  124. u16 temp[4];
  125. u8 temp_ovt[4];
  126. u8 temp_high[4];
  127. u8 temp_hyst[2]; /* 2 hysts stored per reg */
  128. u8 temp_type[4];
  129. u8 temp_status;
  130. u8 temp_beep;
  131. u8 temp_diode_open;
  132. u8 temp_config;
  133. u8 pwm[4];
  134. u8 pwm_enable;
  135. u8 pwm_auto_point_hyst[2];
  136. u8 pwm_auto_point_mapping[4];
  137. u8 pwm_auto_point_pwm[4][5];
  138. s8 pwm_auto_point_temp[4][4];
  139. };
  140. /* Sysfs in */
  141. static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
  142. char *buf);
  143. static ssize_t show_in_max(struct device *dev, struct device_attribute
  144. *devattr, char *buf);
  145. static ssize_t store_in_max(struct device *dev, struct device_attribute
  146. *devattr, const char *buf, size_t count);
  147. static ssize_t show_in_beep(struct device *dev, struct device_attribute
  148. *devattr, char *buf);
  149. static ssize_t store_in_beep(struct device *dev, struct device_attribute
  150. *devattr, const char *buf, size_t count);
  151. static ssize_t show_in_alarm(struct device *dev, struct device_attribute
  152. *devattr, char *buf);
  153. /* Sysfs Fan */
  154. static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
  155. char *buf);
  156. static ssize_t show_fan_full_speed(struct device *dev,
  157. struct device_attribute *devattr, char *buf);
  158. static ssize_t store_fan_full_speed(struct device *dev,
  159. struct device_attribute *devattr, const char *buf, size_t count);
  160. static ssize_t show_fan_beep(struct device *dev, struct device_attribute
  161. *devattr, char *buf);
  162. static ssize_t store_fan_beep(struct device *dev, struct device_attribute
  163. *devattr, const char *buf, size_t count);
  164. static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
  165. *devattr, char *buf);
  166. /* Sysfs Temp */
  167. static ssize_t show_temp(struct device *dev, struct device_attribute
  168. *devattr, char *buf);
  169. static ssize_t show_temp_max(struct device *dev, struct device_attribute
  170. *devattr, char *buf);
  171. static ssize_t store_temp_max(struct device *dev, struct device_attribute
  172. *devattr, const char *buf, size_t count);
  173. static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
  174. *devattr, char *buf);
  175. static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
  176. *devattr, const char *buf, size_t count);
  177. static ssize_t show_temp_crit(struct device *dev, struct device_attribute
  178. *devattr, char *buf);
  179. static ssize_t store_temp_crit(struct device *dev, struct device_attribute
  180. *devattr, const char *buf, size_t count);
  181. static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
  182. *devattr, char *buf);
  183. static ssize_t show_temp_type(struct device *dev, struct device_attribute
  184. *devattr, char *buf);
  185. static ssize_t show_temp_beep(struct device *dev, struct device_attribute
  186. *devattr, char *buf);
  187. static ssize_t store_temp_beep(struct device *dev, struct device_attribute
  188. *devattr, const char *buf, size_t count);
  189. static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
  190. *devattr, char *buf);
  191. static ssize_t show_temp_fault(struct device *dev, struct device_attribute
  192. *devattr, char *buf);
  193. /* PWM and Auto point control */
  194. static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr,
  195. char *buf);
  196. static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
  197. const char *buf, size_t count);
  198. static ssize_t show_pwm_enable(struct device *dev,
  199. struct device_attribute *devattr, char *buf);
  200. static ssize_t store_pwm_enable(struct device *dev,
  201. struct device_attribute *devattr, const char *buf, size_t count);
  202. static ssize_t show_pwm_interpolate(struct device *dev,
  203. struct device_attribute *devattr, char *buf);
  204. static ssize_t store_pwm_interpolate(struct device *dev,
  205. struct device_attribute *devattr, const char *buf, size_t count);
  206. static ssize_t show_pwm_auto_point_channel(struct device *dev,
  207. struct device_attribute *devattr, char *buf);
  208. static ssize_t store_pwm_auto_point_channel(struct device *dev,
  209. struct device_attribute *devattr, const char *buf, size_t count);
  210. static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
  211. struct device_attribute *devattr, char *buf);
  212. static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
  213. struct device_attribute *devattr, const char *buf, size_t count);
  214. static ssize_t show_pwm_auto_point_pwm(struct device *dev,
  215. struct device_attribute *devattr, char *buf);
  216. static ssize_t store_pwm_auto_point_pwm(struct device *dev,
  217. struct device_attribute *devattr, const char *buf, size_t count);
  218. static ssize_t show_pwm_auto_point_temp(struct device *dev,
  219. struct device_attribute *devattr, char *buf);
  220. static ssize_t store_pwm_auto_point_temp(struct device *dev,
  221. struct device_attribute *devattr, const char *buf, size_t count);
  222. /* Sysfs misc */
  223. static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
  224. char *buf);
  225. static int __devinit f71882fg_probe(struct platform_device * pdev);
  226. static int f71882fg_remove(struct platform_device *pdev);
  227. static struct platform_driver f71882fg_driver = {
  228. .driver = {
  229. .owner = THIS_MODULE,
  230. .name = DRVNAME,
  231. },
  232. .probe = f71882fg_probe,
  233. .remove = f71882fg_remove,
  234. };
  235. static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
  236. /* Temp and in attr for the f71858fg, the f71858fg is special as it
  237. has its temperature indexes start at 0 (the others start at 1) and
  238. it only has 3 voltage inputs */
  239. static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
  240. SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
  241. SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
  242. SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
  243. SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
  244. SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
  245. store_temp_max, 0, 0),
  246. SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  247. store_temp_max_hyst, 0, 0),
  248. SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
  249. SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  250. store_temp_crit, 0, 0),
  251. SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  252. 0, 0),
  253. SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
  254. SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
  255. SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
  256. SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
  257. store_temp_max, 0, 1),
  258. SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  259. store_temp_max_hyst, 0, 1),
  260. SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
  261. SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  262. store_temp_crit, 0, 1),
  263. SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  264. 0, 1),
  265. SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
  266. SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
  267. SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
  268. SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
  269. SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
  270. store_temp_max, 0, 2),
  271. SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  272. store_temp_max_hyst, 0, 2),
  273. SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
  274. SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  275. store_temp_crit, 0, 2),
  276. SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  277. 0, 2),
  278. SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
  279. SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
  280. };
  281. /* In attr common to the f71862fg, f71882fg and f71889fg */
  282. static struct sensor_device_attribute_2 fxxxx_in_attr[] = {
  283. SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
  284. SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
  285. SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
  286. SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
  287. SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
  288. SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
  289. SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6),
  290. SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7),
  291. SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8),
  292. };
  293. /* In attr for the f71808fg */
  294. static struct sensor_device_attribute_2 f71808_in_attr[] = {
  295. SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
  296. SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
  297. SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
  298. SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3),
  299. SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4),
  300. SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5),
  301. SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7),
  302. SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8),
  303. };
  304. /* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */
  305. static struct sensor_device_attribute_2 fxxxx_temp_attr[] = {
  306. SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1),
  307. SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
  308. store_temp_max, 0, 1),
  309. SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  310. store_temp_max_hyst, 0, 1),
  311. /* Should really be temp1_max_alarm, but older versions did not handle
  312. the max and crit alarms separately and lm_sensors v2 depends on the
  313. presence of temp#_alarm files. The same goes for temp2/3 _alarm. */
  314. SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
  315. SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  316. store_temp_beep, 0, 1),
  317. SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  318. store_temp_crit, 0, 1),
  319. SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  320. 0, 1),
  321. SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
  322. SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  323. store_temp_beep, 0, 5),
  324. SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1),
  325. SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
  326. SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2),
  327. SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
  328. store_temp_max, 0, 2),
  329. SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  330. store_temp_max_hyst, 0, 2),
  331. /* Should be temp2_max_alarm, see temp1_alarm note */
  332. SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
  333. SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  334. store_temp_beep, 0, 2),
  335. SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  336. store_temp_crit, 0, 2),
  337. SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  338. 0, 2),
  339. SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
  340. SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  341. store_temp_beep, 0, 6),
  342. SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2),
  343. SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
  344. };
  345. /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */
  346. static struct sensor_device_attribute_2 f71862_temp_attr[] = {
  347. SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3),
  348. SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
  349. store_temp_max, 0, 3),
  350. SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
  351. store_temp_max_hyst, 0, 3),
  352. /* Should be temp3_max_alarm, see temp1_alarm note */
  353. SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3),
  354. SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  355. store_temp_beep, 0, 3),
  356. SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
  357. store_temp_crit, 0, 3),
  358. SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
  359. 0, 3),
  360. SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7),
  361. SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep,
  362. store_temp_beep, 0, 7),
  363. SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3),
  364. SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3),
  365. };
  366. /* For models with in1 alarm capability */
  367. static struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = {
  368. SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max,
  369. 0, 1),
  370. SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep,
  371. 0, 1),
  372. SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1),
  373. };
  374. /* Temp and in attr for the f8000
  375. Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max)
  376. is used as hysteresis value to clear alarms
  377. Also like the f71858fg its temperature indexes start at 0
  378. */
  379. static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
  380. SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
  381. SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
  382. SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
  383. SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
  384. SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit,
  385. store_temp_crit, 0, 0),
  386. SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
  387. store_temp_max, 0, 0),
  388. SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
  389. SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
  390. SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
  391. SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
  392. store_temp_crit, 0, 1),
  393. SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
  394. store_temp_max, 0, 1),
  395. SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
  396. SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
  397. SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
  398. SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
  399. SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
  400. store_temp_crit, 0, 2),
  401. SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
  402. store_temp_max, 0, 2),
  403. SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
  404. SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
  405. };
  406. /* Fan / PWM attr common to all models */
  407. static struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { {
  408. SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0),
  409. SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR,
  410. show_fan_full_speed,
  411. store_fan_full_speed, 0, 0),
  412. SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0),
  413. SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0),
  414. SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  415. store_pwm_enable, 0, 0),
  416. SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR,
  417. show_pwm_interpolate, store_pwm_interpolate, 0, 0),
  418. }, {
  419. SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1),
  420. SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR,
  421. show_fan_full_speed,
  422. store_fan_full_speed, 0, 1),
  423. SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1),
  424. SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1),
  425. SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  426. store_pwm_enable, 0, 1),
  427. SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR,
  428. show_pwm_interpolate, store_pwm_interpolate, 0, 1),
  429. }, {
  430. SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
  431. SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR,
  432. show_fan_full_speed,
  433. store_fan_full_speed, 0, 2),
  434. SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
  435. SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
  436. SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  437. store_pwm_enable, 0, 2),
  438. SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
  439. show_pwm_interpolate, store_pwm_interpolate, 0, 2),
  440. }, {
  441. SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
  442. SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
  443. show_fan_full_speed,
  444. store_fan_full_speed, 0, 3),
  445. SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
  446. SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
  447. SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
  448. store_pwm_enable, 0, 3),
  449. SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR,
  450. show_pwm_interpolate, store_pwm_interpolate, 0, 3),
  451. } };
  452. /* Attr for models which can beep on Fan alarm */
  453. static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
  454. SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  455. store_fan_beep, 0, 0),
  456. SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  457. store_fan_beep, 0, 1),
  458. SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  459. store_fan_beep, 0, 2),
  460. SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
  461. store_fan_beep, 0, 3),
  462. };
  463. /* PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the
  464. f71858fg / f71882fg / f71889fg */
  465. static struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[] = {
  466. SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
  467. show_pwm_auto_point_channel,
  468. store_pwm_auto_point_channel, 0, 0),
  469. SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
  470. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  471. 1, 0),
  472. SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
  473. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  474. 4, 0),
  475. SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
  476. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  477. 0, 0),
  478. SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
  479. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  480. 3, 0),
  481. SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  482. show_pwm_auto_point_temp_hyst,
  483. store_pwm_auto_point_temp_hyst,
  484. 0, 0),
  485. SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
  486. show_pwm_auto_point_temp_hyst, NULL, 3, 0),
  487. SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
  488. show_pwm_auto_point_channel,
  489. store_pwm_auto_point_channel, 0, 1),
  490. SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
  491. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  492. 1, 1),
  493. SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
  494. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  495. 4, 1),
  496. SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
  497. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  498. 0, 1),
  499. SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
  500. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  501. 3, 1),
  502. SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  503. show_pwm_auto_point_temp_hyst,
  504. store_pwm_auto_point_temp_hyst,
  505. 0, 1),
  506. SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
  507. show_pwm_auto_point_temp_hyst, NULL, 3, 1),
  508. SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
  509. show_pwm_auto_point_channel,
  510. store_pwm_auto_point_channel, 0, 2),
  511. SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
  512. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  513. 1, 2),
  514. SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
  515. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  516. 4, 2),
  517. SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
  518. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  519. 0, 2),
  520. SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
  521. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  522. 3, 2),
  523. SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  524. show_pwm_auto_point_temp_hyst,
  525. store_pwm_auto_point_temp_hyst,
  526. 0, 2),
  527. SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
  528. show_pwm_auto_point_temp_hyst, NULL, 3, 2),
  529. };
  530. /* PWM attr common to the f71858fg, f71882fg and f71889fg */
  531. static struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { {
  532. SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
  533. show_pwm_auto_point_channel,
  534. store_pwm_auto_point_channel, 0, 0),
  535. SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
  536. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  537. 0, 0),
  538. SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR,
  539. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  540. 1, 0),
  541. SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR,
  542. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  543. 2, 0),
  544. SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR,
  545. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  546. 3, 0),
  547. SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR,
  548. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  549. 4, 0),
  550. SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR,
  551. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  552. 0, 0),
  553. SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR,
  554. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  555. 1, 0),
  556. SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR,
  557. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  558. 2, 0),
  559. SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR,
  560. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  561. 3, 0),
  562. SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  563. show_pwm_auto_point_temp_hyst,
  564. store_pwm_auto_point_temp_hyst,
  565. 0, 0),
  566. SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO,
  567. show_pwm_auto_point_temp_hyst, NULL, 1, 0),
  568. SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO,
  569. show_pwm_auto_point_temp_hyst, NULL, 2, 0),
  570. SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO,
  571. show_pwm_auto_point_temp_hyst, NULL, 3, 0),
  572. }, {
  573. SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
  574. show_pwm_auto_point_channel,
  575. store_pwm_auto_point_channel, 0, 1),
  576. SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR,
  577. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  578. 0, 1),
  579. SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR,
  580. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  581. 1, 1),
  582. SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR,
  583. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  584. 2, 1),
  585. SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR,
  586. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  587. 3, 1),
  588. SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR,
  589. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  590. 4, 1),
  591. SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR,
  592. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  593. 0, 1),
  594. SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR,
  595. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  596. 1, 1),
  597. SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR,
  598. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  599. 2, 1),
  600. SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR,
  601. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  602. 3, 1),
  603. SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  604. show_pwm_auto_point_temp_hyst,
  605. store_pwm_auto_point_temp_hyst,
  606. 0, 1),
  607. SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
  608. show_pwm_auto_point_temp_hyst, NULL, 1, 1),
  609. SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO,
  610. show_pwm_auto_point_temp_hyst, NULL, 2, 1),
  611. SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
  612. show_pwm_auto_point_temp_hyst, NULL, 3, 1),
  613. }, {
  614. SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
  615. show_pwm_auto_point_channel,
  616. store_pwm_auto_point_channel, 0, 2),
  617. SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
  618. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  619. 0, 2),
  620. SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR,
  621. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  622. 1, 2),
  623. SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR,
  624. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  625. 2, 2),
  626. SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR,
  627. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  628. 3, 2),
  629. SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR,
  630. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  631. 4, 2),
  632. SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR,
  633. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  634. 0, 2),
  635. SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR,
  636. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  637. 1, 2),
  638. SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR,
  639. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  640. 2, 2),
  641. SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR,
  642. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  643. 3, 2),
  644. SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  645. show_pwm_auto_point_temp_hyst,
  646. store_pwm_auto_point_temp_hyst,
  647. 0, 2),
  648. SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO,
  649. show_pwm_auto_point_temp_hyst, NULL, 1, 2),
  650. SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO,
  651. show_pwm_auto_point_temp_hyst, NULL, 2, 2),
  652. SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
  653. show_pwm_auto_point_temp_hyst, NULL, 3, 2),
  654. }, {
  655. SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR,
  656. show_pwm_auto_point_channel,
  657. store_pwm_auto_point_channel, 0, 3),
  658. SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR,
  659. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  660. 0, 3),
  661. SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR,
  662. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  663. 1, 3),
  664. SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR,
  665. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  666. 2, 3),
  667. SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR,
  668. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  669. 3, 3),
  670. SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR,
  671. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  672. 4, 3),
  673. SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR,
  674. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  675. 0, 3),
  676. SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR,
  677. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  678. 1, 3),
  679. SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR,
  680. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  681. 2, 3),
  682. SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR,
  683. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  684. 3, 3),
  685. SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  686. show_pwm_auto_point_temp_hyst,
  687. store_pwm_auto_point_temp_hyst,
  688. 0, 3),
  689. SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO,
  690. show_pwm_auto_point_temp_hyst, NULL, 1, 3),
  691. SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO,
  692. show_pwm_auto_point_temp_hyst, NULL, 2, 3),
  693. SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO,
  694. show_pwm_auto_point_temp_hyst, NULL, 3, 3),
  695. } };
  696. /* Fan attr specific to the f8000 (4th fan input can only measure speed) */
  697. static struct sensor_device_attribute_2 f8000_fan_attr[] = {
  698. SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
  699. };
  700. /* PWM attr for the f8000, zones mapped to temp instead of to pwm!
  701. Also the register block at offset A0 maps to TEMP1 (so our temp2, as the
  702. F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 */
  703. static struct sensor_device_attribute_2 f8000_auto_pwm_attr[] = {
  704. SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR,
  705. show_pwm_auto_point_channel,
  706. store_pwm_auto_point_channel, 0, 0),
  707. SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
  708. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  709. 0, 2),
  710. SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR,
  711. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  712. 1, 2),
  713. SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR,
  714. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  715. 2, 2),
  716. SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR,
  717. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  718. 3, 2),
  719. SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR,
  720. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  721. 4, 2),
  722. SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR,
  723. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  724. 0, 2),
  725. SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR,
  726. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  727. 1, 2),
  728. SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR,
  729. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  730. 2, 2),
  731. SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR,
  732. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  733. 3, 2),
  734. SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  735. show_pwm_auto_point_temp_hyst,
  736. store_pwm_auto_point_temp_hyst,
  737. 0, 2),
  738. SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO,
  739. show_pwm_auto_point_temp_hyst, NULL, 1, 2),
  740. SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO,
  741. show_pwm_auto_point_temp_hyst, NULL, 2, 2),
  742. SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO,
  743. show_pwm_auto_point_temp_hyst, NULL, 3, 2),
  744. SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR,
  745. show_pwm_auto_point_channel,
  746. store_pwm_auto_point_channel, 0, 1),
  747. SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR,
  748. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  749. 0, 0),
  750. SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR,
  751. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  752. 1, 0),
  753. SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR,
  754. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  755. 2, 0),
  756. SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR,
  757. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  758. 3, 0),
  759. SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR,
  760. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  761. 4, 0),
  762. SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR,
  763. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  764. 0, 0),
  765. SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR,
  766. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  767. 1, 0),
  768. SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR,
  769. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  770. 2, 0),
  771. SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR,
  772. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  773. 3, 0),
  774. SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  775. show_pwm_auto_point_temp_hyst,
  776. store_pwm_auto_point_temp_hyst,
  777. 0, 0),
  778. SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO,
  779. show_pwm_auto_point_temp_hyst, NULL, 1, 0),
  780. SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO,
  781. show_pwm_auto_point_temp_hyst, NULL, 2, 0),
  782. SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO,
  783. show_pwm_auto_point_temp_hyst, NULL, 3, 0),
  784. SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
  785. show_pwm_auto_point_channel,
  786. store_pwm_auto_point_channel, 0, 2),
  787. SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR,
  788. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  789. 0, 1),
  790. SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR,
  791. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  792. 1, 1),
  793. SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR,
  794. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  795. 2, 1),
  796. SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR,
  797. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  798. 3, 1),
  799. SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR,
  800. show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
  801. 4, 1),
  802. SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR,
  803. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  804. 0, 1),
  805. SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR,
  806. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  807. 1, 1),
  808. SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR,
  809. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  810. 2, 1),
  811. SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR,
  812. show_pwm_auto_point_temp, store_pwm_auto_point_temp,
  813. 3, 1),
  814. SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR,
  815. show_pwm_auto_point_temp_hyst,
  816. store_pwm_auto_point_temp_hyst,
  817. 0, 1),
  818. SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO,
  819. show_pwm_auto_point_temp_hyst, NULL, 1, 1),
  820. SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO,
  821. show_pwm_auto_point_temp_hyst, NULL, 2, 1),
  822. SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO,
  823. show_pwm_auto_point_temp_hyst, NULL, 3, 1),
  824. };
  825. /* Super I/O functions */
  826. static inline int superio_inb(int base, int reg)
  827. {
  828. outb(reg, base);
  829. return inb(base + 1);
  830. }
  831. static int superio_inw(int base, int reg)
  832. {
  833. int val;
  834. val = superio_inb(base, reg) << 8;
  835. val |= superio_inb(base, reg + 1);
  836. return val;
  837. }
  838. static inline void superio_enter(int base)
  839. {
  840. /* according to the datasheet the key must be send twice! */
  841. outb(SIO_UNLOCK_KEY, base);
  842. outb(SIO_UNLOCK_KEY, base);
  843. }
  844. static inline void superio_select(int base, int ld)
  845. {
  846. outb(SIO_REG_LDSEL, base);
  847. outb(ld, base + 1);
  848. }
  849. static inline void superio_exit(int base)
  850. {
  851. outb(SIO_LOCK_KEY, base);
  852. }
  853. static inline int fan_from_reg(u16 reg)
  854. {
  855. return reg ? (1500000 / reg) : 0;
  856. }
  857. static inline u16 fan_to_reg(int fan)
  858. {
  859. return fan ? (1500000 / fan) : 0;
  860. }
  861. static u8 f71882fg_read8(struct f71882fg_data *data, u8 reg)
  862. {
  863. u8 val;
  864. outb(reg, data->addr + ADDR_REG_OFFSET);
  865. val = inb(data->addr + DATA_REG_OFFSET);
  866. return val;
  867. }
  868. static u16 f71882fg_read16(struct f71882fg_data *data, u8 reg)
  869. {
  870. u16 val;
  871. val = f71882fg_read8(data, reg) << 8;
  872. val |= f71882fg_read8(data, reg + 1);
  873. return val;
  874. }
  875. static void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val)
  876. {
  877. outb(reg, data->addr + ADDR_REG_OFFSET);
  878. outb(val, data->addr + DATA_REG_OFFSET);
  879. }
  880. static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
  881. {
  882. f71882fg_write8(data, reg, val >> 8);
  883. f71882fg_write8(data, reg + 1, val & 0xff);
  884. }
  885. static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
  886. {
  887. if (data->type == f71858fg)
  888. return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
  889. else
  890. return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
  891. }
  892. static struct f71882fg_data *f71882fg_update_device(struct device *dev)
  893. {
  894. struct f71882fg_data *data = dev_get_drvdata(dev);
  895. int nr, reg = 0, reg2;
  896. int nr_fans = (data->type == f71882fg) ? 4 : 3;
  897. int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9;
  898. mutex_lock(&data->update_lock);
  899. /* Update once every 60 seconds */
  900. if (time_after(jiffies, data->last_limits + 60 * HZ) ||
  901. !data->valid) {
  902. if (data->type == f71882fg || data->type == f71889fg) {
  903. data->in1_max =
  904. f71882fg_read8(data, F71882FG_REG_IN1_HIGH);
  905. data->in_beep =
  906. f71882fg_read8(data, F71882FG_REG_IN_BEEP);
  907. }
  908. /* Get High & boundary temps*/
  909. for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) {
  910. data->temp_ovt[nr] = f71882fg_read8(data,
  911. F71882FG_REG_TEMP_OVT(nr));
  912. data->temp_high[nr] = f71882fg_read8(data,
  913. F71882FG_REG_TEMP_HIGH(nr));
  914. }
  915. if (data->type != f8000) {
  916. data->temp_hyst[0] = f71882fg_read8(data,
  917. F71882FG_REG_TEMP_HYST(0));
  918. data->temp_hyst[1] = f71882fg_read8(data,
  919. F71882FG_REG_TEMP_HYST(1));
  920. }
  921. if (data->type == f71862fg || data->type == f71882fg ||
  922. data->type == f71889fg) {
  923. data->fan_beep = f71882fg_read8(data,
  924. F71882FG_REG_FAN_BEEP);
  925. data->temp_beep = f71882fg_read8(data,
  926. F71882FG_REG_TEMP_BEEP);
  927. /* Have to hardcode type, because temp1 is special */
  928. reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
  929. data->temp_type[2] = (reg & 0x04) ? 2 : 4;
  930. data->temp_type[3] = (reg & 0x08) ? 2 : 4;
  931. }
  932. /* Determine temp index 1 sensor type */
  933. if (data->type == f71889fg) {
  934. reg2 = f71882fg_read8(data, F71882FG_REG_START);
  935. switch ((reg2 & 0x60) >> 5) {
  936. case 0x00: /* BJT / Thermistor */
  937. data->temp_type[1] = (reg & 0x02) ? 2 : 4;
  938. break;
  939. case 0x01: /* AMDSI */
  940. data->temp_type[1] = 5;
  941. break;
  942. case 0x02: /* PECI */
  943. case 0x03: /* Ibex Peak ?? Report as PECI for now */
  944. data->temp_type[1] = 6;
  945. break;
  946. }
  947. } else if (data->type == f71808fg) {
  948. reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
  949. data->temp_type[1] = (reg & 0x02) ? 2 : 4;
  950. data->temp_type[2] = (reg & 0x04) ? 2 : 4;
  951. } else {
  952. reg2 = f71882fg_read8(data, F71882FG_REG_PECI);
  953. if ((reg2 & 0x03) == 0x01)
  954. data->temp_type[1] = 6; /* PECI */
  955. else if ((reg2 & 0x03) == 0x02)
  956. data->temp_type[1] = 5; /* AMDSI */
  957. else if (data->type == f71862fg ||
  958. data->type == f71882fg)
  959. data->temp_type[1] = (reg & 0x02) ? 2 : 4;
  960. else /* f71858fg and f8000 only support BJT */
  961. data->temp_type[1] = 2;
  962. }
  963. data->pwm_enable = f71882fg_read8(data,
  964. F71882FG_REG_PWM_ENABLE);
  965. data->pwm_auto_point_hyst[0] =
  966. f71882fg_read8(data, F71882FG_REG_FAN_HYST(0));
  967. data->pwm_auto_point_hyst[1] =
  968. f71882fg_read8(data, F71882FG_REG_FAN_HYST(1));
  969. for (nr = 0; nr < nr_fans; nr++) {
  970. data->pwm_auto_point_mapping[nr] =
  971. f71882fg_read8(data,
  972. F71882FG_REG_POINT_MAPPING(nr));
  973. if (data->type != f71862fg) {
  974. int point;
  975. for (point = 0; point < 5; point++) {
  976. data->pwm_auto_point_pwm[nr][point] =
  977. f71882fg_read8(data,
  978. F71882FG_REG_POINT_PWM
  979. (nr, point));
  980. }
  981. for (point = 0; point < 4; point++) {
  982. data->pwm_auto_point_temp[nr][point] =
  983. f71882fg_read8(data,
  984. F71882FG_REG_POINT_TEMP
  985. (nr, point));
  986. }
  987. } else {
  988. data->pwm_auto_point_pwm[nr][1] =
  989. f71882fg_read8(data,
  990. F71882FG_REG_POINT_PWM
  991. (nr, 1));
  992. data->pwm_auto_point_pwm[nr][4] =
  993. f71882fg_read8(data,
  994. F71882FG_REG_POINT_PWM
  995. (nr, 4));
  996. data->pwm_auto_point_temp[nr][0] =
  997. f71882fg_read8(data,
  998. F71882FG_REG_POINT_TEMP
  999. (nr, 0));
  1000. data->pwm_auto_point_temp[nr][3] =
  1001. f71882fg_read8(data,
  1002. F71882FG_REG_POINT_TEMP
  1003. (nr, 3));
  1004. }
  1005. }
  1006. data->last_limits = jiffies;
  1007. }
  1008. /* Update every second */
  1009. if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
  1010. data->temp_status = f71882fg_read8(data,
  1011. F71882FG_REG_TEMP_STATUS);
  1012. data->temp_diode_open = f71882fg_read8(data,
  1013. F71882FG_REG_TEMP_DIODE_OPEN);
  1014. for (nr = data->temp_start; nr < 3 + data->temp_start; nr++)
  1015. data->temp[nr] = f71882fg_read_temp(data, nr);
  1016. data->fan_status = f71882fg_read8(data,
  1017. F71882FG_REG_FAN_STATUS);
  1018. for (nr = 0; nr < nr_fans; nr++) {
  1019. data->fan[nr] = f71882fg_read16(data,
  1020. F71882FG_REG_FAN(nr));
  1021. data->fan_target[nr] =
  1022. f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr));
  1023. data->fan_full_speed[nr] =
  1024. f71882fg_read16(data,
  1025. F71882FG_REG_FAN_FULL_SPEED(nr));
  1026. data->pwm[nr] =
  1027. f71882fg_read8(data, F71882FG_REG_PWM(nr));
  1028. }
  1029. /* The f8000 can monitor 1 more fan, but has no pwm for it */
  1030. if (data->type == f8000)
  1031. data->fan[3] = f71882fg_read16(data,
  1032. F71882FG_REG_FAN(3));
  1033. if (data->type == f71882fg || data->type == f71889fg)
  1034. data->in_status = f71882fg_read8(data,
  1035. F71882FG_REG_IN_STATUS);
  1036. for (nr = 0; nr < nr_ins; nr++)
  1037. data->in[nr] = f71882fg_read8(data,
  1038. F71882FG_REG_IN(nr));
  1039. data->last_updated = jiffies;
  1040. data->valid = 1;
  1041. }
  1042. mutex_unlock(&data->update_lock);
  1043. return data;
  1044. }
  1045. /* Sysfs Interface */
  1046. static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
  1047. char *buf)
  1048. {
  1049. struct f71882fg_data *data = f71882fg_update_device(dev);
  1050. int nr = to_sensor_dev_attr_2(devattr)->index;
  1051. int speed = fan_from_reg(data->fan[nr]);
  1052. if (speed == FAN_MIN_DETECT)
  1053. speed = 0;
  1054. return sprintf(buf, "%d\n", speed);
  1055. }
  1056. static ssize_t show_fan_full_speed(struct device *dev,
  1057. struct device_attribute *devattr, char *buf)
  1058. {
  1059. struct f71882fg_data *data = f71882fg_update_device(dev);
  1060. int nr = to_sensor_dev_attr_2(devattr)->index;
  1061. int speed = fan_from_reg(data->fan_full_speed[nr]);
  1062. return sprintf(buf, "%d\n", speed);
  1063. }
  1064. static ssize_t store_fan_full_speed(struct device *dev,
  1065. struct device_attribute *devattr,
  1066. const char *buf, size_t count)
  1067. {
  1068. struct f71882fg_data *data = dev_get_drvdata(dev);
  1069. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1070. long val;
  1071. err = strict_strtol(buf, 10, &val);
  1072. if (err)
  1073. return err;
  1074. val = SENSORS_LIMIT(val, 23, 1500000);
  1075. val = fan_to_reg(val);
  1076. mutex_lock(&data->update_lock);
  1077. f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val);
  1078. data->fan_full_speed[nr] = val;
  1079. mutex_unlock(&data->update_lock);
  1080. return count;
  1081. }
  1082. static ssize_t show_fan_beep(struct device *dev, struct device_attribute
  1083. *devattr, char *buf)
  1084. {
  1085. struct f71882fg_data *data = f71882fg_update_device(dev);
  1086. int nr = to_sensor_dev_attr_2(devattr)->index;
  1087. if (data->fan_beep & (1 << nr))
  1088. return sprintf(buf, "1\n");
  1089. else
  1090. return sprintf(buf, "0\n");
  1091. }
  1092. static ssize_t store_fan_beep(struct device *dev, struct device_attribute
  1093. *devattr, const char *buf, size_t count)
  1094. {
  1095. struct f71882fg_data *data = dev_get_drvdata(dev);
  1096. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1097. unsigned long val;
  1098. err = strict_strtoul(buf, 10, &val);
  1099. if (err)
  1100. return err;
  1101. mutex_lock(&data->update_lock);
  1102. data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP);
  1103. if (val)
  1104. data->fan_beep |= 1 << nr;
  1105. else
  1106. data->fan_beep &= ~(1 << nr);
  1107. f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep);
  1108. mutex_unlock(&data->update_lock);
  1109. return count;
  1110. }
  1111. static ssize_t show_fan_alarm(struct device *dev, struct device_attribute
  1112. *devattr, char *buf)
  1113. {
  1114. struct f71882fg_data *data = f71882fg_update_device(dev);
  1115. int nr = to_sensor_dev_attr_2(devattr)->index;
  1116. if (data->fan_status & (1 << nr))
  1117. return sprintf(buf, "1\n");
  1118. else
  1119. return sprintf(buf, "0\n");
  1120. }
  1121. static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
  1122. char *buf)
  1123. {
  1124. struct f71882fg_data *data = f71882fg_update_device(dev);
  1125. int nr = to_sensor_dev_attr_2(devattr)->index;
  1126. return sprintf(buf, "%d\n", data->in[nr] * 8);
  1127. }
  1128. static ssize_t show_in_max(struct device *dev, struct device_attribute
  1129. *devattr, char *buf)
  1130. {
  1131. struct f71882fg_data *data = f71882fg_update_device(dev);
  1132. return sprintf(buf, "%d\n", data->in1_max * 8);
  1133. }
  1134. static ssize_t store_in_max(struct device *dev, struct device_attribute
  1135. *devattr, const char *buf, size_t count)
  1136. {
  1137. struct f71882fg_data *data = dev_get_drvdata(dev);
  1138. int err;
  1139. long val;
  1140. err = strict_strtol(buf, 10, &val);
  1141. if (err)
  1142. return err;
  1143. val /= 8;
  1144. val = SENSORS_LIMIT(val, 0, 255);
  1145. mutex_lock(&data->update_lock);
  1146. f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val);
  1147. data->in1_max = val;
  1148. mutex_unlock(&data->update_lock);
  1149. return count;
  1150. }
  1151. static ssize_t show_in_beep(struct device *dev, struct device_attribute
  1152. *devattr, char *buf)
  1153. {
  1154. struct f71882fg_data *data = f71882fg_update_device(dev);
  1155. int nr = to_sensor_dev_attr_2(devattr)->index;
  1156. if (data->in_beep & (1 << nr))
  1157. return sprintf(buf, "1\n");
  1158. else
  1159. return sprintf(buf, "0\n");
  1160. }
  1161. static ssize_t store_in_beep(struct device *dev, struct device_attribute
  1162. *devattr, const char *buf, size_t count)
  1163. {
  1164. struct f71882fg_data *data = dev_get_drvdata(dev);
  1165. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1166. unsigned long val;
  1167. err = strict_strtoul(buf, 10, &val);
  1168. if (err)
  1169. return err;
  1170. mutex_lock(&data->update_lock);
  1171. data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP);
  1172. if (val)
  1173. data->in_beep |= 1 << nr;
  1174. else
  1175. data->in_beep &= ~(1 << nr);
  1176. f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep);
  1177. mutex_unlock(&data->update_lock);
  1178. return count;
  1179. }
  1180. static ssize_t show_in_alarm(struct device *dev, struct device_attribute
  1181. *devattr, char *buf)
  1182. {
  1183. struct f71882fg_data *data = f71882fg_update_device(dev);
  1184. int nr = to_sensor_dev_attr_2(devattr)->index;
  1185. if (data->in_status & (1 << nr))
  1186. return sprintf(buf, "1\n");
  1187. else
  1188. return sprintf(buf, "0\n");
  1189. }
  1190. static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
  1191. char *buf)
  1192. {
  1193. struct f71882fg_data *data = f71882fg_update_device(dev);
  1194. int nr = to_sensor_dev_attr_2(devattr)->index;
  1195. int sign, temp;
  1196. if (data->type == f71858fg) {
  1197. /* TEMP_TABLE_SEL 1 or 3 ? */
  1198. if (data->temp_config & 1) {
  1199. sign = data->temp[nr] & 0x0001;
  1200. temp = (data->temp[nr] >> 5) & 0x7ff;
  1201. } else {
  1202. sign = data->temp[nr] & 0x8000;
  1203. temp = (data->temp[nr] >> 5) & 0x3ff;
  1204. }
  1205. temp *= 125;
  1206. if (sign)
  1207. temp -= 128000;
  1208. } else
  1209. temp = data->temp[nr] * 1000;
  1210. return sprintf(buf, "%d\n", temp);
  1211. }
  1212. static ssize_t show_temp_max(struct device *dev, struct device_attribute
  1213. *devattr, char *buf)
  1214. {
  1215. struct f71882fg_data *data = f71882fg_update_device(dev);
  1216. int nr = to_sensor_dev_attr_2(devattr)->index;
  1217. return sprintf(buf, "%d\n", data->temp_high[nr] * 1000);
  1218. }
  1219. static ssize_t store_temp_max(struct device *dev, struct device_attribute
  1220. *devattr, const char *buf, size_t count)
  1221. {
  1222. struct f71882fg_data *data = dev_get_drvdata(dev);
  1223. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1224. long val;
  1225. err = strict_strtol(buf, 10, &val);
  1226. if (err)
  1227. return err;
  1228. val /= 1000;
  1229. val = SENSORS_LIMIT(val, 0, 255);
  1230. mutex_lock(&data->update_lock);
  1231. f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val);
  1232. data->temp_high[nr] = val;
  1233. mutex_unlock(&data->update_lock);
  1234. return count;
  1235. }
  1236. static ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute
  1237. *devattr, char *buf)
  1238. {
  1239. struct f71882fg_data *data = f71882fg_update_device(dev);
  1240. int nr = to_sensor_dev_attr_2(devattr)->index;
  1241. int temp_max_hyst;
  1242. mutex_lock(&data->update_lock);
  1243. if (nr & 1)
  1244. temp_max_hyst = data->temp_hyst[nr / 2] >> 4;
  1245. else
  1246. temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f;
  1247. temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000;
  1248. mutex_unlock(&data->update_lock);
  1249. return sprintf(buf, "%d\n", temp_max_hyst);
  1250. }
  1251. static ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute
  1252. *devattr, const char *buf, size_t count)
  1253. {
  1254. struct f71882fg_data *data = dev_get_drvdata(dev);
  1255. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1256. ssize_t ret = count;
  1257. u8 reg;
  1258. long val;
  1259. err = strict_strtol(buf, 10, &val);
  1260. if (err)
  1261. return err;
  1262. val /= 1000;
  1263. mutex_lock(&data->update_lock);
  1264. /* convert abs to relative and check */
  1265. data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr));
  1266. val = SENSORS_LIMIT(val, data->temp_high[nr] - 15,
  1267. data->temp_high[nr]);
  1268. val = data->temp_high[nr] - val;
  1269. /* convert value to register contents */
  1270. reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2));
  1271. if (nr & 1)
  1272. reg = (reg & 0x0f) | (val << 4);
  1273. else
  1274. reg = (reg & 0xf0) | val;
  1275. f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg);
  1276. data->temp_hyst[nr / 2] = reg;
  1277. mutex_unlock(&data->update_lock);
  1278. return ret;
  1279. }
  1280. static ssize_t show_temp_crit(struct device *dev, struct device_attribute
  1281. *devattr, char *buf)
  1282. {
  1283. struct f71882fg_data *data = f71882fg_update_device(dev);
  1284. int nr = to_sensor_dev_attr_2(devattr)->index;
  1285. return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000);
  1286. }
  1287. static ssize_t store_temp_crit(struct device *dev, struct device_attribute
  1288. *devattr, const char *buf, size_t count)
  1289. {
  1290. struct f71882fg_data *data = dev_get_drvdata(dev);
  1291. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1292. long val;
  1293. err = strict_strtol(buf, 10, &val);
  1294. if (err)
  1295. return err;
  1296. val /= 1000;
  1297. val = SENSORS_LIMIT(val, 0, 255);
  1298. mutex_lock(&data->update_lock);
  1299. f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val);
  1300. data->temp_ovt[nr] = val;
  1301. mutex_unlock(&data->update_lock);
  1302. return count;
  1303. }
  1304. static ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute
  1305. *devattr, char *buf)
  1306. {
  1307. struct f71882fg_data *data = f71882fg_update_device(dev);
  1308. int nr = to_sensor_dev_attr_2(devattr)->index;
  1309. int temp_crit_hyst;
  1310. mutex_lock(&data->update_lock);
  1311. if (nr & 1)
  1312. temp_crit_hyst = data->temp_hyst[nr / 2] >> 4;
  1313. else
  1314. temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f;
  1315. temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000;
  1316. mutex_unlock(&data->update_lock);
  1317. return sprintf(buf, "%d\n", temp_crit_hyst);
  1318. }
  1319. static ssize_t show_temp_type(struct device *dev, struct device_attribute
  1320. *devattr, char *buf)
  1321. {
  1322. struct f71882fg_data *data = f71882fg_update_device(dev);
  1323. int nr = to_sensor_dev_attr_2(devattr)->index;
  1324. return sprintf(buf, "%d\n", data->temp_type[nr]);
  1325. }
  1326. static ssize_t show_temp_beep(struct device *dev, struct device_attribute
  1327. *devattr, char *buf)
  1328. {
  1329. struct f71882fg_data *data = f71882fg_update_device(dev);
  1330. int nr = to_sensor_dev_attr_2(devattr)->index;
  1331. if (data->temp_beep & (1 << nr))
  1332. return sprintf(buf, "1\n");
  1333. else
  1334. return sprintf(buf, "0\n");
  1335. }
  1336. static ssize_t store_temp_beep(struct device *dev, struct device_attribute
  1337. *devattr, const char *buf, size_t count)
  1338. {
  1339. struct f71882fg_data *data = dev_get_drvdata(dev);
  1340. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1341. unsigned long val;
  1342. err = strict_strtoul(buf, 10, &val);
  1343. if (err)
  1344. return err;
  1345. mutex_lock(&data->update_lock);
  1346. data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP);
  1347. if (val)
  1348. data->temp_beep |= 1 << nr;
  1349. else
  1350. data->temp_beep &= ~(1 << nr);
  1351. f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep);
  1352. mutex_unlock(&data->update_lock);
  1353. return count;
  1354. }
  1355. static ssize_t show_temp_alarm(struct device *dev, struct device_attribute
  1356. *devattr, char *buf)
  1357. {
  1358. struct f71882fg_data *data = f71882fg_update_device(dev);
  1359. int nr = to_sensor_dev_attr_2(devattr)->index;
  1360. if (data->temp_status & (1 << nr))
  1361. return sprintf(buf, "1\n");
  1362. else
  1363. return sprintf(buf, "0\n");
  1364. }
  1365. static ssize_t show_temp_fault(struct device *dev, struct device_attribute
  1366. *devattr, char *buf)
  1367. {
  1368. struct f71882fg_data *data = f71882fg_update_device(dev);
  1369. int nr = to_sensor_dev_attr_2(devattr)->index;
  1370. if (data->temp_diode_open & (1 << nr))
  1371. return sprintf(buf, "1\n");
  1372. else
  1373. return sprintf(buf, "0\n");
  1374. }
  1375. static ssize_t show_pwm(struct device *dev,
  1376. struct device_attribute *devattr, char *buf)
  1377. {
  1378. struct f71882fg_data *data = f71882fg_update_device(dev);
  1379. int val, nr = to_sensor_dev_attr_2(devattr)->index;
  1380. mutex_lock(&data->update_lock);
  1381. if (data->pwm_enable & (1 << (2 * nr)))
  1382. /* PWM mode */
  1383. val = data->pwm[nr];
  1384. else {
  1385. /* RPM mode */
  1386. val = 255 * fan_from_reg(data->fan_target[nr])
  1387. / fan_from_reg(data->fan_full_speed[nr]);
  1388. }
  1389. mutex_unlock(&data->update_lock);
  1390. return sprintf(buf, "%d\n", val);
  1391. }
  1392. static ssize_t store_pwm(struct device *dev,
  1393. struct device_attribute *devattr, const char *buf,
  1394. size_t count)
  1395. {
  1396. struct f71882fg_data *data = dev_get_drvdata(dev);
  1397. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1398. long val;
  1399. err = strict_strtol(buf, 10, &val);
  1400. if (err)
  1401. return err;
  1402. val = SENSORS_LIMIT(val, 0, 255);
  1403. mutex_lock(&data->update_lock);
  1404. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1405. if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) ||
  1406. (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) {
  1407. count = -EROFS;
  1408. goto leave;
  1409. }
  1410. if (data->pwm_enable & (1 << (2 * nr))) {
  1411. /* PWM mode */
  1412. f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
  1413. data->pwm[nr] = val;
  1414. } else {
  1415. /* RPM mode */
  1416. int target, full_speed;
  1417. full_speed = f71882fg_read16(data,
  1418. F71882FG_REG_FAN_FULL_SPEED(nr));
  1419. target = fan_to_reg(val * fan_from_reg(full_speed) / 255);
  1420. f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target);
  1421. data->fan_target[nr] = target;
  1422. data->fan_full_speed[nr] = full_speed;
  1423. }
  1424. leave:
  1425. mutex_unlock(&data->update_lock);
  1426. return count;
  1427. }
  1428. static ssize_t show_pwm_enable(struct device *dev,
  1429. struct device_attribute *devattr, char *buf)
  1430. {
  1431. int result = 0;
  1432. struct f71882fg_data *data = f71882fg_update_device(dev);
  1433. int nr = to_sensor_dev_attr_2(devattr)->index;
  1434. switch ((data->pwm_enable >> 2 * nr) & 3) {
  1435. case 0:
  1436. case 1:
  1437. result = 2; /* Normal auto mode */
  1438. break;
  1439. case 2:
  1440. result = 1; /* Manual mode */
  1441. break;
  1442. case 3:
  1443. if (data->type == f8000)
  1444. result = 3; /* Thermostat mode */
  1445. else
  1446. result = 1; /* Manual mode */
  1447. break;
  1448. }
  1449. return sprintf(buf, "%d\n", result);
  1450. }
  1451. static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
  1452. *devattr, const char *buf, size_t count)
  1453. {
  1454. struct f71882fg_data *data = dev_get_drvdata(dev);
  1455. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1456. long val;
  1457. err = strict_strtol(buf, 10, &val);
  1458. if (err)
  1459. return err;
  1460. /* Special case for F8000 pwm channel 3 which only does auto mode */
  1461. if (data->type == f8000 && nr == 2 && val != 2)
  1462. return -EINVAL;
  1463. mutex_lock(&data->update_lock);
  1464. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1465. /* Special case for F8000 auto PWM mode / Thermostat mode */
  1466. if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) {
  1467. switch (val) {
  1468. case 2:
  1469. data->pwm_enable &= ~(2 << (2 * nr));
  1470. break; /* Normal auto mode */
  1471. case 3:
  1472. data->pwm_enable |= 2 << (2 * nr);
  1473. break; /* Thermostat mode */
  1474. default:
  1475. count = -EINVAL;
  1476. goto leave;
  1477. }
  1478. } else {
  1479. switch (val) {
  1480. case 1:
  1481. /* The f71858fg does not support manual RPM mode */
  1482. if (data->type == f71858fg &&
  1483. ((data->pwm_enable >> (2 * nr)) & 1)) {
  1484. count = -EINVAL;
  1485. goto leave;
  1486. }
  1487. data->pwm_enable |= 2 << (2 * nr);
  1488. break; /* Manual */
  1489. case 2:
  1490. data->pwm_enable &= ~(2 << (2 * nr));
  1491. break; /* Normal auto mode */
  1492. default:
  1493. count = -EINVAL;
  1494. goto leave;
  1495. }
  1496. }
  1497. f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable);
  1498. leave:
  1499. mutex_unlock(&data->update_lock);
  1500. return count;
  1501. }
  1502. static ssize_t show_pwm_auto_point_pwm(struct device *dev,
  1503. struct device_attribute *devattr,
  1504. char *buf)
  1505. {
  1506. int result;
  1507. struct f71882fg_data *data = f71882fg_update_device(dev);
  1508. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1509. int point = to_sensor_dev_attr_2(devattr)->nr;
  1510. mutex_lock(&data->update_lock);
  1511. if (data->pwm_enable & (1 << (2 * pwm))) {
  1512. /* PWM mode */
  1513. result = data->pwm_auto_point_pwm[pwm][point];
  1514. } else {
  1515. /* RPM mode */
  1516. result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]);
  1517. }
  1518. mutex_unlock(&data->update_lock);
  1519. return sprintf(buf, "%d\n", result);
  1520. }
  1521. static ssize_t store_pwm_auto_point_pwm(struct device *dev,
  1522. struct device_attribute *devattr,
  1523. const char *buf, size_t count)
  1524. {
  1525. struct f71882fg_data *data = dev_get_drvdata(dev);
  1526. int err, pwm = to_sensor_dev_attr_2(devattr)->index;
  1527. int point = to_sensor_dev_attr_2(devattr)->nr;
  1528. long val;
  1529. err = strict_strtol(buf, 10, &val);
  1530. if (err)
  1531. return err;
  1532. val = SENSORS_LIMIT(val, 0, 255);
  1533. mutex_lock(&data->update_lock);
  1534. data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1535. if (data->pwm_enable & (1 << (2 * pwm))) {
  1536. /* PWM mode */
  1537. } else {
  1538. /* RPM mode */
  1539. if (val < 29) /* Prevent negative numbers */
  1540. val = 255;
  1541. else
  1542. val = (255 - val) * 32 / val;
  1543. }
  1544. f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val);
  1545. data->pwm_auto_point_pwm[pwm][point] = val;
  1546. mutex_unlock(&data->update_lock);
  1547. return count;
  1548. }
  1549. static ssize_t show_pwm_auto_point_temp_hyst(struct device *dev,
  1550. struct device_attribute *devattr,
  1551. char *buf)
  1552. {
  1553. int result = 0;
  1554. struct f71882fg_data *data = f71882fg_update_device(dev);
  1555. int nr = to_sensor_dev_attr_2(devattr)->index;
  1556. int point = to_sensor_dev_attr_2(devattr)->nr;
  1557. mutex_lock(&data->update_lock);
  1558. if (nr & 1)
  1559. result = data->pwm_auto_point_hyst[nr / 2] >> 4;
  1560. else
  1561. result = data->pwm_auto_point_hyst[nr / 2] & 0x0f;
  1562. result = 1000 * (data->pwm_auto_point_temp[nr][point] - result);
  1563. mutex_unlock(&data->update_lock);
  1564. return sprintf(buf, "%d\n", result);
  1565. }
  1566. static ssize_t store_pwm_auto_point_temp_hyst(struct device *dev,
  1567. struct device_attribute *devattr,
  1568. const char *buf, size_t count)
  1569. {
  1570. struct f71882fg_data *data = dev_get_drvdata(dev);
  1571. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1572. int point = to_sensor_dev_attr_2(devattr)->nr;
  1573. u8 reg;
  1574. long val;
  1575. err = strict_strtol(buf, 10, &val);
  1576. if (err)
  1577. return err;
  1578. val /= 1000;
  1579. mutex_lock(&data->update_lock);
  1580. data->pwm_auto_point_temp[nr][point] =
  1581. f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point));
  1582. val = SENSORS_LIMIT(val, data->pwm_auto_point_temp[nr][point] - 15,
  1583. data->pwm_auto_point_temp[nr][point]);
  1584. val = data->pwm_auto_point_temp[nr][point] - val;
  1585. reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2));
  1586. if (nr & 1)
  1587. reg = (reg & 0x0f) | (val << 4);
  1588. else
  1589. reg = (reg & 0xf0) | val;
  1590. f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg);
  1591. data->pwm_auto_point_hyst[nr / 2] = reg;
  1592. mutex_unlock(&data->update_lock);
  1593. return count;
  1594. }
  1595. static ssize_t show_pwm_interpolate(struct device *dev,
  1596. struct device_attribute *devattr, char *buf)
  1597. {
  1598. int result;
  1599. struct f71882fg_data *data = f71882fg_update_device(dev);
  1600. int nr = to_sensor_dev_attr_2(devattr)->index;
  1601. result = (data->pwm_auto_point_mapping[nr] >> 4) & 1;
  1602. return sprintf(buf, "%d\n", result);
  1603. }
  1604. static ssize_t store_pwm_interpolate(struct device *dev,
  1605. struct device_attribute *devattr,
  1606. const char *buf, size_t count)
  1607. {
  1608. struct f71882fg_data *data = dev_get_drvdata(dev);
  1609. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1610. unsigned long val;
  1611. err = strict_strtoul(buf, 10, &val);
  1612. if (err)
  1613. return err;
  1614. mutex_lock(&data->update_lock);
  1615. data->pwm_auto_point_mapping[nr] =
  1616. f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
  1617. if (val)
  1618. val = data->pwm_auto_point_mapping[nr] | (1 << 4);
  1619. else
  1620. val = data->pwm_auto_point_mapping[nr] & (~(1 << 4));
  1621. f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
  1622. data->pwm_auto_point_mapping[nr] = val;
  1623. mutex_unlock(&data->update_lock);
  1624. return count;
  1625. }
  1626. static ssize_t show_pwm_auto_point_channel(struct device *dev,
  1627. struct device_attribute *devattr,
  1628. char *buf)
  1629. {
  1630. int result;
  1631. struct f71882fg_data *data = f71882fg_update_device(dev);
  1632. int nr = to_sensor_dev_attr_2(devattr)->index;
  1633. result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
  1634. data->temp_start);
  1635. return sprintf(buf, "%d\n", result);
  1636. }
  1637. static ssize_t store_pwm_auto_point_channel(struct device *dev,
  1638. struct device_attribute *devattr,
  1639. const char *buf, size_t count)
  1640. {
  1641. struct f71882fg_data *data = dev_get_drvdata(dev);
  1642. int err, nr = to_sensor_dev_attr_2(devattr)->index;
  1643. long val;
  1644. err = strict_strtol(buf, 10, &val);
  1645. if (err)
  1646. return err;
  1647. switch (val) {
  1648. case 1:
  1649. val = 0;
  1650. break;
  1651. case 2:
  1652. val = 1;
  1653. break;
  1654. case 4:
  1655. val = 2;
  1656. break;
  1657. default:
  1658. return -EINVAL;
  1659. }
  1660. val += data->temp_start;
  1661. mutex_lock(&data->update_lock);
  1662. data->pwm_auto_point_mapping[nr] =
  1663. f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
  1664. val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val;
  1665. f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val);
  1666. data->pwm_auto_point_mapping[nr] = val;
  1667. mutex_unlock(&data->update_lock);
  1668. return count;
  1669. }
  1670. static ssize_t show_pwm_auto_point_temp(struct device *dev,
  1671. struct device_attribute *devattr,
  1672. char *buf)
  1673. {
  1674. int result;
  1675. struct f71882fg_data *data = f71882fg_update_device(dev);
  1676. int pwm = to_sensor_dev_attr_2(devattr)->index;
  1677. int point = to_sensor_dev_attr_2(devattr)->nr;
  1678. result = data->pwm_auto_point_temp[pwm][point];
  1679. return sprintf(buf, "%d\n", 1000 * result);
  1680. }
  1681. static ssize_t store_pwm_auto_point_temp(struct device *dev,
  1682. struct device_attribute *devattr,
  1683. const char *buf, size_t count)
  1684. {
  1685. struct f71882fg_data *data = dev_get_drvdata(dev);
  1686. int err, pwm = to_sensor_dev_attr_2(devattr)->index;
  1687. int point = to_sensor_dev_attr_2(devattr)->nr;
  1688. long val;
  1689. err = strict_strtol(buf, 10, &val);
  1690. if (err)
  1691. return err;
  1692. val /= 1000;
  1693. if (data->type == f71889fg
  1694. || data->type == f71808fg)
  1695. val = SENSORS_LIMIT(val, -128, 127);
  1696. else
  1697. val = SENSORS_LIMIT(val, 0, 127);
  1698. mutex_lock(&data->update_lock);
  1699. f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val);
  1700. data->pwm_auto_point_temp[pwm][point] = val;
  1701. mutex_unlock(&data->update_lock);
  1702. return count;
  1703. }
  1704. static ssize_t show_name(struct device *dev, struct device_attribute *devattr,
  1705. char *buf)
  1706. {
  1707. struct f71882fg_data *data = dev_get_drvdata(dev);
  1708. return sprintf(buf, "%s\n", f71882fg_names[data->type]);
  1709. }
  1710. static int __devinit f71882fg_create_sysfs_files(struct platform_device *pdev,
  1711. struct sensor_device_attribute_2 *attr, int count)
  1712. {
  1713. int err, i;
  1714. for (i = 0; i < count; i++) {
  1715. err = device_create_file(&pdev->dev, &attr[i].dev_attr);
  1716. if (err)
  1717. return err;
  1718. }
  1719. return 0;
  1720. }
  1721. static void f71882fg_remove_sysfs_files(struct platform_device *pdev,
  1722. struct sensor_device_attribute_2 *attr, int count)
  1723. {
  1724. int i;
  1725. for (i = 0; i < count; i++)
  1726. device_remove_file(&pdev->dev, &attr[i].dev_attr);
  1727. }
  1728. static int __devinit f71882fg_probe(struct platform_device *pdev)
  1729. {
  1730. struct f71882fg_data *data;
  1731. struct f71882fg_sio_data *sio_data = pdev->dev.platform_data;
  1732. int err, i, nr_fans = (sio_data->type == f71882fg) ? 4 : 3;
  1733. u8 start_reg;
  1734. data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
  1735. if (!data)
  1736. return -ENOMEM;
  1737. data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
  1738. data->type = sio_data->type;
  1739. data->temp_start =
  1740. (data->type == f71858fg || data->type == f8000) ? 0 : 1;
  1741. mutex_init(&data->update_lock);
  1742. platform_set_drvdata(pdev, data);
  1743. start_reg = f71882fg_read8(data, F71882FG_REG_START);
  1744. if (start_reg & 0x04) {
  1745. dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
  1746. err = -ENODEV;
  1747. goto exit_free;
  1748. }
  1749. if (!(start_reg & 0x03)) {
  1750. dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
  1751. err = -ENODEV;
  1752. goto exit_free;
  1753. }
  1754. /* Register sysfs interface files */
  1755. err = device_create_file(&pdev->dev, &dev_attr_name);
  1756. if (err)
  1757. goto exit_unregister_sysfs;
  1758. if (start_reg & 0x01) {
  1759. switch (data->type) {
  1760. case f71858fg:
  1761. data->temp_config =
  1762. f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
  1763. if (data->temp_config & 0x10)
  1764. /* The f71858fg temperature alarms behave as
  1765. the f8000 alarms in this mode */
  1766. err = f71882fg_create_sysfs_files(pdev,
  1767. f8000_in_temp_attr,
  1768. ARRAY_SIZE(f8000_in_temp_attr));
  1769. else
  1770. err = f71882fg_create_sysfs_files(pdev,
  1771. f71858fg_in_temp_attr,
  1772. ARRAY_SIZE(f71858fg_in_temp_attr));
  1773. break;
  1774. case f71882fg:
  1775. case f71889fg:
  1776. err = f71882fg_create_sysfs_files(pdev,
  1777. fxxxx_in1_alarm_attr,
  1778. ARRAY_SIZE(fxxxx_in1_alarm_attr));
  1779. if (err)
  1780. goto exit_unregister_sysfs;
  1781. /* fall through! */
  1782. case f71862fg:
  1783. err = f71882fg_create_sysfs_files(pdev,
  1784. f71862_temp_attr,
  1785. ARRAY_SIZE(f71862_temp_attr));
  1786. if (err)
  1787. goto exit_unregister_sysfs;
  1788. err = f71882fg_create_sysfs_files(pdev,
  1789. fxxxx_in_attr,
  1790. ARRAY_SIZE(fxxxx_in_attr));
  1791. if (err)
  1792. goto exit_unregister_sysfs;
  1793. err = f71882fg_create_sysfs_files(pdev,
  1794. fxxxx_temp_attr,
  1795. ARRAY_SIZE(fxxxx_temp_attr));
  1796. break;
  1797. case f71808fg:
  1798. err = f71882fg_create_sysfs_files(pdev,
  1799. f71808_in_attr,
  1800. ARRAY_SIZE(f71808_in_attr));
  1801. if (err)
  1802. goto exit_unregister_sysfs;
  1803. err = f71882fg_create_sysfs_files(pdev,
  1804. fxxxx_temp_attr,
  1805. ARRAY_SIZE(fxxxx_temp_attr));
  1806. break;
  1807. case f8000:
  1808. err = f71882fg_create_sysfs_files(pdev,
  1809. f8000_in_temp_attr,
  1810. ARRAY_SIZE(f8000_in_temp_attr));
  1811. break;
  1812. }
  1813. if (err)
  1814. goto exit_unregister_sysfs;
  1815. }
  1816. if (start_reg & 0x02) {
  1817. data->pwm_enable =
  1818. f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
  1819. /* Sanity check the pwm settings */
  1820. switch (data->type) {
  1821. case f71858fg:
  1822. err = 0;
  1823. for (i = 0; i < nr_fans; i++)
  1824. if (((data->pwm_enable >> (i * 2)) & 3) == 3)
  1825. err = 1;
  1826. break;
  1827. case f71862fg:
  1828. err = (data->pwm_enable & 0x15) != 0x15;
  1829. break;
  1830. case f71808fg:
  1831. case f71882fg:
  1832. case f71889fg:
  1833. err = 0;
  1834. break;
  1835. case f8000:
  1836. err = data->pwm_enable & 0x20;
  1837. break;
  1838. }
  1839. if (err) {
  1840. dev_err(&pdev->dev,
  1841. "Invalid (reserved) pwm settings: 0x%02x\n",
  1842. (unsigned int)data->pwm_enable);
  1843. err = -ENODEV;
  1844. goto exit_unregister_sysfs;
  1845. }
  1846. err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
  1847. ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
  1848. if (err)
  1849. goto exit_unregister_sysfs;
  1850. if (data->type == f71862fg || data->type == f71882fg ||
  1851. data->type == f71889fg) {
  1852. err = f71882fg_create_sysfs_files(pdev,
  1853. fxxxx_fan_beep_attr, nr_fans);
  1854. if (err)
  1855. goto exit_unregister_sysfs;
  1856. }
  1857. switch (data->type) {
  1858. case f71862fg:
  1859. err = f71882fg_create_sysfs_files(pdev,
  1860. f71862fg_auto_pwm_attr,
  1861. ARRAY_SIZE(f71862fg_auto_pwm_attr));
  1862. break;
  1863. case f8000:
  1864. err = f71882fg_create_sysfs_files(pdev,
  1865. f8000_fan_attr,
  1866. ARRAY_SIZE(f8000_fan_attr));
  1867. if (err)
  1868. goto exit_unregister_sysfs;
  1869. err = f71882fg_create_sysfs_files(pdev,
  1870. f8000_auto_pwm_attr,
  1871. ARRAY_SIZE(f8000_auto_pwm_attr));
  1872. break;
  1873. case f71808fg:
  1874. case f71889fg:
  1875. for (i = 0; i < nr_fans; i++) {
  1876. data->pwm_auto_point_mapping[i] =
  1877. f71882fg_read8(data,
  1878. F71882FG_REG_POINT_MAPPING(i));
  1879. if (data->pwm_auto_point_mapping[i] & 0x80)
  1880. break;
  1881. }
  1882. if (i != nr_fans) {
  1883. dev_warn(&pdev->dev,
  1884. "Auto pwm controlled by raw digital "
  1885. "data, disabling pwm auto_point "
  1886. "sysfs attributes\n");
  1887. break;
  1888. }
  1889. /* fall through */
  1890. default: /* f71858fg / f71882fg */
  1891. err = f71882fg_create_sysfs_files(pdev,
  1892. &fxxxx_auto_pwm_attr[0][0],
  1893. ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
  1894. }
  1895. if (err)
  1896. goto exit_unregister_sysfs;
  1897. for (i = 0; i < nr_fans; i++)
  1898. dev_info(&pdev->dev, "Fan: %d is in %s mode\n", i + 1,
  1899. (data->pwm_enable & (1 << 2 * i)) ?
  1900. "duty-cycle" : "RPM");
  1901. }
  1902. data->hwmon_dev = hwmon_device_register(&pdev->dev);
  1903. if (IS_ERR(data->hwmon_dev)) {
  1904. err = PTR_ERR(data->hwmon_dev);
  1905. data->hwmon_dev = NULL;
  1906. goto exit_unregister_sysfs;
  1907. }
  1908. return 0;
  1909. exit_unregister_sysfs:
  1910. f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
  1911. return err; /* f71882fg_remove() also frees our data */
  1912. exit_free:
  1913. kfree(data);
  1914. return err;
  1915. }
  1916. static int f71882fg_remove(struct platform_device *pdev)
  1917. {
  1918. struct f71882fg_data *data = platform_get_drvdata(pdev);
  1919. int nr_fans = (data->type == f71882fg) ? 4 : 3;
  1920. u8 start_reg = f71882fg_read8(data, F71882FG_REG_START);
  1921. platform_set_drvdata(pdev, NULL);
  1922. if (data->hwmon_dev)
  1923. hwmon_device_unregister(data->hwmon_dev);
  1924. device_remove_file(&pdev->dev, &dev_attr_name);
  1925. if (start_reg & 0x01) {
  1926. switch (data->type) {
  1927. case f71858fg:
  1928. if (data->temp_config & 0x10)
  1929. f71882fg_remove_sysfs_files(pdev,
  1930. f8000_in_temp_attr,
  1931. ARRAY_SIZE(f8000_in_temp_attr));
  1932. else
  1933. f71882fg_remove_sysfs_files(pdev,
  1934. f71858fg_in_temp_attr,
  1935. ARRAY_SIZE(f71858fg_in_temp_attr));
  1936. break;
  1937. case f71882fg:
  1938. case f71889fg:
  1939. f71882fg_remove_sysfs_files(pdev,
  1940. fxxxx_in1_alarm_attr,
  1941. ARRAY_SIZE(fxxxx_in1_alarm_attr));
  1942. /* fall through! */
  1943. case f71862fg:
  1944. f71882fg_remove_sysfs_files(pdev,
  1945. f71862_temp_attr,
  1946. ARRAY_SIZE(f71862_temp_attr));
  1947. f71882fg_remove_sysfs_files(pdev,
  1948. fxxxx_in_attr,
  1949. ARRAY_SIZE(fxxxx_in_attr));
  1950. f71882fg_remove_sysfs_files(pdev,
  1951. fxxxx_temp_attr,
  1952. ARRAY_SIZE(fxxxx_temp_attr));
  1953. break;
  1954. case f71808fg:
  1955. f71882fg_remove_sysfs_files(pdev,
  1956. f71808_in_attr,
  1957. ARRAY_SIZE(f71808_in_attr));
  1958. f71882fg_remove_sysfs_files(pdev,
  1959. fxxxx_temp_attr,
  1960. ARRAY_SIZE(fxxxx_temp_attr));
  1961. break;
  1962. case f8000:
  1963. f71882fg_remove_sysfs_files(pdev,
  1964. f8000_in_temp_attr,
  1965. ARRAY_SIZE(f8000_in_temp_attr));
  1966. break;
  1967. }
  1968. }
  1969. if (start_reg & 0x02) {
  1970. f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
  1971. ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
  1972. if (data->type == f71862fg || data->type == f71882fg ||
  1973. data->type == f71889fg)
  1974. f71882fg_remove_sysfs_files(pdev,
  1975. fxxxx_fan_beep_attr, nr_fans);
  1976. switch (data->type) {
  1977. case f71862fg:
  1978. f71882fg_remove_sysfs_files(pdev,
  1979. f71862fg_auto_pwm_attr,
  1980. ARRAY_SIZE(f71862fg_auto_pwm_attr));
  1981. break;
  1982. case f8000:
  1983. f71882fg_remove_sysfs_files(pdev,
  1984. f8000_fan_attr,
  1985. ARRAY_SIZE(f8000_fan_attr));
  1986. f71882fg_remove_sysfs_files(pdev,
  1987. f8000_auto_pwm_attr,
  1988. ARRAY_SIZE(f8000_auto_pwm_attr));
  1989. break;
  1990. default: /* f71858fg / f71882fg / f71889fg */
  1991. f71882fg_remove_sysfs_files(pdev,
  1992. &fxxxx_auto_pwm_attr[0][0],
  1993. ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
  1994. }
  1995. }
  1996. kfree(data);
  1997. return 0;
  1998. }
  1999. static int __init f71882fg_find(int sioaddr, unsigned short *address,
  2000. struct f71882fg_sio_data *sio_data)
  2001. {
  2002. int err = -ENODEV;
  2003. u16 devid;
  2004. /* Don't step on other drivers' I/O space by accident */
  2005. if (!request_region(sioaddr, 2, DRVNAME)) {
  2006. printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n",
  2007. (int)sioaddr);
  2008. return -EBUSY;
  2009. }
  2010. superio_enter(sioaddr);
  2011. devid = superio_inw(sioaddr, SIO_REG_MANID);
  2012. if (devid != SIO_FINTEK_ID) {
  2013. pr_debug(DRVNAME ": Not a Fintek device\n");
  2014. goto exit;
  2015. }
  2016. devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
  2017. switch (devid) {
  2018. case SIO_F71808_ID:
  2019. sio_data->type = f71808fg;
  2020. break;
  2021. case SIO_F71858_ID:
  2022. sio_data->type = f71858fg;
  2023. break;
  2024. case SIO_F71862_ID:
  2025. sio_data->type = f71862fg;
  2026. break;
  2027. case SIO_F71882_ID:
  2028. sio_data->type = f71882fg;
  2029. break;
  2030. case SIO_F71889_ID:
  2031. sio_data->type = f71889fg;
  2032. break;
  2033. case SIO_F8000_ID:
  2034. sio_data->type = f8000;
  2035. break;
  2036. default:
  2037. printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n",
  2038. (unsigned int)devid);
  2039. goto exit;
  2040. }
  2041. if (sio_data->type == f71858fg)
  2042. superio_select(sioaddr, SIO_F71858FG_LD_HWM);
  2043. else
  2044. superio_select(sioaddr, SIO_F71882FG_LD_HWM);
  2045. if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
  2046. printk(KERN_WARNING DRVNAME ": Device not activated\n");
  2047. goto exit;
  2048. }
  2049. *address = superio_inw(sioaddr, SIO_REG_ADDR);
  2050. if (*address == 0) {
  2051. printk(KERN_WARNING DRVNAME ": Base address not set\n");
  2052. goto exit;
  2053. }
  2054. *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */
  2055. err = 0;
  2056. printk(KERN_INFO DRVNAME ": Found %s chip at %#x, revision %d\n",
  2057. f71882fg_names[sio_data->type], (unsigned int)*address,
  2058. (int)superio_inb(sioaddr, SIO_REG_DEVREV));
  2059. exit:
  2060. superio_exit(sioaddr);
  2061. release_region(sioaddr, 2);
  2062. return err;
  2063. }
  2064. static int __init f71882fg_device_add(unsigned short address,
  2065. const struct f71882fg_sio_data *sio_data)
  2066. {
  2067. struct resource res = {
  2068. .start = address,
  2069. .end = address + REGION_LENGTH - 1,
  2070. .flags = IORESOURCE_IO,
  2071. };
  2072. int err;
  2073. f71882fg_pdev = platform_device_alloc(DRVNAME, address);
  2074. if (!f71882fg_pdev)
  2075. return -ENOMEM;
  2076. res.name = f71882fg_pdev->name;
  2077. err = acpi_check_resource_conflict(&res);
  2078. if (err)
  2079. goto exit_device_put;
  2080. err = platform_device_add_resources(f71882fg_pdev, &res, 1);
  2081. if (err) {
  2082. printk(KERN_ERR DRVNAME ": Device resource addition failed\n");
  2083. goto exit_device_put;
  2084. }
  2085. err = platform_device_add_data(f71882fg_pdev, sio_data,
  2086. sizeof(struct f71882fg_sio_data));
  2087. if (err) {
  2088. printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
  2089. goto exit_device_put;
  2090. }
  2091. err = platform_device_add(f71882fg_pdev);
  2092. if (err) {
  2093. printk(KERN_ERR DRVNAME ": Device addition failed\n");
  2094. goto exit_device_put;
  2095. }
  2096. return 0;
  2097. exit_device_put:
  2098. platform_device_put(f71882fg_pdev);
  2099. return err;
  2100. }
  2101. static int __init f71882fg_init(void)
  2102. {
  2103. int err = -ENODEV;
  2104. unsigned short address;
  2105. struct f71882fg_sio_data sio_data;
  2106. memset(&sio_data, 0, sizeof(sio_data));
  2107. if (f71882fg_find(0x2e, &address, &sio_data) &&
  2108. f71882fg_find(0x4e, &address, &sio_data))
  2109. goto exit;
  2110. err = platform_driver_register(&f71882fg_driver);
  2111. if (err)
  2112. goto exit;
  2113. err = f71882fg_device_add(address, &sio_data);
  2114. if (err)
  2115. goto exit_driver;
  2116. return 0;
  2117. exit_driver:
  2118. platform_driver_unregister(&f71882fg_driver);
  2119. exit:
  2120. return err;
  2121. }
  2122. static void __exit f71882fg_exit(void)
  2123. {
  2124. platform_device_unregister(f71882fg_pdev);
  2125. platform_driver_unregister(&f71882fg_driver);
  2126. }
  2127. MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
  2128. MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
  2129. MODULE_LICENSE("GPL");
  2130. module_init(f71882fg_init);
  2131. module_exit(f71882fg_exit);