w83627hf.c revision 1c1381076f8c6cf0a2c9918194e3fa6369cdf06a
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 7867b671bceb4a8340a30929e9642620d99ed5ad76Jean Delvarestatic unsigned short force_id; 7967b671bceb4a8340a30929e9642620d99ed5ad76Jean Delvaremodule_param(force_id, ushort, 0); 8067b671bceb4a8340a30929e9642620d99ed5ad76Jean DelvareMODULE_PARM_DESC(force_id, "Override the detected device ID"); 8167b671bceb4a8340a30929e9642620d99ed5ad76Jean Delvare 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* modified from kernel/include/traps.c */ 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int REG; /* The register to read/write */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEV 0x07 /* Register: Logical device select */ 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int VAL; /* The value to read/write */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* logical device numbers for superio_select (below) */ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_FDC 0x00 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_PRT 0x01 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_UART1 0x02 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_UART2 0x03 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_KBC 0x05 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_CIR 0x06 /* w83627hf only */ 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GAME 0x07 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_MIDI 0x07 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO1 0x07 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO5 0x07 /* w83627thf only */ 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO2 0x08 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO3 0x09 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_GPIO4 0x09 /* w83627thf only */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_ACPI 0x0a 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_LD_HWM 0x0b 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEVID 0x20 /* Register: Device ID */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_EN 0x30 /* w83627thf only */ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */ 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */ 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 110c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_EN 0x29 /* w83687thf only */ 111c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_CFG 0xF0 /* w83687thf only */ 112c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83687THF_VID_DATA 0xF1 /* w83687thf only */ 113c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_outb(int reg, int val) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(reg, REG); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(val, VAL); 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_inb(int reg) 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(reg, REG); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return inb(VAL); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_select(int ld) 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(DEV, REG); 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(ld, VAL); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_enter(void) 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0x87, REG); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0x87, REG); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssuperio_exit(void) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb(0xAA, REG); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W627_DEVID 0x52 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W627THF_DEVID 0x82 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W697_DEVID 0x60 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W637_DEVID 0x70 152c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W687THF_DEVID 0x85 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WINB_ACT_REG 0x30 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WINB_BASE_REG 0x60 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Constants specified below */ 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 157ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec/* Alignment of the base address */ 158ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_ALIGNMENT ~7 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 160ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec/* Offset & size of I/O region we are interested in */ 161ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_REGION_OFFSET 5 162ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec#define WINB_REGION_SIZE 2 163ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec 164787c72b107888805981faf148c8fea96a752d22eJean Delvare/* Where are the sensors address/data registers relative to the region offset */ 165787c72b107888805981faf148c8fea96a752d22eJean Delvare#define W83781D_ADDR_REG_OFFSET 0 166787c72b107888805981faf148c8fea96a752d22eJean Delvare#define W83781D_DATA_REG_OFFSET 1 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The W83781D registers */ 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The W83782D registers for nr=7,8 are in bank 5 */ 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x554 + (((nr) - 7) * 2))) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x555 + (((nr) - 7) * 2))) 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (0x550 + (nr) - 7)) 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1772ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie/* nr:0-2 for fans:1-3 */ 1782ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie#define W83627HF_REG_FAN_MIN(nr) (0x3b + (nr)) 1792ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie#define W83627HF_REG_FAN(nr) (0x28 + (nr)) 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie#define W83627HF_REG_TEMP2_CONFIG 0x152 182df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie#define W83627HF_REG_TEMP3_CONFIG 0x252 183df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie/* these are zero-based, unlike config constants above */ 184df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp[] = { 0x27, 0x150, 0x250 }; 185df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp_hyst[] = { 0x3A, 0x153, 0x253 }; 186df48ed804f44a040e990976b537efc1e133c74d8Jim Cromiestatic const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BANK 0x4E 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CONFIG 0x40 1914a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM1 0x459 1924a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM2 0x45A 1934a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu#define W83781D_REG_ALARM3 0x45B 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_CONFIG 0x4D 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS1 0x56 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS2 0x57 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_BEEP_INTS3 0x453 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_VID_FANDIV 0x47 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CHIPID 0x49 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_WCHIPID 0x58 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_CHIPMAN 0x4F 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_PIN 0x4B 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_VBAT 0x5D 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_REG_PWM1 0x5A 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83627HF_REG_PWM2 0x5B 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 212c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */ 213c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */ 214c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 216c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */ 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 }; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2, 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83627THF_REG_PWM3 }; 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W836X7HF_REG_PWM(type, nr) (((type) == w83627hf) ? \ 22207584c762541672e35735b52af031183ca17a5a2Jim Cromie regpwm_627hf[nr] : regpwm[nr]) 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83627HF_REG_PWM_FREQ 0x5C /* Only for the 627HF */ 2251550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2261550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ1 0x00 /* 697HF/687THF too */ 2271550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ2 0x02 /* 697HF/687THF too */ 2281550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83637HF_REG_PWM_FREQ3 0x10 /* 687THF too */ 2291550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2301550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic const u8 W83637HF_REG_PWM_FREQ[] = { W83637HF_REG_PWM_FREQ1, 2311550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ2, 2321550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ3 }; 2331550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2341550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez#define W83627HF_BASE_PWM_FREQ 46870 2351550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_I2C_ADDR 0x48 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_I2C_SUBADDR 0x4A 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Sensor selection */ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_SCFG1 0x5D 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 BIT_SCFG1[] = { 0x02, 0x04, 0x08 }; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_REG_SCFG2 0x59 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define W83781D_DEFAULT_BETA 3435 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Conversions. Limit checking is only done on the TO_REG 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds variants. Note that you should be a bit careful with which arguments 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds these macros are called: arguments may be evaluated more than once. 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Fixing this is just not worth it. */ 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 8)/16),0,255)) 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IN_FROM_REG(val) ((val) * 16) 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 FAN_TO_REG(long rpm, int div) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rpm == 0) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 255; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rpm = SENSORS_LIMIT(rpm, 1, 1000000); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 254); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_MIN (-128000) 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_MAX ( 127000) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* TEMP: 0.001C/bit (-128C to +127C) 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds REG: 1C/bit, two's complement */ 2675bfedac045082a97e20d47d876071279ef984d28Christian Hohnstaedtstatic u8 TEMP_TO_REG(long temp) 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ntemp = SENSORS_LIMIT(temp, TEMP_MIN, TEMP_MAX); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ntemp += (ntemp<0 ? -500 : 500); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (u8)(ntemp / 1000); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int TEMP_FROM_REG(u8 reg) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (s8)reg * 1000; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div))) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2831550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline unsigned long pwm_freq_from_reg_627hf(u8 reg) 2841550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 2851550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez unsigned long freq; 2861550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez freq = W83627HF_BASE_PWM_FREQ >> reg; 2871550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return freq; 2881550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 2891550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline u8 pwm_freq_to_reg_627hf(unsigned long val) 2901550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 2911550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 i; 2921550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Only 5 dividers (1 2 4 8 16) 2931550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez Search for the nearest available frequency */ 2941550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez for (i = 0; i < 4; i++) { 2951550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val > (((W83627HF_BASE_PWM_FREQ >> i) + 2961550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez (W83627HF_BASE_PWM_FREQ >> (i+1))) / 2)) 2971550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez break; 2981550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 2991550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return i; 3001550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 3011550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 3021550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline unsigned long pwm_freq_from_reg(u8 reg) 3031550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 3041550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Clock bit 8 -> 180 kHz or 24 MHz */ 3051550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez unsigned long clock = (reg & 0x80) ? 180000UL : 24000000UL; 3061550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 3071550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez reg &= 0x7f; 3081550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* This should not happen but anyway... */ 3091550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (reg == 0) 3101550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez reg++; 3111550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (clock / (reg << 8)); 3121550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 3131550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic inline u8 pwm_freq_to_reg(unsigned long val) 3141550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 3151550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez /* Minimum divider value is 0x01 and maximum is 0x7F */ 3161550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val >= 93750) /* The highest we can do */ 3171550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return 0x01; 3181550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val >= 720) /* Use 24 MHz clock */ 3191550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (24000000UL / (val << 8)); 3201550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (val < 6) /* The lowest we can do */ 3211550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return 0xFF; 3221550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez else /* Use 180 kHz clock */ 3231550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return (0x80 | (180000UL / (val << 8))); 3241550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 3251550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 3261c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare#define BEEP_MASK_FROM_REG(val) ((val) & 0xff7fff) 3271c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare#define BEEP_MASK_TO_REG(val) ((val) & 0xff7fff) 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DIV_FROM_REG(val) (1 << (val)) 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 DIV_TO_REG(long val) 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = SENSORS_LIMIT(val, 1, 128) >> 1; 335abc01922477104e8d72b494902aff37135c409e7Grant Coady for (i = 0; i < 7; i++) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val == 0) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val >>= 1; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ((u8) i); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 343ed6bafbf6017d6a007b39de6b65ad3b8ae4c8aeeJean Delvare/* For each registered chip, we need to keep some data in memory. 344ed6bafbf6017d6a007b39de6b65ad3b8ae4c8aeeJean Delvare The structure is dynamically allocated. */ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct w83627hf_data { 346787c72b107888805981faf148c8fea96a752d22eJean Delvare unsigned short addr; 347787c72b107888805981faf148c8fea96a752d22eJean Delvare const char *name; 3481beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones struct device *hwmon_dev; 3499a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex lock; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enum chips type; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3529a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex update_lock; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char valid; /* !=0 if following fields are valid */ 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long last_updated; /* In jiffies */ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in[9]; /* Register value */ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_max[9]; /* Register value */ 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_min[9]; /* Register value */ 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan[3]; /* Register value */ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan_min[3]; /* Register value */ 361df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp[3]; /* Register value */ 362df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp_max[3]; /* Register value */ 363df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 temp_max_hyst[3]; /* Register value */ 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fan_div[3]; /* Register encoding, shifted right */ 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vid; /* Register encoding, combined */ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 alarms; /* Register encoding, combined */ 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 beep_mask; /* Register encoding, combined */ 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 pwm[3]; /* Register value */ 3691550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 pwm_freq[3]; /* Register value */ 370b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare u16 sens[3]; /* 1 = pentium diode; 2 = 3904 diode; 371b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare 4 = thermistor */ 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vrm; 373c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 376787c72b107888805981faf148c8fea96a752d22eJean Delvarestruct w83627hf_sio_data { 377787c72b107888805981faf148c8fea96a752d22eJean Delvare enum chips type; 378787c72b107888805981faf148c8fea96a752d22eJean Delvare}; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_probe(struct platform_device *pdev); 382d0546128980c18748010c758903b02909e634830Jean Delvarestatic int __devexit w83627hf_remove(struct platform_device *pdev); 383787c72b107888805981faf148c8fea96a752d22eJean Delvare 384787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_read_value(struct w83627hf_data *data, u16 reg); 385787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); 386c09c5184a26158da32801e89d5849d774605f0ddJean Delvarestatic void w83627hf_update_fan_div(struct w83627hf_data *data); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct w83627hf_data *w83627hf_update_device(struct device *dev); 388787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic void w83627hf_init_device(struct platform_device *pdev); 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 390787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic struct platform_driver w83627hf_driver = { 391cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard .driver = { 392872188420997f7f7c1b968fd9bce6578e4c3d45fJean Delvare .owner = THIS_MODULE, 393d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare .name = DRVNAME, 394cdaf79349c7d24e1d33acb6497849c9e956a33eaLaurent Riffard }, 395787c72b107888805981faf148c8fea96a752d22eJean Delvare .probe = w83627hf_probe, 396787c72b107888805981faf148c8fea96a752d22eJean Delvare .remove = __devexit_p(w83627hf_remove), 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 39907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 40007584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_input(struct device *dev, struct device_attribute *devattr, char *buf) 40107584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 40207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 40307584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 40407584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in[nr])); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 40607584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 40707584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_min(struct device *dev, struct device_attribute *devattr, char *buf) 40807584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 40907584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 41007584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 41107584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_min[nr])); 41207584c762541672e35735b52af031183ca17a5a2Jim Cromie} 41307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 41407584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_in_max(struct device *dev, struct device_attribute *devattr, char *buf) 41507584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 41607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 41707584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 41807584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long)IN_FROM_REG(data->in_max[nr])); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 42007584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 42107584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_in_min(struct device *dev, struct device_attribute *devattr, 42207584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 42307584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 42407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 42507584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 42607584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42807584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 42907584c762541672e35735b52af031183ca17a5a2Jim Cromie data->in_min[nr] = IN_TO_REG(val); 43007584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83781D_REG_IN_MIN(nr), data->in_min[nr]); 43107584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 43207584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 43307584c762541672e35735b52af031183ca17a5a2Jim Cromie} 43407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 43507584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_in_max(struct device *dev, struct device_attribute *devattr, 43607584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 43707584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 43807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 43907584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 44007584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44207584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 44307584c762541672e35735b52af031183ca17a5a2Jim Cromie data->in_max[nr] = IN_TO_REG(val); 44407584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83781D_REG_IN_MAX(nr), data->in_max[nr]); 44507584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 44607584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 44707584c762541672e35735b52af031183ca17a5a2Jim Cromie} 44807584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_vin_decl(offset) \ 44907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ 45007584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_input, NULL, offset); \ 45107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO|S_IWUSR, \ 45207584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_min, store_in_min, offset); \ 45307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO|S_IWUSR, \ 45407584c762541672e35735b52af031183ca17a5a2Jim Cromie show_in_max, store_in_max, offset); 45507584c762541672e35735b52af031183ca17a5a2Jim Cromie 45607584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(1); 45707584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(2); 45807584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(3); 45907584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(4); 46007584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(5); 46107584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(6); 46207584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(7); 46307584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_vin_decl(8); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* use a different set of functions for in0 */ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg) 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long in0; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 471c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 472c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in0 = (long)((reg * 488 + 70000 + 50) / 100); 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in0 = (long)IN_FROM_REG(reg); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf,"%ld\n", in0); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 483a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_0(struct device *dev, struct device_attribute *attr, char *buf) 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in[0]); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 489a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_min0(struct device *dev, struct device_attribute *attr, char *buf) 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in_min[0]); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 495a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *attr, char *buf) 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return show_in_0(data, buf, data->in_max[0]); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr, 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *buf, size_t count) 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 504787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 512c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 513c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 5162723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu data->in_min[0] = 5172723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0, 5182723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu 255); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_min[0] = IN_TO_REG(val); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 523787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_IN_MIN(0), data->in_min[0]); 5249a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 528a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustatic ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr, 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *buf, size_t count) 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 531787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5369a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((data->vrm_ovt & 0x01) && 539c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare (w83627thf == data->type || w83637hf == data->type 540c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare || w83687thf == data->type)) 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM9 calculation */ 5432723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu data->in_max[0] = 5442723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu SENSORS_LIMIT(((val * 100) - 70000 + 244) / 488, 0, 5452723ab91cb4019def10bdb01b0fecb85e6ac7884Yuan Mu 255); 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use VRM8 (standard) calculation */ 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_max[0] = IN_TO_REG(val); 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 550787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_IN_MAX(0), data->in_max[0]); 5519a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_input, S_IRUGO, show_regs_in_0, NULL); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs_in_min0, store_regs_in_min0); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds show_regs_in_max0, store_regs_in_max0); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 56207584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_input(struct device *dev, struct device_attribute *devattr, char *buf) 56307584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 56407584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 56507584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 56607584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan[nr], 56707584c762541672e35735b52af031183ca17a5a2Jim Cromie (long)DIV_FROM_REG(data->fan_div[nr]))); 56807584c762541672e35735b52af031183ca17a5a2Jim Cromie} 56907584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 57007584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_min(struct device *dev, struct device_attribute *devattr, char *buf) 57107584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 57207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 57307584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 57407584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", FAN_FROM_REG(data->fan_min[nr], 57507584c762541672e35735b52af031183ca17a5a2Jim Cromie (long)DIV_FROM_REG(data->fan_div[nr]))); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 57807584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_fan_min(struct device *dev, struct device_attribute *devattr, 57907584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 58107584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 582787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 58307584c762541672e35735b52af031183ca17a5a2Jim Cromie u32 val = simple_strtoul(buf, NULL, 10); 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5859a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 58607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 5872ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), 58807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->fan_min[nr]); 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5909a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 59307584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_fan_decl(offset) \ 59407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 59507584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_input, NULL, offset - 1); \ 59607584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 59707584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_min, store_fan_min, offset - 1); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59907584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(1); 60007584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(2); 60107584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_fan_decl(3); 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 60407584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp(struct device *dev, struct device_attribute *devattr, char *buf) 60507584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 60607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 60707584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 608df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 609df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp[nr]; 610df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 611df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 61507584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_max(struct device *dev, struct device_attribute *devattr, 61607584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 61707584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 61807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 61907584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 620df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 621df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp_max[nr]; 622df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 623df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62607584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 62707584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_max_hyst(struct device *dev, struct device_attribute *devattr, 62807584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 62907584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 63007584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 63107584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = w83627hf_update_device(dev); 632df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie 633df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = data->temp_max_hyst[nr]; 634df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) 635df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie : (long) TEMP_FROM_REG(tmp)); 63607584c762541672e35735b52af031183ca17a5a2Jim Cromie} 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 63807584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 63907584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_max(struct device *dev, struct device_attribute *devattr, 64007584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 64107584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 64207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 64307584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 64407584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 645df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 64707584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 648df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max[nr] = tmp; 649df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp); 65007584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 65107584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 65207584c762541672e35735b52af031183ca17a5a2Jim Cromie} 65307584c762541672e35735b52af031183ca17a5a2Jim Cromie 65407584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 65507584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_max_hyst(struct device *dev, struct device_attribute *devattr, 65607584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 65707584c762541672e35735b52af031183ca17a5a2Jim Cromie{ 65807584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 65907584c762541672e35735b52af031183ca17a5a2Jim Cromie struct w83627hf_data *data = dev_get_drvdata(dev); 66007584c762541672e35735b52af031183ca17a5a2Jim Cromie long val = simple_strtol(buf, NULL, 10); 661df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); 66207584c762541672e35735b52af031183ca17a5a2Jim Cromie 66307584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_lock(&data->update_lock); 664df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max_hyst[nr] = tmp; 665df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp); 66607584c762541672e35735b52af031183ca17a5a2Jim Cromie mutex_unlock(&data->update_lock); 66707584c762541672e35735b52af031183ca17a5a2Jim Cromie return count; 66807584c762541672e35735b52af031183ca17a5a2Jim Cromie} 66907584c762541672e35735b52af031183ca17a5a2Jim Cromie 67007584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_temp_decl(offset) \ 67107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ 672df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp, NULL, offset - 1); \ 67307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR, \ 674df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp_max, store_temp_max, offset - 1); \ 67507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR, \ 676df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie show_temp_max_hyst, store_temp_max_hyst, offset - 1); 67707584c762541672e35735b52af031183ca17a5a2Jim Cromie 67807584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(1); 67907584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(2); 68007584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_decl(3); 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 683a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm)); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 691a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 69390d6619a916062cb75a176aacb318d108758b4a5Jean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) data->vrm); 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 697a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoustore_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 699787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vrm = val; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 710a5099cfc2e82240b0a3e72ad79a5969d5af1a7dcYani Ioannoushow_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) data->alarms); 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 717e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic ssize_t 718e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvareshow_alarm(struct device *dev, struct device_attribute *attr, char *buf) 719e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare{ 720e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare struct w83627hf_data *data = w83627hf_update_device(dev); 721e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare int bitnr = to_sensor_dev_attr(attr)->index; 722e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); 723e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare} 724e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 725e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 726e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); 727e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); 728e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); 729e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9); 730e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10); 731e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 16); 732e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 17); 733e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); 734e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); 735e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11); 736e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); 737e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); 738e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13); 739e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 7401c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvarestatic ssize_t 7411c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvareshow_beep_mask(struct device *dev, struct device_attribute *attr, char *buf) 7421c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare{ 7431c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare struct w83627hf_data *data = w83627hf_update_device(dev); 7441c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare return sprintf(buf, "%ld\n", 7451c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare (long)BEEP_MASK_FROM_REG(data->beep_mask)); 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 7491c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvarestore_beep_mask(struct device *dev, struct device_attribute *attr, 7501c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare const char *buf, size_t count) 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 752787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 7531c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare unsigned long val; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7579a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7591c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare /* preserve beep enable */ 7601c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare data->beep_mask = (data->beep_mask & 0x8000) 7611c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare | BEEP_MASK_TO_REG(val); 7621c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS1, 7631c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare data->beep_mask & 0xff); 7641c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS3, 7651c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare ((data->beep_mask) >> 16) & 0xff); 766787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 7671c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare (data->beep_mask >> 8) & 0xff); 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7699a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7731c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvarestatic DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, 7741c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare show_beep_mask, store_beep_mask); 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 777e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvareshow_beep(struct device *dev, struct device_attribute *attr, char *buf) 778e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare{ 779e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare struct w83627hf_data *data = w83627hf_update_device(dev); 780e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare int bitnr = to_sensor_dev_attr(attr)->index; 781e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare return sprintf(buf, "%u\n", (data->beep_mask >> bitnr) & 1); 782e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare} 783e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 784e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic ssize_t 785e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestore_beep(struct device *dev, struct device_attribute *attr, 786e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare const char *buf, size_t count) 787e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare{ 788e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 789e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare int bitnr = to_sensor_dev_attr(attr)->index; 790e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare unsigned long bit; 791e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare u8 reg; 792e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 793e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare bit = simple_strtoul(buf, NULL, 10); 794e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bit & ~1) 795e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare return -EINVAL; 796e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 797e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare mutex_lock(&data->update_lock); 798e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bit) 799e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare data->beep_mask |= (1 << bitnr); 800e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare else 801e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare data->beep_mask &= ~(1 << bitnr); 802e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 803e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bitnr < 8) { 804e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS1); 805e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bit) 806e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg |= (1 << bitnr); 807e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare else 808e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg &= ~(1 << bitnr); 809e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS1, reg); 810e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare } else if (bitnr < 16) { 811e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2); 812e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bit) 813e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg |= (1 << (bitnr - 8)); 814e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare else 815e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg &= ~(1 << (bitnr - 8)); 816e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, reg); 817e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare } else { 818e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg = w83627hf_read_value(data, W83781D_REG_BEEP_INTS3); 819e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare if (bit) 820e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg |= (1 << (bitnr - 16)); 821e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare else 822e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare reg &= ~(1 << (bitnr - 16)); 823e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS3, reg); 824e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare } 825e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare mutex_unlock(&data->update_lock); 826e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 827e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare return count; 828e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare} 829e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 830e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR, 831e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 0); 832e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO | S_IWUSR, 833e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 1); 834e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO | S_IWUSR, 835e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 2); 836e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO | S_IWUSR, 837e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 3); 838e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO | S_IWUSR, 839e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 8); 840e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO | S_IWUSR, 841e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 9); 842e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO | S_IWUSR, 843e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 10); 844e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO | S_IWUSR, 845e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 16); 846e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(in8_beep, S_IRUGO | S_IWUSR, 847e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 17); 848e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO | S_IWUSR, 849e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 6); 850e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO | S_IWUSR, 851e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 7); 852e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO | S_IWUSR, 853e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 11); 854e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR, 855e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 4); 856e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR, 857e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 5); 858e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO | S_IWUSR, 859e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare show_beep, store_beep, 13); 8601c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvarestatic SENSOR_DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, 8611c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare show_beep, store_beep, 15); 862e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare 863e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvarestatic ssize_t 86407584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_fan_div(struct device *dev, struct device_attribute *devattr, char *buf) 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 86607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", 86907584c762541672e35735b52af031183ca17a5a2Jim Cromie (long) DIV_FROM_REG(data->fan_div[nr])); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Note: we save and restore the fan minimum here, because its value is 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds determined in part by the fan divisor. This follows the principle of 873d6e05edc59ecd79e8badf440c0d295a979bdfa3eAndreas Mohr least surprise; the user doesn't expect the fan minimum to change just 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds because the divisor changed. */ 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 87607584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_fan_div(struct device *dev, struct device_attribute *devattr, 87707584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 87907584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 880787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long min; 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 reg; 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long val = simple_strtoul(buf, NULL, 10); 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8859a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Save fan_min */ 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds min = FAN_FROM_REG(data->fan_min[nr], 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DIV_FROM_REG(data->fan_div[nr])); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_div[nr] = DIV_TO_REG(val); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 893787c72b107888805981faf148c8fea96a752d22eJean Delvare reg = (w83627hf_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds & (nr==0 ? 0xcf : 0x3f)) 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); 896787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 898787c72b107888805981faf148c8fea96a752d22eJean Delvare reg = (w83627hf_read_value(data, W83781D_REG_VBAT) 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds & ~(1 << (5 + nr))) 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | ((data->fan_div[nr] & 0x04) << (3 + nr)); 901787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_VBAT, reg); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Restore fan_min */ 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); 9052ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), data->fan_min[nr]); 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9079a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO|S_IWUSR, 91207584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 0); 91307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO|S_IWUSR, 91407584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 1); 91507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO|S_IWUSR, 91607584c762541672e35735b52af031183ca17a5a2Jim Cromie show_fan_div, store_fan_div, 2); 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 91907584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_pwm(struct device *dev, struct device_attribute *devattr, char *buf) 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 92107584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 92307584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long) data->pwm[nr]); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 92707584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_pwm(struct device *dev, struct device_attribute *devattr, 92807584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 93007584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 931787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 93207584c762541672e35735b52af031183ca17a5a2Jim Cromie u32 val = simple_strtoul(buf, NULL, 10); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9349a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data->type == w83627thf) { 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bits 0-3 are reserved in 627THF */ 93807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] = PWM_TO_REG(val) & 0xf0; 939787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr), 94107584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] | 942787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 94507584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr] = PWM_TO_REG(val); 946787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, nr), 94807584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[nr]); 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9519a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 95507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0); 95607584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1); 95707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 96007584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf) 9611550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 96207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 9631550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez struct w83627hf_data *data = w83627hf_update_device(dev); 9641550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) 9651550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return sprintf(buf, "%ld\n", 96607584c762541672e35735b52af031183ca17a5a2Jim Cromie pwm_freq_from_reg_627hf(data->pwm_freq[nr])); 9671550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez else 9681550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return sprintf(buf, "%ld\n", 96907584c762541672e35735b52af031183ca17a5a2Jim Cromie pwm_freq_from_reg(data->pwm_freq[nr])); 9701550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 9711550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9721550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic ssize_t 97307584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_pwm_freq(struct device *dev, struct device_attribute *devattr, 97407584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 9751550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez{ 97607584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 9771550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez struct w83627hf_data *data = dev_get_drvdata(dev); 9781550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez static const u8 mask[]={0xF8, 0x8F}; 9791550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u32 val; 9801550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9811550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez val = simple_strtoul(buf, NULL, 10); 9821550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9831550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez mutex_lock(&data->update_lock); 9841550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9851550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) { 98607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val); 9871550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez w83627hf_write_value(data, W83627HF_REG_PWM_FREQ, 98807584c762541672e35735b52af031183ca17a5a2Jim Cromie (data->pwm_freq[nr] << (nr*4)) | 9891550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez (w83627hf_read_value(data, 99007584c762541672e35735b52af031183ca17a5a2Jim Cromie W83627HF_REG_PWM_FREQ) & mask[nr])); 9911550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } else { 99207584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr] = pwm_freq_to_reg(val); 99307584c762541672e35735b52af031183ca17a5a2Jim Cromie w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr], 99407584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm_freq[nr]); 9951550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 9961550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 9971550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez mutex_unlock(&data->update_lock); 9981550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez return count; 9991550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez} 10001550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 100107584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO|S_IWUSR, 100207584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 0); 100307584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO|S_IWUSR, 100407584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 1); 100507584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO|S_IWUSR, 100607584c762541672e35735b52af031183ca17a5a2Jim Cromie show_pwm_freq, store_pwm_freq, 2); 10071550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 10081550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinezstatic ssize_t 100907584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_temp_type(struct device *dev, struct device_attribute *devattr, 101007584c762541672e35735b52af031183ca17a5a2Jim Cromie char *buf) 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 101207584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data = w83627hf_update_device(dev); 101407584c762541672e35735b52af031183ca17a5a2Jim Cromie return sprintf(buf, "%ld\n", (long) data->sens[nr]); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t 101807584c762541672e35735b52af031183ca17a5a2Jim Cromiestore_temp_type(struct device *dev, struct device_attribute *devattr, 101907584c762541672e35735b52af031183ca17a5a2Jim Cromie const char *buf, size_t count) 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 102107584c762541672e35735b52af031183ca17a5a2Jim Cromie int nr = to_sensor_dev_attr(devattr)->index; 1022787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 val, tmp; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = simple_strtoul(buf, NULL, 10); 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10279a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (val) { 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: /* PII/Celeron diode */ 1031787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 1032787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 103307584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG1[nr]); 1034787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); 1035787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG2, 103607584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG2[nr]); 103707584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: /* 3904 */ 1040787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 1041787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 104207584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp | BIT_SCFG1[nr]); 1043787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); 1044787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG2, 104507584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp & ~BIT_SCFG2[nr]); 104607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1048b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare case W83781D_DEFAULT_BETA: 1049b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare dev_warn(dev, "Sensor type %d is deprecated, please use 4 " 1050b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare "instead\n", W83781D_DEFAULT_BETA); 1051b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare /* fall through */ 1052b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare case 4: /* thermistor */ 1053787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 1054787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_SCFG1, 105507584c762541672e35735b52af031183ca17a5a2Jim Cromie tmp & ~BIT_SCFG1[nr]); 105607584c762541672e35735b52af031183ca17a5a2Jim Cromie data->sens[nr] = val; 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1059787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_err(dev, 1060b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare "Invalid sensor type %ld; must be 1, 2, or 4\n", 1061b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare (long) val); 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10659a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 106907584c762541672e35735b52af031183ca17a5a2Jim Cromie#define sysfs_temp_type(offset) \ 107007584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \ 107107584c762541672e35735b52af031183ca17a5a2Jim Cromie show_temp_type, store_temp_type, offset - 1); 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107307584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(1); 107407584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(2); 107507584c762541672e35735b52af031183ca17a5a2Jim Cromiesysfs_temp_type(3); 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107707584c762541672e35735b52af031183ca17a5a2Jim Cromiestatic ssize_t 107807584c762541672e35735b52af031183ca17a5a2Jim Cromieshow_name(struct device *dev, struct device_attribute *devattr, char *buf) 1079787c72b107888805981faf148c8fea96a752d22eJean Delvare{ 1080787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 1081787c72b107888805981faf148c8fea96a752d22eJean Delvare 1082787c72b107888805981faf148c8fea96a752d22eJean Delvare return sprintf(buf, "%s\n", data->name); 1083787c72b107888805981faf148c8fea96a752d22eJean Delvare} 1084787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 1085787c72b107888805981faf148c8fea96a752d22eJean Delvare 1086787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __init w83627hf_find(int sioaddr, unsigned short *addr, 1087787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data *sio_data) 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1089d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare int err = -ENODEV; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 val; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1092787c72b107888805981faf148c8fea96a752d22eJean Delvare static const __initdata char *names[] = { 1093787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83627HF", 1094787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83627THF", 1095787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83697HF", 1096787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83637HF", 1097787c72b107888805981faf148c8fea96a752d22eJean Delvare "W83687THF", 1098787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1099787c72b107888805981faf148c8fea96a752d22eJean Delvare 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds REG = sioaddr; 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VAL = sioaddr + 1; 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_enter(); 110467b671bceb4a8340a30929e9642620d99ed5ad76Jean Delvare val = force_id ? force_id : superio_inb(DEVID); 1105787c72b107888805981faf148c8fea96a752d22eJean Delvare switch (val) { 1106787c72b107888805981faf148c8fea96a752d22eJean Delvare case W627_DEVID: 1107787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83627hf; 1108787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1109787c72b107888805981faf148c8fea96a752d22eJean Delvare case W627THF_DEVID: 1110787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83627thf; 1111787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1112787c72b107888805981faf148c8fea96a752d22eJean Delvare case W697_DEVID: 1113787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83697hf; 1114787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1115787c72b107888805981faf148c8fea96a752d22eJean Delvare case W637_DEVID: 1116787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83637hf; 1117787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1118787c72b107888805981faf148c8fea96a752d22eJean Delvare case W687THF_DEVID: 1119787c72b107888805981faf148c8fea96a752d22eJean Delvare sio_data->type = w83687thf; 1120787c72b107888805981faf148c8fea96a752d22eJean Delvare break; 1121e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare case 0xff: /* No device at all */ 1122e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare goto exit; 1123787c72b107888805981faf148c8fea96a752d22eJean Delvare default: 1124e142e2a30787e9fa1bf0f66aa1d01727ce718cc7Jean Delvare pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val); 1125d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare goto exit; 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_select(W83627HF_LD_HWM); 1129d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare force_addr &= WINB_ALIGNMENT; 1130d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (force_addr) { 1131d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", 1132d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare force_addr); 1133d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_BASE_REG, force_addr >> 8); 1134d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); 1135d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = (superio_inb(WINB_BASE_REG) << 8) | 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_inb(WINB_BASE_REG + 1); 1138ada0c2f8fa087dc1dbc34e096c318739b1d6381aPetr Vandrovec *addr = val & WINB_ALIGNMENT; 1139d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (*addr == 0) { 1140d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Base address not set, " 1141d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare "skipping\n"); 1142d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare goto exit; 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1145d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare val = superio_inb(WINB_ACT_REG); 1146d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (!(val & 0x01)) { 1147d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); 1148d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare superio_outb(WINB_ACT_REG, val | 0x01); 1149d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } 1150d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 1151d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare err = 0; 1152787c72b107888805981faf148c8fea96a752d22eJean Delvare pr_info(DRVNAME ": Found %s chip at %#x\n", 1153787c72b107888805981faf148c8fea96a752d22eJean Delvare names[sio_data->type], *addr); 1154d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare 1155d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare exit: 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_exit(); 1157d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare return err; 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 116007584c762541672e35735b52af031183ca17a5a2Jim Cromie#define VIN_UNIT_ATTRS(_X_) \ 116107584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in##_X_##_input.dev_attr.attr, \ 116207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in##_X_##_min.dev_attr.attr, \ 1163e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in##_X_##_max.dev_attr.attr, \ 1164e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in##_X_##_alarm.dev_attr.attr, \ 1165e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in##_X_##_beep.dev_attr.attr 116607584c762541672e35735b52af031183ca17a5a2Jim Cromie 116707584c762541672e35735b52af031183ca17a5a2Jim Cromie#define FAN_UNIT_ATTRS(_X_) \ 116807584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan##_X_##_input.dev_attr.attr, \ 116907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan##_X_##_min.dev_attr.attr, \ 1170e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_fan##_X_##_div.dev_attr.attr, \ 1171e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_fan##_X_##_alarm.dev_attr.attr, \ 1172e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_fan##_X_##_beep.dev_attr.attr 117307584c762541672e35735b52af031183ca17a5a2Jim Cromie 117407584c762541672e35735b52af031183ca17a5a2Jim Cromie#define TEMP_UNIT_ATTRS(_X_) \ 117507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_input.dev_attr.attr, \ 117607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_max.dev_attr.attr, \ 117707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr, \ 1178e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_temp##_X_##_type.dev_attr.attr, \ 1179e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_temp##_X_##_alarm.dev_attr.attr, \ 1180e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_temp##_X_##_beep.dev_attr.attr 118107584c762541672e35735b52af031183ca17a5a2Jim Cromie 1182c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic struct attribute *w83627hf_attributes[] = { 1183c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_input.attr, 1184c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_min.attr, 1185c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_in0_max.attr, 1186e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in0_alarm.dev_attr.attr, 1187e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in0_beep.dev_attr.attr, 118807584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(2), 118907584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(3), 119007584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(4), 119107584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(7), 119207584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(8), 119307584c762541672e35735b52af031183ca17a5a2Jim Cromie 119407584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(1), 119507584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(2), 119607584c762541672e35735b52af031183ca17a5a2Jim Cromie 119707584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(1), 119807584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(2), 1199c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1200c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_alarms.attr, 12011c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare &sensor_dev_attr_beep_enable.dev_attr.attr, 1202c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman &dev_attr_beep_mask.attr, 1203c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 120407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1.dev_attr.attr, 120507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2.dev_attr.attr, 1206787c72b107888805981faf148c8fea96a752d22eJean Delvare &dev_attr_name.attr, 1207c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman NULL 1208c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1209c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1210c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic const struct attribute_group w83627hf_group = { 1211c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman .attrs = w83627hf_attributes, 1212c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1213c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1214c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic struct attribute *w83627hf_attributes_opt[] = { 121507584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(1), 121607584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(5), 121707584c762541672e35735b52af031183ca17a5a2Jim Cromie VIN_UNIT_ATTRS(6), 121807584c762541672e35735b52af031183ca17a5a2Jim Cromie 121907584c762541672e35735b52af031183ca17a5a2Jim Cromie FAN_UNIT_ATTRS(3), 122007584c762541672e35735b52af031183ca17a5a2Jim Cromie TEMP_UNIT_ATTRS(3), 122107584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3.dev_attr.attr, 122207584c762541672e35735b52af031183ca17a5a2Jim Cromie 122307584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr.attr, 122407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr.attr, 122507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1226c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman NULL 1227c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1228c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1229c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffmanstatic const struct attribute_group w83627hf_group_opt = { 1230c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman .attrs = w83627hf_attributes_opt, 1231c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman}; 1232c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1233787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83627hf_probe(struct platform_device *pdev) 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1235787c72b107888805981faf148c8fea96a752d22eJean Delvare struct device *dev = &pdev->dev; 1236787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data *sio_data = dev->platform_data; 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct w83627hf_data *data; 1238787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource *res; 12392ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie int err, i; 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1241787c72b107888805981faf148c8fea96a752d22eJean Delvare static const char *names[] = { 1242787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83627hf", 1243787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83627thf", 1244787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83697hf", 1245787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83637hf", 1246787c72b107888805981faf148c8fea96a752d22eJean Delvare "w83687thf", 1247787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1248787c72b107888805981faf148c8fea96a752d22eJean Delvare 1249787c72b107888805981faf148c8fea96a752d22eJean Delvare res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1250787c72b107888805981faf148c8fea96a752d22eJean Delvare if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { 1251787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", 1252787c72b107888805981faf148c8fea96a752d22eJean Delvare (unsigned long)res->start, 1253787c72b107888805981faf148c8fea96a752d22eJean Delvare (unsigned long)(res->start + WINB_REGION_SIZE - 1)); 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -EBUSY; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto ERROR0; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1258ba9c2e8d15da029ea3051c95e446b2d638ef02e2Deepak Saxena if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENOMEM; 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto ERROR1; 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1262787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr = res->start; 1263787c72b107888805981faf148c8fea96a752d22eJean Delvare data->type = sio_data->type; 1264787c72b107888805981faf148c8fea96a752d22eJean Delvare data->name = names[sio_data->type]; 12659a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->lock); 12669a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->update_lock); 1267787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_set_drvdata(pdev, data); 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize the chip */ 1270787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_init_device(pdev); 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* A few vars need to be filled upon startup */ 12732ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie for (i = 0; i <= 2; i++) 12742ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie data->fan_min[i] = w83627hf_read_value( 12752ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie data, W83627HF_REG_FAN_MIN(i)); 1276c09c5184a26158da32801e89d5849d774605f0ddJean Delvare w83627hf_update_fan_div(data); 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1278c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman /* Register common device attributes */ 1279787c72b107888805981faf148c8fea96a752d22eJean Delvare if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) 1280943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman goto ERROR3; 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1282c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman /* Register chip-specific device attributes */ 1283787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type == w83627hf || data->type == w83697hf) 128407584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 128507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_input.dev_attr)) 128607584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 128707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_min.dev_attr)) 128807584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 128907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in5_max.dev_attr)) 129007584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 1291e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in5_alarm.dev_attr)) 1292e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 1293e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in5_beep.dev_attr)) 1294e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 129507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_input.dev_attr)) 129607584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 129707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_min.dev_attr)) 129807584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 129907584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in6_max.dev_attr)) 130007584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 1301e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in6_alarm.dev_attr)) 1302e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 1303e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in6_beep.dev_attr)) 1304e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 130507584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr)) 130607584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 130707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr))) 1308c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1310787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type != w83697hf) 131107584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 131207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_input.dev_attr)) 131307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 131407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_min.dev_attr)) 131507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 131607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_in1_max.dev_attr)) 131707584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 1318e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in1_alarm.dev_attr)) 1319e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 1320e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_in1_beep.dev_attr)) 1321e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 132207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_input.dev_attr)) 132307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 132407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_min.dev_attr)) 132507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 132607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_fan3_div.dev_attr)) 132707584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 1328e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_fan3_alarm.dev_attr)) 1329e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 1330e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_fan3_beep.dev_attr)) 1331e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 133207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_input.dev_attr)) 133307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 133407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_max.dev_attr)) 133507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 133607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_max_hyst.dev_attr)) 133707584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 1338e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_temp3_alarm.dev_attr)) 1339e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 1340e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare &sensor_dev_attr_temp3_beep.dev_attr)) 1341e3604c626cdcddf37bf5c9663ae75b79dad40000Jean Delvare || (err = device_create_file(dev, 134207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_temp3_type.dev_attr))) 1343c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 1344c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman 1345787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type != w83697hf && data->vid != 0xff) { 13468a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare /* Convert VID to voltage based on VRM */ 13478a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare data->vrm = vid_which_vrm(); 13488a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare 1349787c72b107888805981faf148c8fea96a752d22eJean Delvare if ((err = device_create_file(dev, &dev_attr_cpu0_vid)) 1350787c72b107888805981faf148c8fea96a752d22eJean Delvare || (err = device_create_file(dev, &dev_attr_vrm))) 1351c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 13528a665a0552c414af88788cc0e2cf0e4626182c20Jean Delvare } 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1354787c72b107888805981faf148c8fea96a752d22eJean Delvare if (data->type == w83627thf || data->type == w83637hf 1355787c72b107888805981faf148c8fea96a752d22eJean Delvare || data->type == w83687thf) 135607584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 135707584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3.dev_attr))) 1358c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13601550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83637hf || data->type == w83687thf) 136107584c762541672e35735b52af031183ca17a5a2Jim Cromie if ((err = device_create_file(dev, 136207584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm1_freq.dev_attr)) 136307584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 136407584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm2_freq.dev_attr)) 136507584c762541672e35735b52af031183ca17a5a2Jim Cromie || (err = device_create_file(dev, 136607584c762541672e35735b52af031183ca17a5a2Jim Cromie &sensor_dev_attr_pwm3_freq.dev_attr))) 13671550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez goto ERROR4; 13681550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez 13691beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones data->hwmon_dev = hwmon_device_register(dev); 13701beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones if (IS_ERR(data->hwmon_dev)) { 13711beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones err = PTR_ERR(data->hwmon_dev); 1372c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman goto ERROR4; 1373c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman } 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1377c1685f61b0a3110b701d09b84a9f9a3d4e9ef2e2Mark M. Hoffman ERROR4: 1378787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&dev->kobj, &w83627hf_group); 1379787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); 1380943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman ERROR3: 138104a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(data); 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ERROR1: 1384787c72b107888805981faf148c8fea96a752d22eJean Delvare release_region(res->start, WINB_REGION_SIZE); 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ERROR0: 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1389787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devexit w83627hf_remove(struct platform_device *pdev) 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1391787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = platform_get_drvdata(pdev); 1392787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource *res; 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13941beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones hwmon_device_unregister(data->hwmon_dev); 1395943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman 1396787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); 1397787c72b107888805981faf148c8fea96a752d22eJean Delvare sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); 139804a6217df28e3004ba4e76eb0a356a30f72c564fJean Delvare platform_set_drvdata(pdev, NULL); 1399943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman kfree(data); 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1401787c72b107888805981faf148c8fea96a752d22eJean Delvare res = platform_get_resource(pdev, IORESOURCE_IO, 0); 1402787c72b107888805981faf148c8fea96a752d22eJean Delvare release_region(res->start, WINB_REGION_SIZE); 1403787c72b107888805981faf148c8fea96a752d22eJean Delvare 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1408d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare/* Registers 0x50-0x5f are banked */ 1409d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvarestatic inline void w83627hf_set_bank(struct w83627hf_data *data, u16 reg) 1410d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare{ 1411d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare if ((reg & 0x00f0) == 0x50) { 1412d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); 1413d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(reg >> 8, data->addr + W83781D_DATA_REG_OFFSET); 1414d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare } 1415d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare} 1416d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare 1417d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare/* Not strictly necessary, but play it safe for now */ 1418d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvarestatic inline void w83627hf_reset_bank(struct w83627hf_data *data, u16 reg) 1419d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare{ 1420d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare if (reg & 0xff00) { 1421d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(W83781D_REG_BANK, data->addr + W83781D_ADDR_REG_OFFSET); 1422d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); 1423d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare } 1424d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare} 1425d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare 1426787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_read_value(struct w83627hf_data *data, u16 reg) 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res, word_sized; 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14309a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->lock); 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_sized = (((reg & 0xff00) == 0x100) 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0xff00) == 0x200)) 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (((reg & 0x00ff) == 0x50) 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x53) 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x55)); 1436d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_set_bank(data, reg); 1437787c72b107888805981faf148c8fea96a752d22eJean Delvare outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); 1438787c72b107888805981faf148c8fea96a752d22eJean Delvare res = inb_p(data->addr + W83781D_DATA_REG_OFFSET); 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (word_sized) { 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p((reg & 0xff) + 1, 1441787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_ADDR_REG_OFFSET); 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = 1443787c72b107888805981faf148c8fea96a752d22eJean Delvare (res << 8) + inb_p(data->addr + 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_DATA_REG_OFFSET); 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1446d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_reset_bank(data, reg); 14479a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->lock); 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83627thf_read_gpio5(struct platform_device *pdev) 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res = 0xff, sel; 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_enter(); 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_select(W83627HF_LD_GPIO5); 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure these GPIO pins are enabled */ 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) { 1460787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n"); 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Make sure the pins are configured for input 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds There must be at least five (VRM 9), and possibly 6 (VRM 10) */ 1466dd149c52223cfb05cdefb0755d3c2793e8d33edeYuan Mu sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((sel & 0x1f) != 0x1f) { 1468787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "GPIO5 not configured for VID " 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "function\n"); 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto exit; 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1473787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_info(&pdev->dev, "Reading VID from GPIO5\n"); 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = superio_inb(W83627THF_GPIO5_DR) & sel; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsexit: 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds superio_exit(); 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __devinit w83687thf_read_vid(struct platform_device *pdev) 1482c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare{ 1483c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare int res = 0xff; 1484c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1485c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_enter(); 1486c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_select(W83627HF_LD_HWM); 1487c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1488c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare /* Make sure these GPIO pins are enabled */ 1489c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { 1490787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "VID disabled, no VID function\n"); 1491c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare goto exit; 1492c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare } 1493c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1494c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare /* Make sure the pins are configured for input */ 1495c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { 1496787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_dbg(&pdev->dev, "VID configured as output, " 1497c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare "no VID function\n"); 1498c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare goto exit; 1499c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare } 1500c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1501c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare res = superio_inb(W83687THF_VID_DATA) & 0x3f; 1502c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1503c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvareexit: 1504c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare superio_exit(); 1505c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare return res; 1506c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare} 1507c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare 1508787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int word_sized; 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15129a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->lock); 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds word_sized = (((reg & 0xff00) == 0x100) 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0xff00) == 0x200)) 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && (((reg & 0x00ff) == 0x53) 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || ((reg & 0x00ff) == 0x55)); 1517d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_set_bank(data, reg); 1518787c72b107888805981faf148c8fea96a752d22eJean Delvare outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (word_sized) { 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(value >> 8, 1521787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_DATA_REG_OFFSET); 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p((reg & 0xff) + 1, 1523787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_ADDR_REG_OFFSET); 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds outb_p(value & 0xff, 1526787c72b107888805981faf148c8fea96a752d22eJean Delvare data->addr + W83781D_DATA_REG_OFFSET); 1527d58df9cd788e6fb4962e1c8d5ba7b8b95d639a44Jean Delvare w83627hf_reset_bank(data, reg); 15289a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->lock); 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1532787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic void __devinit w83627hf_init_device(struct platform_device *pdev) 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1534787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = platform_get_drvdata(pdev); 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1536d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare enum chips type = data->type; 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 tmp; 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15392251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare if (reset) { 15402251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare /* Resetting the chip has been the default for a long time, 15412251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare but repeatedly caused problems (fans going to full 15422251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare speed...) so it is now optional. It might even go away if 15432251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare nobody reports it as being useful, as I see very little 15442251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare reason why this would be needed at all. */ 1545787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_info(&pdev->dev, "If reset=1 solved a problem you were " 15462251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare "having, please report!\n"); 15472251cf1a4b37bd483501614c2d78f5b8286f20d7Jean Delvare 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* save this register */ 1549787c72b107888805981faf148c8fea96a752d22eJean Delvare i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset all except Watchdog values and last conversion values 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This sets fan-divs to 2, among others */ 1552787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Restore the register and disable power-on abnormal beep. 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This saves FAN 1/2/3 input/output values set by BIOS. */ 1555787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable master beep-enable (reset turns it on). 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Individual beeps should be reset to off but for some reason 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds disabling this bit helps some people not get beeped */ 1559787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Minimize conflicts with other winbond i2c-only clients... */ 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* disable i2c subclients... how to disable main i2c client?? */ 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* force i2c address to relatively uncommon address */ 1565787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); 1566787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Read VID only once */ 1569d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (type == w83627hf || type == w83637hf) { 1570787c72b107888805981faf148c8fea96a752d22eJean Delvare int lo = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); 1571787c72b107888805981faf148c8fea96a752d22eJean Delvare int hi = w83627hf_read_value(data, W83781D_REG_CHIPID); 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); 1573d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } else if (type == w83627thf) { 1574787c72b107888805981faf148c8fea96a752d22eJean Delvare data->vid = w83627thf_read_gpio5(pdev); 1575d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare } else if (type == w83687thf) { 1576787c72b107888805981faf148c8fea96a752d22eJean Delvare data->vid = w83687thf_read_vid(pdev); 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Read VRM & OVT Config only once */ 1580d27c37c0be3fd97a696dafb28507277d49875dcbJean Delvare if (type == w83627thf || type == w83637hf || type == w83687thf) { 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->vrm_ovt = 1582787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83627THF_REG_VRM_OVT_CFG); 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1585787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 1; i <= 3; i++) { 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(tmp & BIT_SCFG1[i - 1])) { 1588b26f93309282bdfebb3edb8939e022a4bbe56dfeJean Delvare data->sens[i - 1] = 4; 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (w83627hf_read_value 1591787c72b107888805981faf148c8fea96a752d22eJean Delvare (data, 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->sens[i - 1] = 1; 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->sens[i - 1] = 2; 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((type == w83697hf) && (i == 2)) 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(init) { 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Enable temp2 */ 1603df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG); 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp & 0x01) { 1605787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_warn(&pdev->dev, "Enabling temp2, readings " 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "might not make sense\n"); 1607df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG, 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp & 0xfe); 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Enable temp3 */ 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type != w83697hf) { 1613787c72b107888805981faf148c8fea96a752d22eJean Delvare tmp = w83627hf_read_value(data, 1614df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie W83627HF_REG_TEMP3_CONFIG); 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp & 0x01) { 1616787c72b107888805981faf148c8fea96a752d22eJean Delvare dev_warn(&pdev->dev, "Enabling temp3, " 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "readings might not make sense\n"); 1618787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, 1619df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe); 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Start monitoring */ 1625787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_write_value(data, W83781D_REG_CONFIG, 1626787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_CONFIG) & 0xf7) 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds | 0x01); 1629ef878b11ba245d14b7db7816217a825d6a894182Jean Delvare 1630ef878b11ba245d14b7db7816217a825d6a894182Jean Delvare /* Enable VBAT monitoring if needed */ 1631ef878b11ba245d14b7db7816217a825d6a894182Jean Delvare tmp = w83627hf_read_value(data, W83781D_REG_VBAT); 1632ef878b11ba245d14b7db7816217a825d6a894182Jean Delvare if (!(tmp & 0x01)) 1633ef878b11ba245d14b7db7816217a825d6a894182Jean Delvare w83627hf_write_value(data, W83781D_REG_VBAT, tmp | 0x01); 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1636c09c5184a26158da32801e89d5849d774605f0ddJean Delvarestatic void w83627hf_update_fan_div(struct w83627hf_data *data) 1637c09c5184a26158da32801e89d5849d774605f0ddJean Delvare{ 1638c09c5184a26158da32801e89d5849d774605f0ddJean Delvare int reg; 1639c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 1640c09c5184a26158da32801e89d5849d774605f0ddJean Delvare reg = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); 1641c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[0] = (reg >> 4) & 0x03; 1642c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[1] = (reg >> 6) & 0x03; 1643c09c5184a26158da32801e89d5849d774605f0ddJean Delvare if (data->type != w83697hf) { 1644c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[2] = (w83627hf_read_value(data, 1645c09c5184a26158da32801e89d5849d774605f0ddJean Delvare W83781D_REG_PIN) >> 6) & 0x03; 1646c09c5184a26158da32801e89d5849d774605f0ddJean Delvare } 1647c09c5184a26158da32801e89d5849d774605f0ddJean Delvare reg = w83627hf_read_value(data, W83781D_REG_VBAT); 1648c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[0] |= (reg >> 3) & 0x04; 1649c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[1] |= (reg >> 4) & 0x04; 1650c09c5184a26158da32801e89d5849d774605f0ddJean Delvare if (data->type != w83697hf) 1651c09c5184a26158da32801e89d5849d774605f0ddJean Delvare data->fan_div[2] |= (reg >> 5) & 0x04; 1652c09c5184a26158da32801e89d5849d774605f0ddJean Delvare} 1653c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct w83627hf_data *w83627hf_update_device(struct device *dev) 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1656787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_data *data = dev_get_drvdata(dev); 1657df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie int i, num_temps = (data->type == w83697hf) ? 2 : 3; 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16599a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || !data->valid) { 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i <= 8; i++) { 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* skip missing sensors */ 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((data->type == w83697hf) && (i == 1)) || 1666c2db6ce14a743ac5f8973124272cf425c4f86b90Jean Delvare ((data->type != w83627hf && data->type != w83697hf) 16674a1c4447e523003019a2bf9b972ed6fe411e84d2Yuan Mu && (i == 5 || i == 6))) 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in[i] = 1670787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_IN(i)); 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_min[i] = 1672787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_IN_MIN(i)); 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_max[i] = 1675787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W83781D_REG_IN_MAX(i)); 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16782ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie for (i = 0; i <= 2; i++) { 16792ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie data->fan[i] = 16802ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie w83627hf_read_value(data, W83627HF_REG_FAN(i)); 16812ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie data->fan_min[i] = 1682787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, 16832ca2fcd124c00a5e733fb0206ef106fade9a76a4Jim Cromie W83627HF_REG_FAN_MIN(i)); 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 168507584c762541672e35735b52af031183ca17a5a2Jim Cromie for (i = 0; i <= 2; i++) { 1686787c72b107888805981faf148c8fea96a752d22eJean Delvare u8 tmp = w83627hf_read_value(data, 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds W836X7HF_REG_PWM(data->type, i)); 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* bits 0-3 are reserved in 627THF */ 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data->type == w83627thf) 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp &= 0xf0; 169107584c762541672e35735b52af031183ca17a5a2Jim Cromie data->pwm[i] = tmp; 169207584c762541672e35735b52af031183ca17a5a2Jim Cromie if (i == 1 && 169307584c762541672e35735b52af031183ca17a5a2Jim Cromie (data->type == w83627hf || data->type == w83697hf)) 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16961550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (data->type == w83627hf) { 16971550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez u8 tmp = w83627hf_read_value(data, 16981550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83627HF_REG_PWM_FREQ); 16991550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[0] = tmp & 0x07; 17001550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[1] = (tmp >> 4) & 0x07; 17011550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } else if (data->type != w83627thf) { 17021550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez for (i = 1; i <= 3; i++) { 17031550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez data->pwm_freq[i - 1] = 17041550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez w83627hf_read_value(data, 17051550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez W83637HF_REG_PWM_FREQ[i - 1]); 17061550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez if (i == 2 && (data->type == w83697hf)) 17071550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez break; 17081550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 17091550cb6d7e78c7cfdd7b48bee6809795d43d6a33Carlos Olalla Martinez } 1710df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie for (i = 0; i < num_temps; i++) { 1711df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp[i] = w83627hf_read_value( 1712df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp[i]); 1713df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max[i] = w83627hf_read_value( 1714df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp_over[i]); 1715df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data->temp_max_hyst[i] = w83627hf_read_value( 1716df48ed804f44a040e990976b537efc1e133c74d8Jim Cromie data, w83627hf_reg_temp_hyst[i]); 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1719c09c5184a26158da32801e89d5849d774605f0ddJean Delvare w83627hf_update_fan_div(data); 1720c09c5184a26158da32801e89d5849d774605f0ddJean Delvare 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->alarms = 1722787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_ALARM1) | 1723787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) | 1724787c72b107888805981faf148c8fea96a752d22eJean Delvare (w83627hf_read_value(data, W83781D_REG_ALARM3) << 16); 1725787c72b107888805981faf148c8fea96a752d22eJean Delvare i = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2); 17261c1381076f8c6cf0a2c9918194e3fa6369cdf06aJean Delvare data->beep_mask = (i << 8) | 1727787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) | 1728787c72b107888805981faf148c8fea96a752d22eJean Delvare w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16; 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->last_updated = jiffies; 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->valid = 1; 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17339a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return data; 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1738787c72b107888805981faf148c8fea96a752d22eJean Delvarestatic int __init w83627hf_device_add(unsigned short address, 1739787c72b107888805981faf148c8fea96a752d22eJean Delvare const struct w83627hf_sio_data *sio_data) 1740787c72b107888805981faf148c8fea96a752d22eJean Delvare{ 1741787c72b107888805981faf148c8fea96a752d22eJean Delvare struct resource res = { 1742787c72b107888805981faf148c8fea96a752d22eJean Delvare .start = address + WINB_REGION_OFFSET, 1743787c72b107888805981faf148c8fea96a752d22eJean Delvare .end = address + WINB_REGION_OFFSET + WINB_REGION_SIZE - 1, 1744787c72b107888805981faf148c8fea96a752d22eJean Delvare .name = DRVNAME, 1745787c72b107888805981faf148c8fea96a752d22eJean Delvare .flags = IORESOURCE_IO, 1746787c72b107888805981faf148c8fea96a752d22eJean Delvare }; 1747787c72b107888805981faf148c8fea96a752d22eJean Delvare int err; 1748787c72b107888805981faf148c8fea96a752d22eJean Delvare 1749787c72b107888805981faf148c8fea96a752d22eJean Delvare pdev = platform_device_alloc(DRVNAME, address); 1750787c72b107888805981faf148c8fea96a752d22eJean Delvare if (!pdev) { 1751787c72b107888805981faf148c8fea96a752d22eJean Delvare err = -ENOMEM; 1752787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device allocation failed\n"); 1753787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit; 1754787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1755787c72b107888805981faf148c8fea96a752d22eJean Delvare 1756787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_device_add_resources(pdev, &res, 1); 1757787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) { 1758787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device resource addition failed " 1759787c72b107888805981faf148c8fea96a752d22eJean Delvare "(%d)\n", err); 1760787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1761787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1762787c72b107888805981faf148c8fea96a752d22eJean Delvare 17632df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare err = platform_device_add_data(pdev, sio_data, 17642df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare sizeof(struct w83627hf_sio_data)); 17652df6d811574f46bea0d38bf91aa54df4c05488cdJean Delvare if (err) { 1766787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); 1767787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1768787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1769787c72b107888805981faf148c8fea96a752d22eJean Delvare 1770787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_device_add(pdev); 1771787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) { 1772787c72b107888805981faf148c8fea96a752d22eJean Delvare printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", 1773787c72b107888805981faf148c8fea96a752d22eJean Delvare err); 1774787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_device_put; 1775787c72b107888805981faf148c8fea96a752d22eJean Delvare } 1776787c72b107888805981faf148c8fea96a752d22eJean Delvare 1777787c72b107888805981faf148c8fea96a752d22eJean Delvare return 0; 1778787c72b107888805981faf148c8fea96a752d22eJean Delvare 1779787c72b107888805981faf148c8fea96a752d22eJean Delvareexit_device_put: 1780787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_device_put(pdev); 1781787c72b107888805981faf148c8fea96a752d22eJean Delvareexit: 1782787c72b107888805981faf148c8fea96a752d22eJean Delvare return err; 1783787c72b107888805981faf148c8fea96a752d22eJean Delvare} 1784787c72b107888805981faf148c8fea96a752d22eJean Delvare 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init sensors_w83627hf_init(void) 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1787787c72b107888805981faf148c8fea96a752d22eJean Delvare int err; 1788787c72b107888805981faf148c8fea96a752d22eJean Delvare unsigned short address; 1789787c72b107888805981faf148c8fea96a752d22eJean Delvare struct w83627hf_sio_data sio_data; 1790787c72b107888805981faf148c8fea96a752d22eJean Delvare 1791787c72b107888805981faf148c8fea96a752d22eJean Delvare if (w83627hf_find(0x2e, &address, &sio_data) 1792787c72b107888805981faf148c8fea96a752d22eJean Delvare && w83627hf_find(0x4e, &address, &sio_data)) 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1795787c72b107888805981faf148c8fea96a752d22eJean Delvare err = platform_driver_register(&w83627hf_driver); 1796787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) 1797787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit; 1798787c72b107888805981faf148c8fea96a752d22eJean Delvare 1799787c72b107888805981faf148c8fea96a752d22eJean Delvare /* Sets global pdev as a side effect */ 1800787c72b107888805981faf148c8fea96a752d22eJean Delvare err = w83627hf_device_add(address, &sio_data); 1801787c72b107888805981faf148c8fea96a752d22eJean Delvare if (err) 1802787c72b107888805981faf148c8fea96a752d22eJean Delvare goto exit_driver; 1803787c72b107888805981faf148c8fea96a752d22eJean Delvare 1804787c72b107888805981faf148c8fea96a752d22eJean Delvare return 0; 1805787c72b107888805981faf148c8fea96a752d22eJean Delvare 1806787c72b107888805981faf148c8fea96a752d22eJean Delvareexit_driver: 1807787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_driver_unregister(&w83627hf_driver); 1808787c72b107888805981faf148c8fea96a752d22eJean Delvareexit: 1809787c72b107888805981faf148c8fea96a752d22eJean Delvare return err; 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit sensors_w83627hf_exit(void) 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1814787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_device_unregister(pdev); 1815787c72b107888805981faf148c8fea96a752d22eJean Delvare platform_driver_unregister(&w83627hf_driver); 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, " 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Philip Edelbrock <phil@netroedge.com>, " 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "and Mark Studebaker <mdsxyz123@yahoo.com>"); 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("W83627HF driver"); 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sensors_w83627hf_init); 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(sensors_w83627hf_exit); 1826