w83627hf.c revision df48ed804f44a040e990976b537efc1e133c74d8
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w83627hf.c - Part of lm_sensors, Linux kernel modules for hardware 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds monitoring 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (c) 1998 - 2003 Frodo Looijaard <frodol@dds.nl>, 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Philip Edelbrock <phil@netroedge.com>, 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds and Mark Studebaker <mdsxyz123@yahoo.com> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Ported to 2.6 by Bernhard C. Schrenk <clemy@clemy.org> 8787c72b107888805981faf148c8fea96a752d22eJean Delvare Copyright (c) 2007 Jean Delvare <khali@linux-fr.org> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License as published by 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the Free Software Foundation; either version 2 of the License, or 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (at your option) any later version. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is distributed in the hope that it will be useful, 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GNU General Public License for more details. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds You should have received a copy of the GNU General Public License 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds along with this program; if not, write to the Free Software 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Supports following chips: 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) 32c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC) 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds For other winbond chips, and for i2c support in the above chips, 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds use w83781d.c. 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Note: automatic ("cruise") fan control for 697, 637 & 627thf not 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds supported yet. 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h> 46787c72b107888805981faf148c8fea96a752d22eJean Delvare#include <linux/platform_device.h> 47943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h> 4807584c762541672e35735b52af031183ca17a5a2Jim Cromie#include <linux/hwmon-sysfs.h> 49303760b44a7a142cb9f4c9df4609fb63bbda98dbJean Delvare#include <linux/hwmon-vid.h> 50943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h> 519a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h> 52d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare#include <linux/ioport.h> 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "lm75.h" 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic struct platform_device *pdev; 57d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 58d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare#define DRVNAME "w83627hf" 59d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvareenum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; 60d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u16 force_addr; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(force_addr, ushort, 0); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(force_addr, 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Initialize the base address of the sensors"); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 force_i2c = 0x1f; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(force_i2c, byte, 0); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(force_i2c, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Initialize the i2c address of the sensors"); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 702251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvarestatic int reset; 712251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvaremodule_param(reset, bool, 0); 722251cf1a4b37bd483501614c2d78f5b8286f20d7Jean DelvareMODULE_PARM_DESC(reset, "Set to one to reset chip on load"); 732251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int init = 1; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(init, bool, 0); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* modified from kernel/include/traps.c */ 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int REG; /* The register to read/write */ 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEV 0x07 /* Register: Logical device select */ 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int VAL; /* The value to read/write */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* logical device numbers for superio_select (below) */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_FDC 0x00 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_PRT 0x01 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_UART1 0x02 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_UART2 0x03 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_KBC 0x05 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_CIR 0x06 /* w83627hf only */ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GAME 0x07 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_MIDI 0x07 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO1 0x07 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO5 0x07 /* w83627thf only */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO2 0x08 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO3 0x09 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO4 0x09 /* w83627thf only */ 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_ACPI 0x0a 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_HWM 0x0b 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEVID 0x20 /* Register: Device ID */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_EN 0x30 /* w83627thf only */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_EN 0x29 /* w83687thf only */ 107c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_CFG 0xF0 /* w83687thf only */ 108c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_DATA 0xF1 /* w83687thf only */ 109c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_outb(int reg, int val) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(reg, REG); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(val, VAL); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_inb(int reg) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(reg, REG); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return inb(VAL); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_select(int ld) 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(DEV, REG); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(ld, VAL); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_enter(void) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0x87, REG); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0x87, REG); 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_exit(void) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0xAA, REG); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W627_DEVID 0x52 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W627THF_DEVID 0x82 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W697_DEVID 0x60 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W637_DEVID 0x70 148c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W687THF_DEVID 0x85 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WINB_ACT_REG 0x30 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WINB_BASE_REG 0x60 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Constants specified below */ 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 153ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec/* Alignment of the base address */ 154ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_ALIGNMENT ~7 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 156ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec/* Offset & size of I/O region we are interested in */ 157ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_REGION_OFFSET 5 158ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_REGION_SIZE 2 159ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec 160787c72b107888805981faf148c8fea96a752d22eJean Delvare/* Where are the sensors address/data registers relative to the region offset */ 161787c72b107888805981faf148c8fea96a752d22eJean Delvare#define W83781D_ADDR_REG_OFFSET 0 162787c72b107888805981faf148c8fea96a752d22eJean Delvare#define W83781D_DATA_REG_OFFSET 1 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The W83781D registers */ 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The W83782D registers for nr=7,8 are in bank 5 */ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x554 + (((nr) - 7) * 2))) 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x555 + (((nr) - 7) * 2))) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x550 + (nr) - 7)) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_FAN(nr) (0x27 + (nr)) 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 176df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie#define W83627HF_REG_TEMP2_CONFIG 0x152 177df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie#define W83627HF_REG_TEMP3_CONFIG 0x252 178df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie/* these are zero-based, unlike config constants above */ 179df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp[] = { 0x27, 0x150, 0x250 }; 180df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp_hyst[] = { 0x3A, 0x153, 0x253 }; 181df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BANK 0x4E 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CONFIG 0x40 1864a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM1 0x459 1874a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM2 0x45A 1884a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM3 0x45B 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_CONFIG 0x4D 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS1 0x56 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS2 0x57 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS3 0x453 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_VID_FANDIV 0x47 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CHIPID 0x49 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_WCHIPID 0x58 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CHIPMAN 0x4F 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_PIN 0x4B 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_VBAT 0x5D 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_REG_PWM1 0x5A 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_REG_PWM2 0x5B 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 207c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ 208c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ 209c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83627THF_REG_PWM3 }; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ 21707584c762541672e35735b52af031183ca17a5a2Jim Cromie regpwm_627hf[nr] : regpwm[nr]) 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2191550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ 2201550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2211550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ1 0x00 /* 697HF/687THF too */ 2221550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ2 0x02 /* 697HF/687THF too */ 2231550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ3 0x10 /* 687THF too */ 2241550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2251550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1, 2261550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ2, 2271550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ3 }; 2281550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2291550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83627HF_BASE_PWM_FREQ 46870 2301550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_I2C_ADDR 0x48 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_I2C_SUBADDR 0x4A 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Sensor selection */ 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_SCFG1 0x5D 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_SCFG2 0x59 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_DEFAULT_BETA 3435 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Conversions. Limit checking is only done on the TO_REG 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds variants. Note that you should be a bit careful with which arguments 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds these macros are called: arguments may be evaluated more than once. 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Fixing this is just not worth it. */ 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IN_FROM_REG(val) ((val) * 16) 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 FAN_TO_REG(long rpm, int div) 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rpm == 0) 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 255; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpm = SENSORS_LIMIT(rpm, 1, 1000000); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 254); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_MIN (-128000) 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_MAX ( 127000) 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* TEMP: 0.001C/bit (-128C to +127C) 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds REG: 1C/bit, two's complement */ 2625bfedac045082a97e20d47d876071279ef984d28Christian Hohnstaedtstatic u8 TEMP_TO_REG(long temp) 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ntemp += (ntemp<0 ? -500 : 500); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (u8)(ntemp / 1000); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int TEMP_FROM_REG(u8 reg) 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (s8)reg * 1000; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline unsigned long pwm_freq_from_reg_627hf(u8 reg) 2791550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 2801550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez unsigned long freq; 2811550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez freq = W83627HF_BASE_PWM_FREQ >> reg; 2821550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return freq; 2831550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 2841550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline u8 pwm_freq_to_reg_627hf(unsigned long val) 2851550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 2861550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 i; 2871550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Only 5 dividers (1 2 4 8 16) 2881550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez Search for the nearest available frequency */ 2891550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez for (i = 0; i < 4; i++) { 2901550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val > (((W83627HF_BASE_PWM_FREQ >> i) + 2911550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2)) 2921550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez break; 2931550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 2941550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return i; 2951550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 2961550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2971550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline unsigned long pwm_freq_from_reg(u8 reg) 2981550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 2991550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Clock bit 8 -> 180 kHz or 24 MHz */ 3001550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL; 3011550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 3021550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez reg &= 0x7f; 3031550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* This should not happen but anyway... */ 3041550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (reg == 0) 3051550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez reg++; 3061550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (clock / (reg << 8)); 3071550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 3081550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline u8 pwm_freq_to_reg(unsigned long val) 3091550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 3101550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Minimum divider value is 0x01 and maximum is 0x7F */ 3111550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val >= 93750) /* The highest we can do */ 3121550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return 0x01; 3131550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val >= 720) /* Use 24 MHz clock */ 3141550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (24000000UL / (val << 8)); 3151550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val < 6) /* The lowest we can do */ 3161550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return 0xFF; 3171550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez else /* Use 180 kHz clock */ 3181550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (0x80 | (180000UL / (val << 8))); 3191550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 3201550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_MASK_FROM_REG(val) (val) 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_ENABLE_TO_REG(val) ((val)?1:0) 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_ENABLE_FROM_REG(val) ((val)?1:0) 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DIV_FROM_REG(val) (1 << (val)) 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 DIV_TO_REG(long val) 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = SENSORS_LIMIT(val, 1, 128) >> 1; 332abc01922477104e8d72b494902aff37135c409e7Grant Coady for (i = 0; i < 7; i++) { 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val == 0) 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val >>= 1; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((u8) i); 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 340ed6bafbf6017d6a007b39de6b65ad3b8ae4c8aeeJean Delvare/* For each registered chip, we need to keep some data in memory. 341ed6bafbf6017d6a007b39de6b65ad3b8ae4c8aeeJean Delvare The structure is dynamically allocated. */ 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct w83627hf_data { 343787c72b107888805981faf148c8fea96a752d22eJean Delvare unsigned short addr; 344787c72b107888805981faf148c8fea96a752d22eJean Delvare const char *name; 3451beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones struct device *hwmon_dev; 3469a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex lock; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enum chips type; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3499a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex update_lock; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char valid; /* !=0 if following fields are valid */ 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long last_updated; /* In jiffies */ 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in[9]; /* Register value */ 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_max[9]; /* Register value */ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_min[9]; /* Register value */ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan[3]; /* Register value */ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan_min[3]; /* Register value */ 358df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp[3]; /* Register value */ 359df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp_max[3]; /* Register value */ 360df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp_max_hyst[3]; /* Register value */ 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan_div[3]; /* Register encoding, shifted right */ 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vid; /* Register encoding, combined */ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 alarms; /* Register encoding, combined */ 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 beep_mask; /* Register encoding, combined */ 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 beep_enable; /* Boolean */ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 pwm[3]; /* Register value */ 3671550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 pwm_freq[3]; /* Register value */ 368b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; 369b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare 4 = thermistor */ 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vrm; 371c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 374787c72b107888805981faf148c8fea96a752d22eJean Delvarestruct w83627hf_sio_data { 375787c72b107888805981faf148c8fea96a752d22eJean Delvare enum chips type; 376787c72b107888805981faf148c8fea96a752d22eJean Delvare}; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 379787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_probe(struct platform_device *pdev); 380d0546128980c18748010c758903b02909e634830Jean Delvarestatic int __devexit w83627hf_remove(struct platform_device *pdev); 381787c72b107888805981faf148c8fea96a752d22eJean Delvare 382787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_read_value(struct w83627hf_data *data, u16 reg); 383787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); 384c09c5184a26158da32801e89d5849d774605f0ddJean Delvarestatic void w83627hf_update_fan_div(struct w83627hf_data *data); 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct w83627hf_data *w83627hf_update_device(struct device *dev); 386787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic void w83627hf_init_device(struct platform_device *pdev); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 388787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic struct platform_driver w83627hf_driver = { 389cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard .driver = { 390872188420997f7f7c1b968fd9bce6578e4c3d45fJean Delvare .owner = THIS_MODULE, 391d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare .name = DRVNAME, 392cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard }, 393787c72b107888805981faf148c8fea96a752d22eJean Delvare .probe = w83627hf_probe, 394787c72b107888805981faf148c8fea96a752d22eJean Delvare .remove = __devexit_p(w83627hf_remove), 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 39807584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_input(struct device *dev, struct device_attribute *devattr, char *buf) 39907584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 40007584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 40107584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 40207584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in[nr])); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 40407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 40507584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_min(struct device *dev, struct device_attribute *devattr, char *buf) 40607584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 40707584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 40807584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 40907584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_min[nr])); 41007584c762541672e35735b52af031183ca17a5a2Jim Cromie} 41107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 41207584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_max(struct device *dev, struct device_attribute *devattr, char *buf) 41307584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 41407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 41507584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 41607584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_max[nr])); 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 41807584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 41907584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_in_min(struct device *dev, struct device_attribute *devattr, 42007584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 42107584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 42207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 42307584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 42407584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42607584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 42707584c762541672e35735b52af031183ca17a5a2Jim Cromie data->in_min[nr] = IN_TO_REG(val); 42807584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83781D_REG_IN_MIN(nr), data->in_min[nr]); 42907584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 43007584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 43107584c762541672e35735b52af031183ca17a5a2Jim Cromie} 43207584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 43307584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_in_max(struct device *dev, struct device_attribute *devattr, 43407584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 43507584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 43607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 43707584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 43807584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44007584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 44107584c762541672e35735b52af031183ca17a5a2Jim Cromie data->in_max[nr] = IN_TO_REG(val); 44207584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83781D_REG_IN_MAX(nr), data->in_max[nr]); 44307584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 44407584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 44507584c762541672e35735b52af031183ca17a5a2Jim Cromie} 44607584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_vin_decl(offset) \ 44707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ 44807584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_input, NULL, offset); \ 44907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO|S_IWUSR, \ 45007584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_min, store_in_min, offset); \ 45107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO|S_IWUSR, \ 45207584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_max, store_in_max, offset); 45307584c762541672e35735b52af031183ca17a5a2Jim Cromie 45407584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(1); 45507584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(2); 45607584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(3); 45707584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(4); 45807584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(5); 45907584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(6); 46007584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(7); 46107584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(8); 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* use a different set of functions for in0 */ 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long in0; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 469c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 470c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in0 = (long)((reg * 488 + 70000 + 50) / 100); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in0 = (long)IN_FROM_REG(reg); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf,"%ld\n", in0); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_0(struct device *dev, struct device_attribute *attr, char *buf) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in[0]); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 487a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_min0(struct device *dev, struct device_attribute *attr, char *buf) 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in_min[0]); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 493a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *attr, char *buf) 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in_max[0]); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 499a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr, 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *buf, size_t count) 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 502787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5079a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 510c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 511c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 5142723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu data->in_min[0] = 5152723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0, 5162723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu 255); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_min[0] = IN_TO_REG(val); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_IN_MIN(0), data->in_min[0]); 5229a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 526a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr, 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *buf, size_t count) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 529787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5349a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 537c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 538c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 5412723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu data->in_max[0] = 5422723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0, 5432723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu 255); 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_max[0] = IN_TO_REG(val); 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 548787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_IN_MAX(0), data->in_max[0]); 5499a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs_in_min0, store_regs_in_min0); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs_in_max0, store_regs_in_max0); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 56007584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_input(struct device *dev, struct device_attribute *devattr, char *buf) 56107584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 56207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 56307584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 56407584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan[nr], 56507584c762541672e35735b52af031183ca17a5a2Jim Cromie (long)DIV_FROM_REG(data->fan_div[nr]))); 56607584c762541672e35735b52af031183ca17a5a2Jim Cromie} 56707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 56807584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_min(struct device *dev, struct device_attribute *devattr, char *buf) 56907584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 57007584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 57107584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 57207584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan_min[nr], 57307584c762541672e35735b52af031183ca17a5a2Jim Cromie (long)DIV_FROM_REG(data->fan_div[nr]))); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 57607584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_fan_min(struct device *dev, struct device_attribute *devattr, 57707584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 57907584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 580787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 58107584c762541672e35735b52af031183ca17a5a2Jim Cromie u32 val = simple_strtoul(buf, NULL, 10); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5839a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 58407584c762541672e35735b52af031183ca17a5a2Jim Cromie data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 58507584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), 58607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->fan_min[nr]); 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5889a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 59107584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_fan_decl(offset) \ 59207584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 59307584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_input, NULL, offset - 1); \ 59407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 59507584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_min, store_fan_min, offset - 1); 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59707584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(1); 59807584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(2); 59907584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(3); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 60207584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp(struct device *dev, struct device_attribute *devattr, char *buf) 60307584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 60407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 60507584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 606df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 607df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp[nr]; 608df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 609df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61207584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 61307584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_max(struct device *dev, struct device_attribute *devattr, 61407584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 61507584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 61607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 61707584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 618df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 619df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp_max[nr]; 620df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 621df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 62507584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_max_hyst(struct device *dev, struct device_attribute *devattr, 62607584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 62707584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 62807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 62907584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 630df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 631df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp_max_hyst[nr]; 632df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 633df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 63407584c762541672e35735b52af031183ca17a5a2Jim Cromie} 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 63607584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 63707584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_max(struct device *dev, struct device_attribute *devattr, 63807584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 63907584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 64007584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 64107584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 64207584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 643df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 64507584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 646df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max[nr] = tmp; 647df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp); 64807584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 64907584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 65007584c762541672e35735b52af031183ca17a5a2Jim Cromie} 65107584c762541672e35735b52af031183ca17a5a2Jim Cromie 65207584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 65307584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_max_hyst(struct device *dev, struct device_attribute *devattr, 65407584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 65507584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 65607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 65707584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 65807584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 659df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); 66007584c762541672e35735b52af031183ca17a5a2Jim Cromie 66107584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 662df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max_hyst[nr] = tmp; 663df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp); 66407584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 66507584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 66607584c762541672e35735b52af031183ca17a5a2Jim Cromie} 66707584c762541672e35735b52af031183ca17a5a2Jim Cromie 66807584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_temp_decl(offset) \ 66907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ 670df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp, NULL, offset - 1); \ 67107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR, \ 672df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp_max, store_temp_max, offset - 1); \ 67307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR, \ 674df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp_max_hyst, store_temp_max_hyst, offset - 1); 67507584c762541672e35735b52af031183ca17a5a2Jim Cromie 67607584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(1); 67707584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(2); 67807584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(3); 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 681a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 689a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 69190d6619a916062cb75a176aacb318d108758b4a5Jean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) data->vrm); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 695a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustore_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 697787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vrm = val; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 708a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) data->alarms); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_beep_reg(REG, reg) \ 716a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ \ 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); \ 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf,"%ld\n", \ 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \ 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_beep_reg(ENABLE, enable) 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_beep_reg(MASK, mask) 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_ENABLE 0 /* Store beep_enable */ 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define BEEP_MASK 1 /* Store beep_mask */ 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstore_beep_reg(struct device *dev, const char *buf, size_t count, 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int update_mask) 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 732787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val, val2; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7379a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->beep_mask = BEEP_MASK_TO_REG(val); 741787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS1, 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->beep_mask & 0xff); 743787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS3, 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((data->beep_mask) >> 16) & 0xff); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val2 = (data->beep_mask >> 8) & 0x7f; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { /* We are storing beep_enable */ 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val2 = 748787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->beep_enable = BEEP_ENABLE_TO_REG(val); 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 752787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val2 | data->beep_enable << 7); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7559a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define sysfs_beep(REG, reg) \ 760a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ \ 762a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannou return show_beep_##reg(dev, attr, buf); \ 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} \ 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t \ 765a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustore_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ \ 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return store_beep_reg(dev, buf, count, BEEP_##REG); \ 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} \ 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, \ 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs_beep_##reg, store_regs_beep_##reg); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssysfs_beep(ENABLE, enable); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssysfs_beep(MASK, mask); 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 77607584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 77807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", 78107584c762541672e35735b52af031183ca17a5a2Jim Cromie (long) DIV_FROM_REG(data->fan_div[nr])); 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Note: we save and restore the fan minimum here, because its value is 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds determined in part by the fan divisor. This follows the principle of 785d6e05edc59ecd79e8badf440c0d295a979bdfa3eAndreas Mohr least surprise; the user doesn't expect the fan minimum to change just 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds because the divisor changed. */ 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 78807584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_fan_div(struct device *dev, struct device_attribute *devattr, 78907584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 79107584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 792787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long min; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg; 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long val = simple_strtoul(buf, NULL, 10); 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7979a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Save fan_min */ 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds min = FAN_FROM_REG(data->fan_min[nr], 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DIV_FROM_REG(data->fan_div[nr])); 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_div[nr] = DIV_TO_REG(val); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 805787c72b107888805981faf148c8fea96a752d22eJean Delvare reg = (w83627hf_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds & (nr==0 ? 0xcf : 0x3f)) 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); 808787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 810787c72b107888805981faf148c8fea96a752d22eJean Delvare reg = (w83627hf_read_value(data, W83781D_REG_VBAT) 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds & ~(1 << (5 + nr))) 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | ((data->fan_div[nr] & 0x04) << (3 + nr)); 813787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_VBAT, reg); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Restore fan_min */ 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); 817787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8199a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 82307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO|S_IWUSR, 82407584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 0); 82507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO|S_IWUSR, 82607584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 1); 82707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO|S_IWUSR, 82807584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 2); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 83107584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_pwm(struct device *dev, struct device_attribute *devattr, char *buf) 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 83307584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 83507584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long) data->pwm[nr]); 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 83907584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_pwm(struct device *dev, struct device_attribute *devattr, 84007584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 84207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 843787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 84407584c762541672e35735b52af031183ca17a5a2Jim Cromie u32 val = simple_strtoul(buf, NULL, 10); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8469a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data->type == w83627thf) { 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bits 0-3 are reserved in 627THF */ 85007584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] = PWM_TO_REG(val) & 0xf0; 851787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr), 85307584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] | 854787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 85707584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] = PWM_TO_REG(val); 858787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr), 86007584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr]); 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8639a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 86707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0); 86807584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); 86907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 87207584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) 8731550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 87407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 8751550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez struct w83627hf_data *data = w83627hf_update_device(dev); 8761550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) 8771550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return sprintf(buf, "%ld\n", 87807584c762541672e35735b52af031183ca17a5a2Jim Cromie pwm_freq_from_reg_627hf(data->pwm_freq[nr])); 8791550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez else 8801550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return sprintf(buf, "%ld\n", 88107584c762541672e35735b52af031183ca17a5a2Jim Cromie pwm_freq_from_reg(data->pwm_freq[nr])); 8821550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 8831550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 8841550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic ssize_t 88507584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_pwm_freq(struct device *dev, struct device_attribute *devattr, 88607584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 8871550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 88807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 8891550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez struct w83627hf_data *data = dev_get_drvdata(dev); 8901550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez static const u8 mask[]={0xF8, 0x8F}; 8911550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u32 val; 8921550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 8931550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez val = simple_strtoul(buf, NULL, 10); 8941550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 8951550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez mutex_lock(&data->update_lock); 8961550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 8971550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) { 89807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val); 8991550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, 90007584c762541672e35735b52af031183ca17a5a2Jim Cromie (data->pwm_freq[nr] << (nr*4)) | 9011550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez (w83627hf_read_value(data, 90207584c762541672e35735b52af031183ca17a5a2Jim Cromie W83627HF_REG_PWM_FREQ) & mask[nr])); 9031550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } else { 90407584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr] = pwm_freq_to_reg(val); 90507584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr], 90607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr]); 9071550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 9081550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9091550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez mutex_unlock(&data->update_lock); 9101550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return count; 9111550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 9121550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 91307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO|S_IWUSR, 91407584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 0); 91507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO|S_IWUSR, 91607584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 1); 91707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO|S_IWUSR, 91807584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 2); 9191550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9201550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic ssize_t 92107584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_type(struct device *dev, struct device_attribute *devattr, 92207584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 92407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 92607584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long) data->sens[nr]); 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 93007584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_type(struct device *dev, struct device_attribute *devattr, 93107584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 93307584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 934787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val, tmp; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9399a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (val) { 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: /* PII/Celeron diode */ 943787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 944787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 94507584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG1[nr]); 946787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); 947787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG2, 94807584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG2[nr]); 94907584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: /* 3904 */ 952787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 953787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 95407584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG1[nr]); 955787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); 956787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG2, 95707584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp & ~BIT_SCFG2[nr]); 95807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 960b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare case W83781D_DEFAULT_BETA: 961b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare dev_warn(dev, "Sensor type %d is deprecated, please use 4 " 962b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare "instead\n", W83781D_DEFAULT_BETA); 963b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare /* fall through */ 964b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare case 4: /* thermistor */ 965787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 966787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 96707584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp & ~BIT_SCFG1[nr]); 96807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 971787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_err(dev, 972b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare "Invalid sensor type %ld; must be 1, 2, or 4\n", 973b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare (long) val); 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9779a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 98107584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_temp_type(offset) \ 98207584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ 98307584c762541672e35735b52af031183ca17a5a2Jim Cromie show_temp_type, store_temp_type, offset - 1); 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 98507584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(1); 98607584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(2); 98707584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(3); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 98907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 99007584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_name(struct device *dev, struct device_attribute *devattr, char *buf) 991787c72b107888805981faf148c8fea96a752d22eJean Delvare{ 992787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 993787c72b107888805981faf148c8fea96a752d22eJean Delvare 994787c72b107888805981faf148c8fea96a752d22eJean Delvare return sprintf(buf, "%s\n", data->name); 995787c72b107888805981faf148c8fea96a752d22eJean Delvare} 996787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 997787c72b107888805981faf148c8fea96a752d22eJean Delvare 998787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __init w83627hf_find(int sioaddr, unsigned short *addr, 999787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data *sio_data) 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare int err = -ENODEV; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 val; 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1004787c72b107888805981faf148c8fea96a752d22eJean Delvare static const __initdata char *names[] = { 1005787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83627HF", 1006787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83627THF", 1007787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83697HF", 1008787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83637HF", 1009787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83687THF", 1010787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1011787c72b107888805981faf148c8fea96a752d22eJean Delvare 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds REG = sioaddr; 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VAL = sioaddr + 1; 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_enter(); 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val= superio_inb(DEVID); 1017787c72b107888805981faf148c8fea96a752d22eJean Delvare switch (val) { 1018787c72b107888805981faf148c8fea96a752d22eJean Delvare case W627_DEVID: 1019787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83627hf; 1020787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1021787c72b107888805981faf148c8fea96a752d22eJean Delvare case W627THF_DEVID: 1022787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83627thf; 1023787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1024787c72b107888805981faf148c8fea96a752d22eJean Delvare case W697_DEVID: 1025787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83697hf; 1026787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1027787c72b107888805981faf148c8fea96a752d22eJean Delvare case W637_DEVID: 1028787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83637hf; 1029787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1030787c72b107888805981faf148c8fea96a752d22eJean Delvare case W687THF_DEVID: 1031787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83687thf; 1032787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1033e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare case 0xff: /* No device at all */ 1034e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare goto exit; 1035787c72b107888805981faf148c8fea96a752d22eJean Delvare default: 1036e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val); 1037d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare goto exit; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_select(W83627HF_LD_HWM); 1041d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare force_addr &= WINB_ALIGNMENT; 1042d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (force_addr) { 1043d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", 1044d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare force_addr); 1045d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_BASE_REG, force_addr >> 8); 1046d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); 1047d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = (superio_inb(WINB_BASE_REG) << 8) | 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_inb(WINB_BASE_REG + 1); 1050ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec *addr = val & WINB_ALIGNMENT; 1051d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (*addr == 0) { 1052d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Base address not set, " 1053d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare "skipping\n"); 1054d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare goto exit; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1057d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare val = superio_inb(WINB_ACT_REG); 1058d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (!(val & 0x01)) { 1059d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); 1060d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_ACT_REG, val | 0x01); 1061d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } 1062d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 1063d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare err = 0; 1064787c72b107888805981faf148c8fea96a752d22eJean Delvare pr_info(DRVNAME ": Found %s chip at %#x\n", 1065787c72b107888805981faf148c8fea96a752d22eJean Delvare names[sio_data->type], *addr); 1066d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 1067d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare exit: 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_exit(); 1069d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare return err; 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107207584c762541672e35735b52af031183ca17a5a2Jim Cromie#define VIN_UNIT_ATTRS(_X_) \ 107307584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in##_X_##_input.dev_attr.attr, \ 107407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in##_X_##_min.dev_attr.attr, \ 107507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in##_X_##_max.dev_attr.attr 107607584c762541672e35735b52af031183ca17a5a2Jim Cromie 107707584c762541672e35735b52af031183ca17a5a2Jim Cromie#define FAN_UNIT_ATTRS(_X_) \ 107807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan##_X_##_input.dev_attr.attr, \ 107907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan##_X_##_min.dev_attr.attr, \ 108007584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan##_X_##_div.dev_attr.attr 108107584c762541672e35735b52af031183ca17a5a2Jim Cromie 108207584c762541672e35735b52af031183ca17a5a2Jim Cromie#define TEMP_UNIT_ATTRS(_X_) \ 108307584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_input.dev_attr.attr, \ 108407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_max.dev_attr.attr, \ 108507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr, \ 108607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_type.dev_attr.attr 108707584c762541672e35735b52af031183ca17a5a2Jim Cromie 1088c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic struct attribute *w83627hf_attributes[] = { 1089c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_input.attr, 1090c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_min.attr, 1091c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_max.attr, 109207584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(2), 109307584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(3), 109407584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(4), 109507584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(7), 109607584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(8), 109707584c762541672e35735b52af031183ca17a5a2Jim Cromie 109807584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(1), 109907584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(2), 110007584c762541672e35735b52af031183ca17a5a2Jim Cromie 110107584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(1), 110207584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(2), 1103c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1104c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_alarms.attr, 1105c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_beep_enable.attr, 1106c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_beep_mask.attr, 1107c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 110807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1.dev_attr.attr, 110907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2.dev_attr.attr, 1110787c72b107888805981faf148c8fea96a752d22eJean Delvare &dev_attr_name.attr, 1111c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman NULL 1112c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1113c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1114c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic const struct attribute_group w83627hf_group = { 1115c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman .attrs = w83627hf_attributes, 1116c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1117c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1118c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic struct attribute *w83627hf_attributes_opt[] = { 111907584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(1), 112007584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(5), 112107584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(6), 112207584c762541672e35735b52af031183ca17a5a2Jim Cromie 112307584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(3), 112407584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(3), 112507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3.dev_attr.attr, 112607584c762541672e35735b52af031183ca17a5a2Jim Cromie 112707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr.attr, 112807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr.attr, 112907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1130c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman NULL 1131c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1132c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1133c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic const struct attribute_group w83627hf_group_opt = { 1134c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman .attrs = w83627hf_attributes_opt, 1135c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1136c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1137787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83627hf_probe(struct platform_device *pdev) 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1139787c72b107888805981faf148c8fea96a752d22eJean Delvare struct device *dev = &pdev->dev; 1140787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data *sio_data = dev->platform_data; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data; 1142787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource *res; 1143787c72b107888805981faf148c8fea96a752d22eJean Delvare int err; 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1145787c72b107888805981faf148c8fea96a752d22eJean Delvare static const char *names[] = { 1146787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83627hf", 1147787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83627thf", 1148787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83697hf", 1149787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83637hf", 1150787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83687thf", 1151787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1152787c72b107888805981faf148c8fea96a752d22eJean Delvare 1153787c72b107888805981faf148c8fea96a752d22eJean Delvare res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1154787c72b107888805981faf148c8fea96a752d22eJean Delvare if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { 1155787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", 1156787c72b107888805981faf148c8fea96a752d22eJean Delvare (unsigned long)res->start, 1157787c72b107888805981faf148c8fea96a752d22eJean Delvare (unsigned long)(res->start + WINB_REGION_SIZE - 1)); 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EBUSY; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto ERROR0; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1162ba9c2e8d15da029ea3051c95e446b2d638ef02e2Deepak Saxena if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENOMEM; 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto ERROR1; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1166787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr = res->start; 1167787c72b107888805981faf148c8fea96a752d22eJean Delvare data->type = sio_data->type; 1168787c72b107888805981faf148c8fea96a752d22eJean Delvare data->name = names[sio_data->type]; 11699a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->lock); 11709a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->update_lock); 1171787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_set_drvdata(pdev, data); 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize the chip */ 1174787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_init_device(pdev); 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* A few vars need to be filled upon startup */ 1177787c72b107888805981faf148c8fea96a752d22eJean Delvare data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); 1178787c72b107888805981faf148c8fea96a752d22eJean Delvare data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); 1179787c72b107888805981faf148c8fea96a752d22eJean Delvare data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); 1180c09c5184a26158da32801e89d5849d774605f0ddJean Delvare w83627hf_update_fan_div(data); 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1182c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman /* Register common device attributes */ 1183787c72b107888805981faf148c8fea96a752d22eJean Delvare if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) 1184943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman goto ERROR3; 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1186c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman /* Register chip-specific device attributes */ 1187787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type == w83627hf || data->type == w83697hf) 118807584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 118907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_input.dev_attr)) 119007584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 119107584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_min.dev_attr)) 119207584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 119307584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_max.dev_attr)) 119407584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 119507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_input.dev_attr)) 119607584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 119707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_min.dev_attr)) 119807584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 119907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_max.dev_attr)) 120007584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 120107584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr)) 120207584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 120307584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr))) 1204c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1206787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type != w83697hf) 120707584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 120807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_input.dev_attr)) 120907584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 121007584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_min.dev_attr)) 121107584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 121207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_max.dev_attr)) 121307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 121407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_input.dev_attr)) 121507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 121607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_min.dev_attr)) 121707584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 121807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_div.dev_attr)) 121907584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 122007584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_input.dev_attr)) 122107584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 122207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_max.dev_attr)) 122307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 122407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_max_hyst.dev_attr)) 122507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 122607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_type.dev_attr))) 1227c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 1228c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1229787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type != w83697hf && data->vid != 0xff) { 12308a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare /* Convert VID to voltage based on VRM */ 12318a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare data->vrm = vid_which_vrm(); 12328a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare 1233787c72b107888805981faf148c8fea96a752d22eJean Delvare if ((err = device_create_file(dev, &dev_attr_cpu0_vid)) 1234787c72b107888805981faf148c8fea96a752d22eJean Delvare || (err = device_create_file(dev, &dev_attr_vrm))) 1235c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 12368a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare } 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1238787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type == w83627thf || data->type == w83637hf 1239787c72b107888805981faf148c8fea96a752d22eJean Delvare || data->type == w83687thf) 124007584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 124107584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3.dev_attr))) 1242c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12441550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83637hf || data->type == w83687thf) 124507584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 124607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr)) 124707584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 124807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr)) 124907584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 125007584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3_freq.dev_attr))) 12511550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez goto ERROR4; 12521550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 12531beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones data->hwmon_dev = hwmon_device_register(dev); 12541beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones if (IS_ERR(data->hwmon_dev)) { 12551beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones err = PTR_ERR(data->hwmon_dev); 1256c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 1257c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman } 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman ERROR4: 1262787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&dev->kobj, &w83627hf_group); 1263787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); 1264943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman ERROR3: 126504a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(data); 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ERROR1: 1268787c72b107888805981faf148c8fea96a752d22eJean Delvare release_region(res->start, WINB_REGION_SIZE); 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ERROR0: 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1273787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devexit w83627hf_remove(struct platform_device *pdev) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1275787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = platform_get_drvdata(pdev); 1276787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource *res; 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12781beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones hwmon_device_unregister(data->hwmon_dev); 1279943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman 1280787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); 1281787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); 128204a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 1283943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman kfree(data); 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1285787c72b107888805981faf148c8fea96a752d22eJean Delvare res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1286787c72b107888805981faf148c8fea96a752d22eJean Delvare release_region(res->start, WINB_REGION_SIZE); 1287787c72b107888805981faf148c8fea96a752d22eJean Delvare 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1292d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare/* Registers 0x50-0x5f are banked */ 1293d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvarestatic inline void w83627hf_set_bank(struct w83627hf_data *data, u16 reg) 1294d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare{ 1295d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare if ((reg & 0x00f0) == 0x50) { 1296d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); 1297d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(reg >> 8, data->addr + W83781D_DATA_REG_OFFSET); 1298d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare } 1299d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare} 1300d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare 1301d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare/* Not strictly necessary, but play it safe for now */ 1302d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvarestatic inline void w83627hf_reset_bank(struct w83627hf_data *data, u16 reg) 1303d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare{ 1304d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare if (reg & 0xff00) { 1305d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); 1306d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); 1307d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare } 1308d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare} 1309d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare 1310787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_read_value(struct w83627hf_data *data, u16 reg) 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res, word_sized; 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13149a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->lock); 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_sized = (((reg & 0xff00) == 0x100) 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0xff00) == 0x200)) 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (((reg & 0x00ff) == 0x50) 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x53) 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x55)); 1320d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_set_bank(data, reg); 1321787c72b107888805981faf148c8fea96a752d22eJean Delvare outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); 1322787c72b107888805981faf148c8fea96a752d22eJean Delvare res = inb_p(data->addr + W83781D_DATA_REG_OFFSET); 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (word_sized) { 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p((reg & 0xff) + 1, 1325787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_ADDR_REG_OFFSET); 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = 1327787c72b107888805981faf148c8fea96a752d22eJean Delvare (res << 8) + inb_p(data->addr + 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_DATA_REG_OFFSET); 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1330d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_reset_bank(data, reg); 13319a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->lock); 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1335787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83627thf_read_gpio5(struct platform_device *pdev) 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res = 0xff, sel; 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_enter(); 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_select(W83627HF_LD_GPIO5); 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure these GPIO pins are enabled */ 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) { 1344787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n"); 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure the pins are configured for input 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds There must be at least five (VRM 9), and possibly 6 (VRM 10) */ 1350dd149c52223cfb05cdefb0755d3c2793e8d33edeYuan Mu sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((sel & 0x1f) != 0x1f) { 1352787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "GPIO5 not configured for VID " 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "function\n"); 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1357787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_info(&pdev->dev, "Reading VID from GPIO5\n"); 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = superio_inb(W83627THF_GPIO5_DR) & sel; 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_exit(); 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1365787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83687thf_read_vid(struct platform_device *pdev) 1366c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare{ 1367c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare int res = 0xff; 1368c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1369c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_enter(); 1370c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_select(W83627HF_LD_HWM); 1371c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1372c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare /* Make sure these GPIO pins are enabled */ 1373c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { 1374787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "VID disabled, no VID function\n"); 1375c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare goto exit; 1376c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare } 1377c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1378c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare /* Make sure the pins are configured for input */ 1379c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { 1380787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "VID configured as output, " 1381c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare "no VID function\n"); 1382c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare goto exit; 1383c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare } 1384c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1385c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare res = superio_inb(W83687THF_VID_DATA) & 0x3f; 1386c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1387c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvareexit: 1388c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_exit(); 1389c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare return res; 1390c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare} 1391c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1392787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int word_sized; 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13969a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->lock); 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_sized = (((reg & 0xff00) == 0x100) 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0xff00) == 0x200)) 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (((reg & 0x00ff) == 0x53) 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x55)); 1401d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_set_bank(data, reg); 1402787c72b107888805981faf148c8fea96a752d22eJean Delvare outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (word_sized) { 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(value >> 8, 1405787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_DATA_REG_OFFSET); 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p((reg & 0xff) + 1, 1407787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_ADDR_REG_OFFSET); 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(value & 0xff, 1410787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_DATA_REG_OFFSET); 1411d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_reset_bank(data, reg); 14129a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->lock); 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1416787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic void __devinit w83627hf_init_device(struct platform_device *pdev) 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1418787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = platform_get_drvdata(pdev); 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1420d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare enum chips type = data->type; 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tmp; 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14232251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare if (reset) { 14242251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare /* Resetting the chip has been the default for a long time, 14252251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare but repeatedly caused problems (fans going to full 14262251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare speed...) so it is now optional. It might even go away if 14272251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare nobody reports it as being useful, as I see very little 14282251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare reason why this would be needed at all. */ 1429787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_info(&pdev->dev, "If reset=1 solved a problem you were " 14302251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare "having, please report!\n"); 14312251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* save this register */ 1433787c72b107888805981faf148c8fea96a752d22eJean Delvare i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset all except Watchdog values and last conversion values 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This sets fan-divs to 2, among others */ 1436787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Restore the register and disable power-on abnormal beep. 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This saves FAN 1/2/3 input/output values set by BIOS. */ 1439787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable master beep-enable (reset turns it on). 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Individual beeps should be reset to off but for some reason 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disabling this bit helps some people not get beeped */ 1443787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Minimize conflicts with other winbond i2c-only clients... */ 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* disable i2c subclients... how to disable main i2c client?? */ 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* force i2c address to relatively uncommon address */ 1449787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); 1450787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Read VID only once */ 1453d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (type == w83627hf || type == w83637hf) { 1454787c72b107888805981faf148c8fea96a752d22eJean Delvare int lo = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); 1455787c72b107888805981faf148c8fea96a752d22eJean Delvare int hi = w83627hf_read_value(data, W83781D_REG_CHIPID); 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); 1457d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } else if (type == w83627thf) { 1458787c72b107888805981faf148c8fea96a752d22eJean Delvare data->vid = w83627thf_read_gpio5(pdev); 1459d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } else if (type == w83687thf) { 1460787c72b107888805981faf148c8fea96a752d22eJean Delvare data->vid = w83687thf_read_vid(pdev); 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Read VRM & OVT Config only once */ 1464d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (type == w83627thf || type == w83637hf || type == w83687thf) { 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vrm_ovt = 1466787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83627THF_REG_VRM_OVT_CFG); 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1469787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i <= 3; i++) { 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(tmp & BIT_SCFG1[i - 1])) { 1472b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare data->sens[i - 1] = 4; 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (w83627hf_read_value 1475787c72b107888805981faf148c8fea96a752d22eJean Delvare (data, 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->sens[i - 1] = 1; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->sens[i - 1] = 2; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((type == w83697hf) && (i == 2)) 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(init) { 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Enable temp2 */ 1487df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp & 0x01) { 1489787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_warn(&pdev->dev, "Enabling temp2, readings " 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "might not make sense\n"); 1491df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG, 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp & 0xfe); 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Enable temp3 */ 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type != w83697hf) { 1497787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, 1498df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie W83627HF_REG_TEMP3_CONFIG); 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp & 0x01) { 1500787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_warn(&pdev->dev, "Enabling temp3, " 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "readings might not make sense\n"); 1502787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 1503df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe); 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start monitoring */ 1509787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_CONFIG, 1510787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_CONFIG) & 0xf7) 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | 0x01); 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1515c09c5184a26158da32801e89d5849d774605f0ddJean Delvarestatic void w83627hf_update_fan_div(struct w83627hf_data *data) 1516c09c5184a26158da32801e89d5849d774605f0ddJean Delvare{ 1517c09c5184a26158da32801e89d5849d774605f0ddJean Delvare int reg; 1518c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 1519c09c5184a26158da32801e89d5849d774605f0ddJean Delvare reg = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); 1520c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[0] = (reg >> 4) & 0x03; 1521c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[1] = (reg >> 6) & 0x03; 1522c09c5184a26158da32801e89d5849d774605f0ddJean Delvare if (data->type != w83697hf) { 1523c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[2] = (w83627hf_read_value(data, 1524c09c5184a26158da32801e89d5849d774605f0ddJean Delvare W83781D_REG_PIN) >> 6) & 0x03; 1525c09c5184a26158da32801e89d5849d774605f0ddJean Delvare } 1526c09c5184a26158da32801e89d5849d774605f0ddJean Delvare reg = w83627hf_read_value(data, W83781D_REG_VBAT); 1527c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[0] |= (reg >> 3) & 0x04; 1528c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[1] |= (reg >> 4) & 0x04; 1529c09c5184a26158da32801e89d5849d774605f0ddJean Delvare if (data->type != w83697hf) 1530c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[2] |= (reg >> 5) & 0x04; 1531c09c5184a26158da32801e89d5849d774605f0ddJean Delvare} 1532c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct w83627hf_data *w83627hf_update_device(struct device *dev) 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1535787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 1536df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie int i, num_temps = (data->type == w83697hf) ? 2 : 3; 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15389a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || !data->valid) { 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i <= 8; i++) { 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* skip missing sensors */ 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((data->type == w83697hf) && (i == 1)) || 1545c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare ((data->type != w83627hf && data->type != w83697hf) 15464a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu && (i == 5 || i == 6))) 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in[i] = 1549787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_IN(i)); 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_min[i] = 1551787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_IN_MIN(i)); 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_max[i] = 1554787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_IN_MAX(i)); 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i <= 3; i++) { 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan[i - 1] = 1559787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_FAN(i)); 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_min[i - 1] = 1561787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_FAN_MIN(i)); 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 156407584c762541672e35735b52af031183ca17a5a2Jim Cromie for (i = 0; i <= 2; i++) { 1565787c72b107888805981faf148c8fea96a752d22eJean Delvare u8 tmp = w83627hf_read_value(data, 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, i)); 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bits 0-3 are reserved in 627THF */ 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data->type == w83627thf) 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp &= 0xf0; 157007584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[i] = tmp; 157107584c762541672e35735b52af031183ca17a5a2Jim Cromie if (i == 1 && 157207584c762541672e35735b52af031183ca17a5a2Jim Cromie (data->type == w83627hf || data->type == w83697hf)) 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15751550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) { 15761550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 tmp = w83627hf_read_value(data, 15771550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83627HF_REG_PWM_FREQ); 15781550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[0] = tmp & 0x07; 15791550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[1] = (tmp >> 4) & 0x07; 15801550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } else if (data->type != w83627thf) { 15811550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez for (i = 1; i <= 3; i++) { 15821550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[i - 1] = 15831550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez w83627hf_read_value(data, 15841550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ[i - 1]); 15851550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (i == 2 && (data->type == w83697hf)) 15861550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez break; 15871550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 15881550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 1589df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie for (i = 0; i < num_temps; i++) { 1590df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp[i] = w83627hf_read_value( 1591df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp[i]); 1592df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max[i] = w83627hf_read_value( 1593df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp_over[i]); 1594df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max_hyst[i] = w83627hf_read_value( 1595df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp_hyst[i]); 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1598c09c5184a26158da32801e89d5849d774605f0ddJean Delvare w83627hf_update_fan_div(data); 1599c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->alarms = 1601787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_ALARM1) | 1602787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) | 1603787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, W83781D_REG_ALARM3) << 16); 1604787c72b107888805981faf148c8fea96a752d22eJean Delvare i = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2); 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->beep_enable = i >> 7; 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->beep_mask = ((i & 0x7f) << 8) | 1607787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) | 1608787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16; 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->last_updated = jiffies; 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->valid = 1; 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16139a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return data; 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1618787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __init w83627hf_device_add(unsigned short address, 1619787c72b107888805981faf148c8fea96a752d22eJean Delvare const struct w83627hf_sio_data *sio_data) 1620787c72b107888805981faf148c8fea96a752d22eJean Delvare{ 1621787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource res = { 1622787c72b107888805981faf148c8fea96a752d22eJean Delvare .start = address + WINB_REGION_OFFSET, 1623787c72b107888805981faf148c8fea96a752d22eJean Delvare .end = address + WINB_REGION_OFFSET + WINB_REGION_SIZE - 1, 1624787c72b107888805981faf148c8fea96a752d22eJean Delvare .name = DRVNAME, 1625787c72b107888805981faf148c8fea96a752d22eJean Delvare .flags = IORESOURCE_IO, 1626787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1627787c72b107888805981faf148c8fea96a752d22eJean Delvare int err; 1628787c72b107888805981faf148c8fea96a752d22eJean Delvare 1629787c72b107888805981faf148c8fea96a752d22eJean Delvare pdev = platform_device_alloc(DRVNAME, address); 1630787c72b107888805981faf148c8fea96a752d22eJean Delvare if (!pdev) { 1631787c72b107888805981faf148c8fea96a752d22eJean Delvare err = -ENOMEM; 1632787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device allocation failed\n"); 1633787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit; 1634787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1635787c72b107888805981faf148c8fea96a752d22eJean Delvare 1636787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_device_add_resources(pdev, &res, 1); 1637787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) { 1638787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device resource addition failed " 1639787c72b107888805981faf148c8fea96a752d22eJean Delvare "(%d)\n", err); 1640787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1641787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1642787c72b107888805981faf148c8fea96a752d22eJean Delvare 16432df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare err = platform_device_add_data(pdev, sio_data, 16442df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare sizeof(struct w83627hf_sio_data)); 16452df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare if (err) { 1646787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); 1647787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1648787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1649787c72b107888805981faf148c8fea96a752d22eJean Delvare 1650787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_device_add(pdev); 1651787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) { 1652787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", 1653787c72b107888805981faf148c8fea96a752d22eJean Delvare err); 1654787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1655787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1656787c72b107888805981faf148c8fea96a752d22eJean Delvare 1657787c72b107888805981faf148c8fea96a752d22eJean Delvare return 0; 1658787c72b107888805981faf148c8fea96a752d22eJean Delvare 1659787c72b107888805981faf148c8fea96a752d22eJean Delvareexit_device_put: 1660787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_device_put(pdev); 1661787c72b107888805981faf148c8fea96a752d22eJean Delvareexit: 1662787c72b107888805981faf148c8fea96a752d22eJean Delvare return err; 1663787c72b107888805981faf148c8fea96a752d22eJean Delvare} 1664787c72b107888805981faf148c8fea96a752d22eJean Delvare 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init sensors_w83627hf_init(void) 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1667787c72b107888805981faf148c8fea96a752d22eJean Delvare int err; 1668787c72b107888805981faf148c8fea96a752d22eJean Delvare unsigned short address; 1669787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data sio_data; 1670787c72b107888805981faf148c8fea96a752d22eJean Delvare 1671787c72b107888805981faf148c8fea96a752d22eJean Delvare if (w83627hf_find(0x2e, &address, &sio_data) 1672787c72b107888805981faf148c8fea96a752d22eJean Delvare && w83627hf_find(0x4e, &address, &sio_data)) 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1675787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_driver_register(&w83627hf_driver); 1676787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) 1677787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit; 1678787c72b107888805981faf148c8fea96a752d22eJean Delvare 1679787c72b107888805981faf148c8fea96a752d22eJean Delvare /* Sets global pdev as a side effect */ 1680787c72b107888805981faf148c8fea96a752d22eJean Delvare err = w83627hf_device_add(address, &sio_data); 1681787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) 1682787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_driver; 1683787c72b107888805981faf148c8fea96a752d22eJean Delvare 1684787c72b107888805981faf148c8fea96a752d22eJean Delvare return 0; 1685787c72b107888805981faf148c8fea96a752d22eJean Delvare 1686787c72b107888805981faf148c8fea96a752d22eJean Delvareexit_driver: 1687787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_driver_unregister(&w83627hf_driver); 1688787c72b107888805981faf148c8fea96a752d22eJean Delvareexit: 1689787c72b107888805981faf148c8fea96a752d22eJean Delvare return err; 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit sensors_w83627hf_exit(void) 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1694787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_device_unregister(pdev); 1695787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_driver_unregister(&w83627hf_driver); 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Philip Edelbrock <phil@netroedge.com>, " 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "and Mark Studebaker <mdsxyz123@yahoo.com>"); 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("W83627HF driver"); 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sensors_w83627hf_init); 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(sensors_w83627hf_exit); 1706