1e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* 22804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * lm93.c - Part of lm_sensors, Linux kernel modules for hardware monitoring 32804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 42804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Author/Maintainer: Mark M. Hoffman <mhoffman@lightlink.com> 52804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2004 Utilitek Systems, Inc. 62804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 72804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * derived in part from lm78.c: 82804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 92804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * derived in part from lm85.c: 112804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> 122804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> 132804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 142804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * derived in part from w83l785ts.c: 152804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2003-2004 Jean Delvare <khali@linux-fr.org> 162804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 172804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Ported to Linux 2.6 by Eric J. Bowersox <ericb@aspsys.com> 182804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2005 Aspen Systems, Inc. 192804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 202804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Adapted to 2.6.20 by Carsten Emde <cbe@osadl.org> 212804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2006 Carsten Emde, Open Source Automation Development Lab 222804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Modified for mainline integration by Hans J. Koch <hjk@hansjkoch.de> 242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Copyright (c) 2007 Hans J. Koch, Linutronix GmbH 252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 262804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * This program is free software; you can redistribute it and/or modify 272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * it under the terms of the GNU General Public License as published by 282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 292804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * (at your option) any later version. 302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * This program is distributed in the hope that it will be useful, 322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * GNU General Public License for more details. 352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * You should have received a copy of the GNU General Public License 372804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * along with this program; if not, write to the Free Software 382804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 392804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 40e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 41e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/module.h> 42e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/init.h> 43e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/slab.h> 44e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/i2c.h> 45e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/hwmon.h> 46e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/hwmon-sysfs.h> 47e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/hwmon-vid.h> 48e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/err.h> 49e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#include <linux/delay.h> 50e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 51e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* LM93 REGISTER ADDRESSES */ 52e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 53e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* miscellaneous */ 54e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_MFR_ID 0x3e 55e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_VER 0x3f 56e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_STATUS_CONTROL 0xe2 57e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_CONFIG 0xe3 58e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_SLEEP_CONTROL 0xe4 59e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 60e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* alarm values start here */ 61e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_HOST_ERROR_1 0x48 62e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 63e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* voltage inputs: in1-in16 (nr => 0-15) */ 64e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_IN(nr) (0x56 + (nr)) 65e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_IN_MIN(nr) (0x90 + (nr) * 2) 66e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_IN_MAX(nr) (0x91 + (nr) * 2) 67e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 68e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temperature inputs: temp1-temp4 (nr => 0-3) */ 69e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_TEMP(nr) (0x50 + (nr)) 70e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_TEMP_MIN(nr) (0x78 + (nr) * 2) 71e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_TEMP_MAX(nr) (0x79 + (nr) * 2) 72e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 73e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temp[1-4]_auto_boost (nr => 0-3) */ 74e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_BOOST(nr) (0x80 + (nr)) 75e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 76e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* #PROCHOT inputs: prochot1-prochot2 (nr => 0-1) */ 77e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PROCHOT_CUR(nr) (0x67 + (nr) * 2) 78e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PROCHOT_AVG(nr) (0x68 + (nr) * 2) 79e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PROCHOT_MAX(nr) (0xb0 + (nr)) 80e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 81e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* fan tach inputs: fan1-fan4 (nr => 0-3) */ 82e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_FAN(nr) (0x6e + (nr) * 2) 83e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_FAN_MIN(nr) (0xb4 + (nr) * 2) 84e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 85e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* pwm outputs: pwm1-pwm2 (nr => 0-1, reg => 0-3) */ 862804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_REG_PWM_CTL(nr, reg) (0xc8 + (reg) + (nr) * 4) 87e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_PWM_CTL1 0x0 88e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_PWM_CTL2 0x1 89e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_PWM_CTL3 0x2 90e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_PWM_CTL4 0x3 91e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 92e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* GPIO input state */ 93e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_GPI 0x6b 94e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 95e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* vid inputs: vid1-vid2 (nr => 0-1) */ 96e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_VID(nr) (0x6c + (nr)) 97e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 98e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* vccp1 & vccp2: VID relative inputs (nr => 0-1) */ 99e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_VCCP_LIMIT_OFF(nr) (0xb2 + (nr)) 100e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 101e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temp[1-4]_auto_boost_hyst */ 102e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_BOOST_HYST_12 0xc0 103e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_BOOST_HYST_34 0xc1 104e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_BOOST_HYST(nr) (0xc0 + (nr)/2) 105e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 106e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temp[1-4]_auto_pwm_[min|hyst] */ 107e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PWM_MIN_HYST_12 0xc3 108e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PWM_MIN_HYST_34 0xc4 109e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PWM_MIN_HYST(nr) (0xc3 + (nr)/2) 110e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 111e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* prochot_override & prochot_interval */ 112e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PROCHOT_OVERRIDE 0xc6 113e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PROCHOT_INTERVAL 0xc7 114e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 115e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temp[1-4]_auto_base (nr => 0-3) */ 116e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_TEMP_BASE(nr) (0xd0 + (nr)) 117e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 118e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* temp[1-4]_auto_offsets (step => 0-11) */ 119e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_TEMP_OFFSET(step) (0xd4 + (step)) 120e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 121e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* #PROCHOT & #VRDHOT PWM ramp control */ 122e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_PWM_RAMP_CTL 0xbf 123e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 124e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* miscellaneous */ 125e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_SFC1 0xbc 126e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_SFC2 0xbd 127e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_GPI_VID_CTL 0xbe 128e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_SF_TACH_TO_PWM 0xe0 129e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 130e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* error masks */ 131e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_GPI_ERR_MASK 0xec 132e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_REG_MISC_ERR_MASK 0xed 133e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 134e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* LM93 REGISTER VALUES */ 135e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_MFR_ID 0x73 136e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_MFR_ID_PROTOTYPE 0x72 137e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 138c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck/* LM94 REGISTER VALUES */ 139c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck#define LM94_MFR_ID_2 0x7a 140c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck#define LM94_MFR_ID 0x79 141c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck#define LM94_MFR_ID_PROTOTYPE 0x78 142c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck 143e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* SMBus capabilities */ 144e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_SMBUS_FUNC_FULL (I2C_FUNC_SMBUS_BYTE_DATA | \ 145e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA) 146e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_SMBUS_FUNC_MIN (I2C_FUNC_SMBUS_BYTE_DATA | \ 147e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch I2C_FUNC_SMBUS_WORD_DATA) 148e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 149e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* Addresses to scan */ 15025e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; 151e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 152e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* Insmod parameters */ 153e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 15490ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool disable_block; 155e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochmodule_param(disable_block, bool, 0); 156e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_PARM_DESC(disable_block, 157e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "Set to non-zero to disable SMBus block data transactions."); 158e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 15990ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool init; 160e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochmodule_param(init, bool, 0); 161e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_PARM_DESC(init, "Set to non-zero to force chip initialization."); 162e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1632804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeckstatic int vccp_limit_type[2] = {0, 0}; 164e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochmodule_param_array(vccp_limit_type, int, NULL, 0); 165e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_PARM_DESC(vccp_limit_type, "Configures in7 and in8 limit modes."); 166e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 167e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int vid_agtl; 168e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochmodule_param(vid_agtl, int, 0); 169e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_PARM_DESC(vid_agtl, "Configures VID pin input thresholds."); 170e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 171e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* Driver data */ 172e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic struct i2c_driver lm93_driver; 173e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 174e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* LM93 BLOCK READ COMMANDS */ 175e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const struct { u8 cmd; u8 len; } lm93_block_read_cmds[12] = { 176e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf2, 8 }, 177e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf3, 8 }, 178e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf4, 6 }, 179e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf5, 16 }, 180e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf6, 4 }, 181e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf7, 8 }, 182e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf8, 12 }, 183e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xf9, 32 }, 184e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xfa, 8 }, 185e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xfb, 8 }, 186e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xfc, 16 }, 187e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 0xfd, 9 }, 188e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 189e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1902804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 1912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * ALARMS: SYSCTL format described further below 1922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 64 bits in 8 registers, as immediately below 1932804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 194e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstruct block1_t { 195e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 host_status_1; 196e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 host_status_2; 197e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 host_status_3; 198e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 host_status_4; 199e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 p1_prochot_status; 200e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 p2_prochot_status; 201e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 gpi_status; 202e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 fan_status; 203e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 204e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 205e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* 206e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch * Client-specific data 207e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch */ 208e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstruct lm93_data { 2091beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones struct device *hwmon_dev; 210e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 211e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct mutex update_lock; 212e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch unsigned long last_updated; /* In jiffies */ 213e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 214e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* client update function */ 215e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch void (*update)(struct lm93_data *, struct i2c_client *); 216e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 217e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char valid; /* !=0 if following fields are valid */ 218e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 219e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* register values, arranged by block read groups */ 220e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct block1_t block1; 221e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2222804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck /* 2232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * temp1 - temp4: unfiltered readings 2242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * temp1 - temp2: filtered readings 2252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 226e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 block2[6]; 227e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 228e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* vin1 - vin16: readings */ 229e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 block3[16]; 230e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 231e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* prochot1 - prochot2: readings */ 232e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct { 233e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 cur; 234e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 avg; 235e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } block4[2]; 236e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 237e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* fan counts 1-4 => 14-bits, LE, *left* justified */ 238e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u16 block5[4]; 239e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 240e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* block6 has a lot of data we don't need */ 241e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct { 242e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 min; 243e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 max; 244f08a34874f93d5081c735ffcb2f9071be9b5d270Hans-Jürgen Koch } temp_lim[4]; 245e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 246e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* vin1 - vin16: low and high limits */ 247e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct { 248e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 min; 249e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 max; 250e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } block7[16]; 251e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 252e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* fan count limits 1-4 => same format as block5 */ 253e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u16 block8[4]; 254e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 255e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* pwm control registers (2 pwms, 4 regs) */ 256e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 block9[2][4]; 257e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 258e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* auto/pwm base temp and offset temp registers */ 259e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct { 260e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 base[4]; 261e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 offset[12]; 262e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } block10; 263e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 264e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* master config register */ 265e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 config; 266e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 267e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* VID1 & VID2 => register format, 6-bits, right justified */ 268e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 vid[2]; 269e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 270e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* prochot1 - prochot2: limits */ 271e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 prochot_max[2]; 272e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 273e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* vccp1 & vccp2 (in7 & in8): VID relative limits (register format) */ 274e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 vccp_limits[2]; 275e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 276e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* GPIO input state (register format, i.e. inverted) */ 277e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 gpi; 278e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 279e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT override (register format) */ 280e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 prochot_override; 281e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 282e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT intervals (register format) */ 283e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 prochot_interval; 284e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 285e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Fan Boost Temperatures (register format) */ 286e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 boost[4]; 287e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 288e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Fan Boost Hysteresis (register format) */ 289e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 boost_hyst[2]; 290e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 291e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Temperature Zone Min. PWM & Hysteresis (register format) */ 292e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 auto_pwm_min_hyst[2]; 293e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 294e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT & #VRDHOT PWM Ramp Control */ 295e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 pwm_ramp_ctl; 296e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 297e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* miscellaneous setup regs */ 298e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 sfc1; 299e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 sfc2; 300e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 sf_tach_to_pwm; 301e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 3022804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck /* 3032804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * The two PWM CTL2 registers can read something other than what was 3042804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * last written for the OVR_DC field (duty cycle override). So, we 3052804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * save the user-commanded value here. 3062804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 307e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 pwm_override[2]; 308e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 309e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 3102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 3112804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * VID: mV 3122804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 6-bits, right justified, *always* using Intel VRM/VRD 10 3132804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 314e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_VID_FROM_REG(u8 reg) 315e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 316e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return vid_from_reg((reg & 0x3f), 100); 317e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 318e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 319e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* min, max, and nominal register values, per channel (u8) */ 320e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const u8 lm93_vin_reg_min[16] = { 321e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 322e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 323e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 324e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const u8 lm93_vin_reg_max[16] = { 325e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 326e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd1, 327e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 3282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 3292804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Values from the datasheet. They're here for documentation only. 3302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * static const u8 lm93_vin_reg_nom[16] = { 3312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 3322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0xc0, 3332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * }; 3342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 335e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 336e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* min, max, and nominal voltage readings, per channel (mV)*/ 337e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const unsigned long lm93_vin_val_min[16] = { 338e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0, 0, 0, 0, 0, 0, 0, 0, 339e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0, 0, 0, 0, 0, 0, 0, 3000, 340e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 341e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 342e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const unsigned long lm93_vin_val_max[16] = { 343e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1236, 1236, 1236, 1600, 2000, 2000, 1600, 1600, 344e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4400, 6500, 3333, 2625, 1312, 1312, 1236, 3600, 345e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 3462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 3472804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Values from the datasheet. They're here for documentation only. 3482804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * static const unsigned long lm93_vin_val_nom[16] = { 3492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 927, 927, 927, 1200, 1500, 1500, 1200, 1200, 3502804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 3300, 5000, 2500, 1969, 984, 984, 309, 3300, 3512804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * }; 3522804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 353e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 354e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic unsigned LM93_IN_FROM_REG(int nr, u8 reg) 355e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 356e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_max = lm93_vin_val_max[nr] * 1000; 357e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_min = lm93_vin_val_min[nr] * 1000; 358e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 359e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long slope = (uV_max - uV_min) / 360e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); 361e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; 362e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 363e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (slope * reg + intercept + 500) / 1000; 364e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 365e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 3662804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 3672804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * IN: mV, limits determined by channel nr 3682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: scaling determined by channel nr 3692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 370e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_IN_TO_REG(int nr, unsigned val) 371e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 372e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* range limit */ 373e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long mV = SENSORS_LIMIT(val, 374e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_vin_val_min[nr], lm93_vin_val_max[nr]); 375e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 376e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* try not to lose too much precision here */ 377e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV = mV * 1000; 378e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_max = lm93_vin_val_max[nr] * 1000; 379e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_min = lm93_vin_val_min[nr] * 1000; 380e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 381e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* convert */ 382e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long slope = (uV_max - uV_min) / 383e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (lm93_vin_reg_max[nr] - lm93_vin_reg_min[nr]); 384e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long intercept = uV_min - slope * lm93_vin_reg_min[nr]; 385e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 386e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 result = ((uV - intercept + (slope/2)) / slope); 387e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result = SENSORS_LIMIT(result, 388e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_vin_reg_min[nr], lm93_vin_reg_max[nr]); 389e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return result; 390e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 391e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 392e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* vid in mV, upper == 0 indicates low limit, otherwise upper limit */ 393e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) 394e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 395e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_offset = upper ? (((reg >> 4 & 0x0f) + 1) * 12500) : 396e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (((reg >> 0 & 0x0f) + 1) * -25000); 397e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const long uV_vid = vid * 1000; 398e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (uV_vid + uV_offset + 5000) / 10000; 399e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 400e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4012804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_IN_MIN_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 0, (vid)) 4022804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_IN_MAX_FROM_REG(reg, vid) LM93_IN_REL_FROM_REG((reg), 1, (vid)) 403e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4042804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4052804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * vid in mV , upper == 0 indicates low limit, otherwise upper limit 4062804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * upper also determines which nibble of the register is returned 4072804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * (the other nibble will be 0x0) 4082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 409e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) 410e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 411e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long uV_offset = vid * 1000 - val * 10000; 412e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (upper) { 413e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch uV_offset = SENSORS_LIMIT(uV_offset, 12500, 200000); 414e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)((uV_offset / 12500 - 1) << 4); 415e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 416e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch uV_offset = SENSORS_LIMIT(uV_offset, -400000, -25000); 417e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)((uV_offset / -25000 - 1) << 0); 418e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 419e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 420e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4212804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4222804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * TEMP: 1/1000 degrees C (-128C to +127C) 4232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 1C/bit, two's complement 4242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 425e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_TEMP_FROM_REG(u8 reg) 426e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 427e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (s8)reg * 1000; 428e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 429e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 430e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_TEMP_MIN (-128000) 4312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_TEMP_MAX (127000) 432e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * TEMP: 1/1000 degrees C (-128C to +127C) 4352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 1C/bit, two's complement 4362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 4375bfedac045082a97e20d47d876071279ef984d28Christian Hohnstaedtstatic u8 LM93_TEMP_TO_REG(long temp) 438e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 439e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int ntemp = SENSORS_LIMIT(temp, LM93_TEMP_MIN, LM93_TEMP_MAX); 4402804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ntemp += (ntemp < 0 ? -500 : 500); 441e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)(ntemp / 1000); 442e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 443e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 444e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* Determine 4-bit temperature offset resolution */ 445e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr) 446e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 447e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* mode: 0 => 1C/bit, nonzero => 0.5C/bit */ 448e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return sfc2 & (nr < 2 ? 0x10 : 0x20); 449e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 450e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4512804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4522804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * This function is common to all 4-bit temperature offsets 4532804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * reg is 4 bits right justified 4542804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * mode 0 => 1C/bit, mode !0 => 0.5C/bit 4552804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 456e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode) 457e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 458e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (reg & 0x0f) * (mode ? 5 : 10); 459e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 460e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4612804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_TEMP_OFFSET_MIN (0) 462e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_TEMP_OFFSET_MAX0 (150) 4632804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck#define LM93_TEMP_OFFSET_MAX1 (75) 464e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4652804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4662804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * This function is common to all 4-bit temperature offsets 4672804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * returns 4 bits right justified 4682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * mode 0 => 1C/bit, mode !0 => 0.5C/bit 4692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 470e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode) 471e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 472e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int factor = mode ? 5 : 10; 473e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 474e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch off = SENSORS_LIMIT(off, LM93_TEMP_OFFSET_MIN, 475e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mode ? LM93_TEMP_OFFSET_MAX1 : LM93_TEMP_OFFSET_MAX0); 476e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)((off + factor/2) / factor); 477e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 478e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 479e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* 0 <= nr <= 3 */ 480e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) 481e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 482e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp1-temp2 (nr=0,1) use lower nibble */ 483e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (nr < 2) 484e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return LM93_TEMP_OFFSET_FROM_REG(reg & 0x0f, mode); 485e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 486e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp3-temp4 (nr=2,3) use upper nibble */ 487e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 488e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return LM93_TEMP_OFFSET_FROM_REG(reg >> 4 & 0x0f, mode); 489e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 490e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 4912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 4922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * TEMP: 1/10 degrees C (0C to +15C (mode 0) or +7.5C (mode non-zero)) 4932804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) 4942804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 0 <= nr <= 3 4952804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 496e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) 497e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 498e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); 499e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 500e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp1-temp2 (nr=0,1) use lower nibble */ 501e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (nr < 2) 502e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (old & 0xf0) | (new & 0x0f); 503e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 504e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp3-temp4 (nr=2,3) use upper nibble */ 505e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 506e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (new << 4 & 0xf0) | (old & 0x0f); 507e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 508e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 509e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_AUTO_BOOST_HYST_FROM_REGS(struct lm93_data *data, int nr, 510e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mode) 511e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 512e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg; 513e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 514e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch switch (nr) { 515e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 0: 516e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->boost_hyst[0] & 0x0f; 517e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 518e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 1: 519e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->boost_hyst[0] >> 4 & 0x0f; 520e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 521e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 2: 522e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->boost_hyst[1] & 0x0f; 523e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 524e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 3: 525e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch default: 526e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->boost_hyst[1] >> 4 & 0x0f; 527e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 528e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 529e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 530e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return LM93_TEMP_FROM_REG(data->boost[nr]) - 531e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_TEMP_OFFSET_FROM_REG(reg, mode); 532e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 533e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 534e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst, 535e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr, int mode) 536e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 537e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg = LM93_TEMP_OFFSET_TO_REG( 538e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (LM93_TEMP_FROM_REG(data->boost[nr]) - hyst), mode); 539e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 540e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch switch (nr) { 541e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 0: 542e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (data->boost_hyst[0] & 0xf0) | (reg & 0x0f); 543e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 544e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 1: 545e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (reg << 4 & 0xf0) | (data->boost_hyst[0] & 0x0f); 546e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 547e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 2: 548e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (data->boost_hyst[1] & 0xf0) | (reg & 0x0f); 549e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 550e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 3: 551e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch default: 552e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (reg << 4 & 0xf0) | (data->boost_hyst[1] & 0x0f); 553e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 554e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 555e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 556e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return reg; 557e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 558e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 5592804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 5602804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * PWM: 0-255 per sensors documentation 5612804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 0-13 as mapped below... right justified 5622804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 5632804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeckenum pwm_freq { LM93_PWM_MAP_HI_FREQ, LM93_PWM_MAP_LO_FREQ }; 5642804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 565e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_pwm_map[2][16] = { 566e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 567e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x00, /* 0.00% */ 0x40, /* 25.00% */ 568e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x50, /* 31.25% */ 0x60, /* 37.50% */ 569e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x70, /* 43.75% */ 0x80, /* 50.00% */ 570e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x90, /* 56.25% */ 0xa0, /* 62.50% */ 571e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xb0, /* 68.75% */ 0xc0, /* 75.00% */ 572e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xd0, /* 81.25% */ 0xe0, /* 87.50% */ 573e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xf0, /* 93.75% */ 0xff, /* 100.00% */ 574e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xff, 0xff, /* 14, 15 are reserved and should never occur */ 575e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch }, 576e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch { 577e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x00, /* 0.00% */ 0x40, /* 25.00% */ 578e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x49, /* 28.57% */ 0x52, /* 32.14% */ 579e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x5b, /* 35.71% */ 0x64, /* 39.29% */ 580e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x6d, /* 42.86% */ 0x76, /* 46.43% */ 581e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x80, /* 50.00% */ 0x89, /* 53.57% */ 582e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0x92, /* 57.14% */ 0xb6, /* 71.43% */ 583e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xdb, /* 85.71% */ 0xff, /* 100.00% */ 584e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0xff, 0xff, /* 14, 15 are reserved and should never occur */ 585e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch }, 586e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 587e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 5882804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeckstatic int LM93_PWM_FROM_REG(u8 reg, enum pwm_freq freq) 589e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 590e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return lm93_pwm_map[freq][reg & 0x0f]; 591e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 592e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 593e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* round up to nearest match */ 5942804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeckstatic u8 LM93_PWM_TO_REG(int pwm, enum pwm_freq freq) 595e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 596e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 597e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 13; i++) 598e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (pwm <= lm93_pwm_map[freq][i]) 599e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 600e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 601e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* can fall through with i==13 */ 602e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)i; 603e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 604e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 605e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_FAN_FROM_REG(u16 regs) 606e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 607e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const u16 count = le16_to_cpu(regs) >> 2; 6082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return count == 0 ? -1 : count == 0x3fff ? 0 : 1350000 / count; 609e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 610e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 611e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* 612e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch * RPM: (82.5 to 1350000) 613e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch * REG: 14-bits, LE, *left* justified 614e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch */ 615e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u16 LM93_FAN_TO_REG(long rpm) 616e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 617e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u16 count, regs; 618e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 619e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (rpm == 0) { 620e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch count = 0x3fff; 621e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 622e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rpm = SENSORS_LIMIT(rpm, 1, 1000000); 623e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch count = SENSORS_LIMIT((1350000 + rpm) / rpm, 1, 0x3ffe); 624e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 625e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 626e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch regs = count << 2; 627e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return cpu_to_le16(regs); 628e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 629e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 6302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 6312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * PWM FREQ: HZ 6322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 0-7 as mapped below 6332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 634e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_pwm_freq_map[8] = { 635e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 22500, 96, 84, 72, 60, 48, 36, 12 636e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 637e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 638e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_PWM_FREQ_FROM_REG(u8 reg) 639e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 640e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return lm93_pwm_freq_map[reg & 0x07]; 641e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 642e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 643e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* round up to nearest match */ 644e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_PWM_FREQ_TO_REG(int freq) 645e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 646e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 647e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 7; i > 0; i--) 648e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (freq <= lm93_pwm_freq_map[i]) 649e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 650e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 651e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* can fall through with i==0 */ 652e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)i; 653e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 654e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 6552804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 6562804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * TIME: 1/100 seconds 6572804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 0-7 as mapped below 6582804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 659e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_spinup_time_map[8] = { 660e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 0, 10, 25, 40, 70, 100, 200, 400, 661e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 662e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 663e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_SPINUP_TIME_FROM_REG(u8 reg) 664e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 665e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return lm93_spinup_time_map[reg >> 5 & 0x07]; 666e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 667e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 668e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* round up to nearest match */ 669e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_SPINUP_TIME_TO_REG(int time) 670e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 671e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 672e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 7; i++) 673e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (time <= lm93_spinup_time_map[i]) 674e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 675e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 676e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* can fall through with i==8 */ 677e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)i; 678e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 679e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 680e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_RAMP_MIN 0 681e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_RAMP_MAX 75 682e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 683e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_RAMP_FROM_REG(u8 reg) 684e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 685e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (reg & 0x0f) * 5; 686e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 687e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 6882804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 6892804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * RAMP: 1/100 seconds 6902804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 50mS/bit 4-bits right justified 6912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 692e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_RAMP_TO_REG(int ramp) 693e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 694e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ramp = SENSORS_LIMIT(ramp, LM93_RAMP_MIN, LM93_RAMP_MAX); 695e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)((ramp + 2) / 5); 696e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 697e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 6982804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 6992804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * PROCHOT: 0-255, 0 => 0%, 255 => > 96.6% 7002804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: (same) 7012804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 702e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_PROCHOT_TO_REG(long prochot) 703e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 704e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch prochot = SENSORS_LIMIT(prochot, 0, 255); 705e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)prochot; 706e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 707e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 7082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 7092804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * PROCHOT-INTERVAL: 73 - 37200 (1/100 seconds) 7102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: 0-9 as mapped below 7112804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 712e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_interval_map[10] = { 713e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 73, 146, 290, 580, 1170, 2330, 4660, 9320, 18600, 37200, 714e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 715e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 716e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int LM93_INTERVAL_FROM_REG(u8 reg) 717e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 718e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return lm93_interval_map[reg & 0x0f]; 719e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 720e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 721e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* round up to nearest match */ 722e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 LM93_INTERVAL_TO_REG(long interval) 723e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 724e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 725e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 9; i++) 726e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (interval <= lm93_interval_map[i]) 727e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 728e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 729e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* can fall through with i==9 */ 730e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return (u8)i; 731e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 732e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 7332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 7342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * GPIO: 0-255, GPIO0 is LSB 7352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * REG: inverted 7362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 737e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic unsigned LM93_GPI_FROM_REG(u8 reg) 738e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 739e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return ~reg & 0xff; 740e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 741e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 7422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 7432804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * alarm bitmask definitions 7442804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * The LM93 has nearly 64 bits of error status... I've pared that down to 7452804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * what I think is a useful subset in order to fit it into 32 bits. 7462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 7472804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * Especially note that the #VRD_HOT alarms are missing because we provide 7482804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * that information as values in another sysfs file. 7492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 7502804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * If libsensors is extended to support 64 bit values, this could be revisited. 7512804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 752e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN1 0x00000001 753e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN2 0x00000002 754e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN3 0x00000004 755e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN4 0x00000008 756e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN5 0x00000010 757e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN6 0x00000020 758e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN7 0x00000040 759e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN8 0x00000080 760e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN9 0x00000100 761e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN10 0x00000200 762e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN11 0x00000400 763e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN12 0x00000800 764e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN13 0x00001000 765e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN14 0x00002000 766e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN15 0x00004000 767e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_IN16 0x00008000 768e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_FAN1 0x00010000 769e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_FAN2 0x00020000 770e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_FAN3 0x00040000 771e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_FAN4 0x00080000 772e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_PH1_ERR 0x00100000 773e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_PH2_ERR 0x00200000 774e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_SCSI1_ERR 0x00400000 775e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_SCSI2_ERR 0x00800000 776e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_DVDDP1_ERR 0x01000000 777e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_DVDDP2_ERR 0x02000000 778e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_D1_ERR 0x04000000 779e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_D2_ERR 0x08000000 780e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_TEMP1 0x10000000 781e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_TEMP2 0x20000000 782e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define LM93_ALARM_TEMP3 0x40000000 783e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 784e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic unsigned LM93_ALARMS_FROM_REG(struct block1_t b1) 785e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 786e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch unsigned result; 787e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result = b1.host_status_2 & 0x3f; 788e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 789e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (vccp_limit_type[0]) 790e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.host_status_4 & 0x10) << 2; 791e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 792e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= b1.host_status_2 & 0x40; 793e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 794e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (vccp_limit_type[1]) 795e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.host_status_4 & 0x20) << 2; 796e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 797e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= b1.host_status_2 & 0x80; 798e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 799e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= b1.host_status_3 << 8; 800e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.fan_status & 0x0f) << 16; 801e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.p1_prochot_status & 0x80) << 13; 802e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.p2_prochot_status & 0x80) << 14; 803e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.host_status_4 & 0xfc) << 20; 804e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result |= (b1.host_status_1 & 0x07) << 28; 805e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return result; 806e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 807e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 808e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch#define MAX_RETRIES 5 809e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 810e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 lm93_read_byte(struct i2c_client *client, u8 reg) 811e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 812e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int value, i; 813e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 814e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* retry in case of read errors */ 8152804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck for (i = 1; i <= MAX_RETRIES; i++) { 8162804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck value = i2c_smbus_read_byte_data(client, reg); 8172804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (value >= 0) { 818e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return value; 819e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 8202804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "lm93: read byte data failed, " 821e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "address 0x%02x.\n", reg); 822e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mdelay(i + 3); 823e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 824e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 825e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 826e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 827e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* <TODO> what to return in case of error? */ 8282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_err(&client->dev, "lm93: All read byte retries failed!!\n"); 829e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return 0; 830e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 831e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 832e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_write_byte(struct i2c_client *client, u8 reg, u8 value) 833e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 834e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int result; 835e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 836e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* <TODO> how to handle write errors? */ 837e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result = i2c_smbus_write_byte_data(client, reg, value); 838e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 839e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (result < 0) 8402804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "lm93: write byte data failed, " 841e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "0x%02x at address 0x%02x.\n", value, reg); 842e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 843e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return result; 844e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 845e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 846e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u16 lm93_read_word(struct i2c_client *client, u8 reg) 847e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 848e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int value, i; 849e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 850e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* retry in case of read errors */ 8512804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck for (i = 1; i <= MAX_RETRIES; i++) { 8522804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck value = i2c_smbus_read_word_data(client, reg); 8532804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (value >= 0) { 854e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return value; 855e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 8562804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "lm93: read word data failed, " 857e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "address 0x%02x.\n", reg); 858e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mdelay(i + 3); 859e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 860e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 861e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 862e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 863e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* <TODO> what to return in case of error? */ 8642804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_err(&client->dev, "lm93: All read word retries failed!!\n"); 865e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return 0; 866e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 867e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 868e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic int lm93_write_word(struct i2c_client *client, u8 reg, u16 value) 869e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 870e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int result; 871e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 872e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* <TODO> how to handle write errors? */ 873e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result = i2c_smbus_write_word_data(client, reg, value); 874e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 875e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (result < 0) 8762804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "lm93: write word data failed, " 877e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "0x%04x at address 0x%02x.\n", value, reg); 878e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 879e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return result; 880e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 881e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 882e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic u8 lm93_block_buffer[I2C_SMBUS_BLOCK_MAX]; 883e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 884e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* 8852804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * read block data into values, retry if not expected length 8862804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * fbn => index to lm93_block_read_cmds table 8872804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * (Fixed Block Number - section 14.5.2 of LM93 datasheet) 8882804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 889e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values) 890e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 8912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int i, result = 0; 892e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 893e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 1; i <= MAX_RETRIES; i++) { 894e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch result = i2c_smbus_read_block_data(client, 895e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_block_read_cmds[fbn].cmd, lm93_block_buffer); 896e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 897e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (result == lm93_block_read_cmds[fbn].len) { 898e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 899e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 9002804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "lm93: block read data failed, " 901e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "command 0x%02x.\n", 902e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_block_read_cmds[fbn].cmd); 903e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mdelay(i + 3); 904e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 905e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 906e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 907e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (result == lm93_block_read_cmds[fbn].len) { 9082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck memcpy(values, lm93_block_buffer, 9092804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_block_read_cmds[fbn].len); 910e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } else { 911e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* <TODO> what to do in case of error? */ 912e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 913e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 914e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 915e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic struct lm93_data *lm93_update_device(struct device *dev) 916e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 917e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 918e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 919e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const unsigned long interval = HZ + (HZ / 2); 920e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 921e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 922e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 923e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (time_after(jiffies, data->last_updated + interval) || 924e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch !data->valid) { 925e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 926e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->update(data, client); 927e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->last_updated = jiffies; 928e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->valid = 1; 929e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 930e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 931e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 932e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return data; 933e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 934e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 935e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* update routine for data that has no corresponding SMBus block command */ 936e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_update_client_common(struct lm93_data *data, 937e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client) 938e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 939e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 940e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 *ptr; 941e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 942e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp1 - temp4: limits */ 943e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 4; i++) { 944e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->temp_lim[i].min = 945e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_TEMP_MIN(i)); 946e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->temp_lim[i].max = 947e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_TEMP_MAX(i)); 948e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 949e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 950e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* config register */ 951e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->config = lm93_read_byte(client, LM93_REG_CONFIG); 952e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 953e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* vid1 - vid2: values */ 954e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 2; i++) 955e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vid[i] = lm93_read_byte(client, LM93_REG_VID(i)); 956e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 957e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* prochot1 - prochot2: limits */ 958e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 2; i++) 959e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_max[i] = lm93_read_byte(client, 960e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_REG_PROCHOT_MAX(i)); 961e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 962e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* vccp1 - vccp2: VID relative limits */ 963e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 2; i++) 964e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vccp_limits[i] = lm93_read_byte(client, 965e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_REG_VCCP_LIMIT_OFF(i)); 966e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 967e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* GPIO input state */ 968e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->gpi = lm93_read_byte(client, LM93_REG_GPI); 969e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 970e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT override state */ 971e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override = lm93_read_byte(client, 972e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_REG_PROCHOT_OVERRIDE); 973e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 974e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT intervals */ 975e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_interval = lm93_read_byte(client, 976e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_REG_PROCHOT_INTERVAL); 977e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 978af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa /* Fan Boost Temperature registers */ 979e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 4; i++) 980e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost[i] = lm93_read_byte(client, LM93_REG_BOOST(i)); 981e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 982e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Fan Boost Temperature Hyst. registers */ 983e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost_hyst[0] = lm93_read_byte(client, LM93_REG_BOOST_HYST_12); 984e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost_hyst[1] = lm93_read_byte(client, LM93_REG_BOOST_HYST_34); 985e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 986e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Temperature Zone Min. PWM & Hysteresis registers */ 987e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->auto_pwm_min_hyst[0] = 988e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_12); 989e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->auto_pwm_min_hyst[1] = 990e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_PWM_MIN_HYST_34); 991e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 992e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* #PROCHOT & #VRDHOT PWM Ramp Control register */ 993e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->pwm_ramp_ctl = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); 994e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 995e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* misc setup registers */ 996e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc1 = lm93_read_byte(client, LM93_REG_SFC1); 997e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 998e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sf_tach_to_pwm = lm93_read_byte(client, 999e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_REG_SF_TACH_TO_PWM); 1000e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1001e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* write back alarm values to clear */ 1002e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) 1003e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_HOST_ERROR_1 + i, *(ptr + i)); 1004e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1005e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1006e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* update routine which uses SMBus block data commands */ 1007e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_update_client_full(struct lm93_data *data, 1008e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client) 1009e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 10102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_dbg(&client->dev, "starting device update (block data enabled)\n"); 1011e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1012e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* in1 - in16: values & limits */ 1013e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 3, (u8 *)(data->block3)); 1014e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 7, (u8 *)(data->block7)); 1015e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1016e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp1 - temp4: values */ 1017e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 2, (u8 *)(data->block2)); 1018e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1019e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* prochot1 - prochot2: values */ 1020e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 4, (u8 *)(data->block4)); 1021e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1022e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* fan1 - fan4: values & limits */ 1023e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 5, (u8 *)(data->block5)); 1024e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 8, (u8 *)(data->block8)); 1025e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1026e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* pmw control registers */ 1027e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 9, (u8 *)(data->block9)); 1028e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1029e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* alarm values */ 1030e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 1, (u8 *)(&data->block1)); 1031e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1032e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* auto/pwm registers */ 1033e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_block(client, 10, (u8 *)(&data->block10)); 1034e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1035e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_update_client_common(data, client); 1036e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1037e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1038e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* update routine which uses SMBus byte/word data commands only */ 1039e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_update_client_min(struct lm93_data *data, 1040e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client) 1041e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 10422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int i, j; 1043e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 *ptr; 1044e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 10452804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_dbg(&client->dev, "starting device update (block data disabled)\n"); 1046e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1047e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* in1 - in16: values & limits */ 1048e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 16; i++) { 1049e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block3[i] = 1050e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_IN(i)); 1051e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block7[i].min = 1052e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_IN_MIN(i)); 1053e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block7[i].max = 1054e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_IN_MAX(i)); 1055e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1056e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1057e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* temp1 - temp4: values */ 1058e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 4; i++) { 1059e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block2[i] = 1060e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_TEMP(i)); 1061e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1062e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1063e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* prochot1 - prochot2: values */ 1064e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 2; i++) { 1065e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block4[i].cur = 1066e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_PROCHOT_CUR(i)); 1067e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block4[i].avg = 1068e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_PROCHOT_AVG(i)); 1069e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1070e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1071e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* fan1 - fan4: values & limits */ 1072e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 4; i++) { 1073e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block5[i] = 1074e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_word(client, LM93_REG_FAN(i)); 1075e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block8[i] = 1076e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_word(client, LM93_REG_FAN_MIN(i)); 1077e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1078e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1079e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* pwm control registers */ 1080e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 2; i++) { 1081e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (j = 0; j < 4; j++) { 1082e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[i][j] = 10832804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_read_byte(client, LM93_REG_PWM_CTL(i, j)); 1084e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1085e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1086e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1087e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* alarm values */ 1088e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0, ptr = (u8 *)(&data->block1); i < 8; i++) { 1089e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch *(ptr + i) = 1090e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_HOST_ERROR_1 + i); 1091e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1092e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1093e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* auto/pwm (base temp) registers */ 1094e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 4; i++) { 1095e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.base[i] = 1096e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_TEMP_BASE(i)); 1097e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1098e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1099e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* auto/pwm (offset temp) registers */ 1100e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch for (i = 0; i < 12; i++) { 1101e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.offset[i] = 1102e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_read_byte(client, LM93_REG_TEMP_OFFSET(i)); 1103e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1104e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1105e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_update_client_common(data, client); 1106e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1107e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1108e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch/* following are the sysfs callback functions */ 1109e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_in(struct device *dev, struct device_attribute *attr, 1110e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 1111e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1112e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1113e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1114e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1115e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return sprintf(buf, "%d\n", LM93_IN_FROM_REG(nr, data->block3[nr])); 1116e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1117e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1118e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 0); 1119e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 1); 1120e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 2); 1121e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 3); 1122e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_in, NULL, 4); 1123e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_in, NULL, 5); 1124e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_in, NULL, 6); 1125e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_in, NULL, 7); 1126e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_in, NULL, 8); 1127e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_in, NULL, 9); 1128e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_in, NULL, 10); 1129e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_in, NULL, 11); 1130e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_in, NULL, 12); 1131e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in14_input, S_IRUGO, show_in, NULL, 13); 1132e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, show_in, NULL, 14); 1133e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in, NULL, 15); 1134e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1135e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_in_min(struct device *dev, 1136e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1137e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1138e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1139e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1140e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int vccp = nr - 6; 1141e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long rc, vid; 1142e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 11432804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { 1144e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch vid = LM93_VID_FROM_REG(data->vid[vccp]); 1145e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = LM93_IN_MIN_FROM_REG(data->vccp_limits[vccp], vid); 11462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck } else { 11472804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck rc = LM93_IN_FROM_REG(nr, data->block7[nr].min); 1148e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 11492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%ld\n", rc); 1150e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1151e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1152e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_in_min(struct device *dev, struct device_attribute *attr, 1153e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1154e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1155e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1156e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1157e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1158e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int vccp = nr - 6; 1159e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long vid; 11602804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 11612804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 11622804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 11632804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 11642804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 11652804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1166e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1167e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 11682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { 1169e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch vid = LM93_VID_FROM_REG(data->vid[vccp]); 1170e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0xf0) | 1171e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_IN_REL_TO_REG(val, 0, vid); 1172e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), 1173e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vccp_limits[vccp]); 11742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck } else { 11752804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck data->block7[nr].min = LM93_IN_TO_REG(nr, val); 1176e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_IN_MIN(nr), 1177e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block7[nr].min); 1178e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1179e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1180e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1181e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1182e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1183e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, 1184e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 0); 1185e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, 1186e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 1); 1187e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, 1188e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 2); 1189e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, 1190e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 3); 1191e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, 1192e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 4); 1193e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, 1194e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 5); 1195e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, 1196e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 6); 1197e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, 1198e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 7); 1199e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, 1200e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 8); 1201e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, 1202e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 9); 1203e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, 1204e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 10); 1205e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, 1206e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 11); 1207e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, 1208e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 12); 1209e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in14_min, S_IWUSR | S_IRUGO, 1210e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 13); 1211e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in15_min, S_IWUSR | S_IRUGO, 1212e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 14); 1213e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in16_min, S_IWUSR | S_IRUGO, 1214e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_min, store_in_min, 15); 1215e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1216e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_in_max(struct device *dev, 1217e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1218e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1219e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1220e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1221e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int vccp = nr - 6; 1222e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long rc, vid; 1223e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 12242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { 1225e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch vid = LM93_VID_FROM_REG(data->vid[vccp]); 12262804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck rc = LM93_IN_MAX_FROM_REG(data->vccp_limits[vccp], vid); 12272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck } else { 12282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck rc = LM93_IN_FROM_REG(nr, data->block7[nr].max); 1229e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 12302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%ld\n", rc); 1231e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1232e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1233e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_in_max(struct device *dev, struct device_attribute *attr, 1234e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1235e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1236e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1237e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1238e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1239e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int vccp = nr - 6; 1240e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long vid; 12412804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 12422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 12432804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 12442804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 12452804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 12462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1247e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1248e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 12492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if ((nr == 6 || nr == 7) && vccp_limit_type[vccp]) { 1250e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch vid = LM93_VID_FROM_REG(data->vid[vccp]); 1251e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vccp_limits[vccp] = (data->vccp_limits[vccp] & 0x0f) | 1252e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_IN_REL_TO_REG(val, 1, vid); 1253e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_VCCP_LIMIT_OFF(vccp), 1254e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->vccp_limits[vccp]); 12552804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck } else { 12562804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck data->block7[nr].max = LM93_IN_TO_REG(nr, val); 1257e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_IN_MAX(nr), 1258e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block7[nr].max); 1259e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1260e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1261e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1262e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1263e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1264e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, 1265e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 0); 1266e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, 1267e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 1); 1268e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, 1269e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 2); 1270e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, 1271e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 3); 1272e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, 1273e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 4); 1274e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, 1275e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 5); 1276e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, 1277e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 6); 1278e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, 1279e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 7); 1280e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, 1281e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 8); 1282e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, 1283e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 9); 1284e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, 1285e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 10); 1286e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, 1287e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 11); 1288e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, 1289e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 12); 1290e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in14_max, S_IWUSR | S_IRUGO, 1291e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 13); 1292e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in15_max, S_IWUSR | S_IRUGO, 1293e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 14); 1294e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(in16_max, S_IWUSR | S_IRUGO, 1295e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_in_max, store_in_max, 15); 1296e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1297e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp(struct device *dev, 1298e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1299e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1300e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1301e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 13022804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block2[nr])); 1303e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1304e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1305e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); 1306e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); 1307e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); 1308e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1309e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_min(struct device *dev, 1310e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1311e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1312e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1313e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 13142804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].min)); 1315e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1316e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1317e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_min(struct device *dev, struct device_attribute *attr, 1318e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1319e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1320e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1321e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1322e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 13232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck long val; 13242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 13252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 13262804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtol(buf, 10, &val); 13272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 13282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1329e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1330e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1331e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->temp_lim[nr].min = LM93_TEMP_TO_REG(val); 1332e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_TEMP_MIN(nr), data->temp_lim[nr].min); 1333e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1334e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1335e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1336e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1337e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, 1338e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_min, store_temp_min, 0); 1339e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, 1340e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_min, store_temp_min, 1); 1341e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, 1342e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_min, store_temp_min, 2); 1343e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1344e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_max(struct device *dev, 1345e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1346e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1347e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1348e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 13492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->temp_lim[nr].max)); 1350e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1351e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1352e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_max(struct device *dev, struct device_attribute *attr, 1353e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1354e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1355e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1356e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1357e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 13582804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck long val; 13592804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 13602804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 13612804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtol(buf, 10, &val); 13622804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 13632804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1364e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1365e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1366e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->temp_lim[nr].max = LM93_TEMP_TO_REG(val); 1367e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_TEMP_MAX(nr), data->temp_lim[nr].max); 1368e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1369e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1370e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1371e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1372e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 1373e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_max, store_temp_max, 0); 1374e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, 1375e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_max, store_temp_max, 1); 1376e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, 1377e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_max, store_temp_max, 2); 1378e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1379e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_base(struct device *dev, 1380e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1381e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1382e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1383e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 13842804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->block10.base[nr])); 1385e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1386e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1387e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_base(struct device *dev, 1388e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1389e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1390e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1391e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1392e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1393e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 13942804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck long val; 13952804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 13962804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 13972804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtol(buf, 10, &val); 13982804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 13992804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1400e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1401e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1402e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.base[nr] = LM93_TEMP_TO_REG(val); 1403e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_TEMP_BASE(nr), data->block10.base[nr]); 1404e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1405e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1406e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1407e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1408e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_auto_base, S_IWUSR | S_IRUGO, 1409e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_base, store_temp_auto_base, 0); 1410e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_auto_base, S_IWUSR | S_IRUGO, 1411e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_base, store_temp_auto_base, 1); 1412e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_auto_base, S_IWUSR | S_IRUGO, 1413e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_base, store_temp_auto_base, 2); 1414e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1415e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_boost(struct device *dev, 14162804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck struct device_attribute *attr, char *buf) 1417e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1418e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1419e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 14202804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_FROM_REG(data->boost[nr])); 1421e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1422e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1423e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_boost(struct device *dev, 1424e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1425e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1426e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1427e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1428e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1429e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 14302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck long val; 14312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 14322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 14332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtol(buf, 10, &val); 14342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 14352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1436e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1437e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1438e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost[nr] = LM93_TEMP_TO_REG(val); 1439e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_BOOST(nr), data->boost[nr]); 1440e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1441e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1442e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1443e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1444e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_auto_boost, S_IWUSR | S_IRUGO, 1445e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost, store_temp_auto_boost, 0); 1446e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_auto_boost, S_IWUSR | S_IRUGO, 1447e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost, store_temp_auto_boost, 1); 1448e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_auto_boost, S_IWUSR | S_IRUGO, 1449e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost, store_temp_auto_boost, 2); 1450e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1451e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_boost_hyst(struct device *dev, 1452e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1453e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 1454e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1455e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1456e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1457e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); 14582804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 1459e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_AUTO_BOOST_HYST_FROM_REGS(data, nr, mode)); 1460e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1461e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1462e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_boost_hyst(struct device *dev, 1463e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1464e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1465e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1466e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1467e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1468e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 14692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 14702804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 14712804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 14722804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 14732804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 14742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1475e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1476e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1477e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* force 0.5C/bit mode */ 1478e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 1479e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); 1480e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 1481e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost_hyst[nr/2] = LM93_AUTO_BOOST_HYST_TO_REG(data, val, nr, 1); 1482e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_BOOST_HYST(nr), 1483e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->boost_hyst[nr/2]); 1484e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1485e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1486e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1487e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1488e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_auto_boost_hyst, S_IWUSR | S_IRUGO, 1489e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost_hyst, 1490e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_boost_hyst, 0); 1491e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_auto_boost_hyst, S_IWUSR | S_IRUGO, 1492e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost_hyst, 1493e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_boost_hyst, 1); 1494e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_auto_boost_hyst, S_IWUSR | S_IRUGO, 1495e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_boost_hyst, 1496e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_boost_hyst, 2); 1497e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1498e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_offset(struct device *dev, 1499e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1500e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1501e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); 1502e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = s_attr->index; 1503e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int ofs = s_attr->nr; 1504e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1505e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); 15062804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 1507e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_TEMP_AUTO_OFFSET_FROM_REG(data->block10.offset[ofs], 15082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck nr, mode)); 1509e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1510e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1511e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_offset(struct device *dev, 1512e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1513e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1514e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1515e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr); 1516e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = s_attr->index; 1517e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int ofs = s_attr->nr; 1518e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1519e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 15202804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 15212804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 15222804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 15232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 15242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 15252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1526e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1527e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1528e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* force 0.5C/bit mode */ 1529e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 1530e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); 1531e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 1532e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.offset[ofs] = LM93_TEMP_AUTO_OFFSET_TO_REG( 1533e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.offset[ofs], val, nr, 1); 1534e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_TEMP_OFFSET(ofs), 1535e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block10.offset[ofs]); 1536e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1537e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1538e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1539e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1540e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset1, S_IWUSR | S_IRUGO, 1541e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 0, 0); 1542e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset2, S_IWUSR | S_IRUGO, 1543e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 1, 0); 1544e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset3, S_IWUSR | S_IRUGO, 1545e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 2, 0); 1546e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset4, S_IWUSR | S_IRUGO, 1547e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 3, 0); 1548e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset5, S_IWUSR | S_IRUGO, 1549e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 4, 0); 1550e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset6, S_IWUSR | S_IRUGO, 1551e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 5, 0); 1552e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset7, S_IWUSR | S_IRUGO, 1553e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 6, 0); 1554e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset8, S_IWUSR | S_IRUGO, 1555e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 7, 0); 1556e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset9, S_IWUSR | S_IRUGO, 1557e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 8, 0); 1558e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset10, S_IWUSR | S_IRUGO, 1559e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 9, 0); 1560e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset11, S_IWUSR | S_IRUGO, 1561e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 10, 0); 1562e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp1_auto_offset12, S_IWUSR | S_IRUGO, 1563e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 11, 0); 1564e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset1, S_IWUSR | S_IRUGO, 1565e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 0, 1); 1566e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset2, S_IWUSR | S_IRUGO, 1567e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 1, 1); 1568e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset3, S_IWUSR | S_IRUGO, 1569e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 2, 1); 1570e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset4, S_IWUSR | S_IRUGO, 1571e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 3, 1); 1572e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset5, S_IWUSR | S_IRUGO, 1573e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 4, 1); 1574e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset6, S_IWUSR | S_IRUGO, 1575e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 5, 1); 1576e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset7, S_IWUSR | S_IRUGO, 1577e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 6, 1); 1578e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset8, S_IWUSR | S_IRUGO, 1579e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 7, 1); 1580e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset9, S_IWUSR | S_IRUGO, 1581e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 8, 1); 1582e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset10, S_IWUSR | S_IRUGO, 1583e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 9, 1); 1584e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset11, S_IWUSR | S_IRUGO, 1585e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 10, 1); 1586e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp2_auto_offset12, S_IWUSR | S_IRUGO, 1587e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 11, 1); 1588e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset1, S_IWUSR | S_IRUGO, 1589e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 0, 2); 1590e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset2, S_IWUSR | S_IRUGO, 1591e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 1, 2); 1592e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset3, S_IWUSR | S_IRUGO, 1593e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 2, 2); 1594e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset4, S_IWUSR | S_IRUGO, 1595e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 3, 2); 1596e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset5, S_IWUSR | S_IRUGO, 1597e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 4, 2); 1598e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset6, S_IWUSR | S_IRUGO, 1599e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 5, 2); 1600e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset7, S_IWUSR | S_IRUGO, 1601e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 6, 2); 1602e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset8, S_IWUSR | S_IRUGO, 1603e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 7, 2); 1604e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset9, S_IWUSR | S_IRUGO, 1605e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 8, 2); 1606e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset10, S_IWUSR | S_IRUGO, 1607e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 9, 2); 1608e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset11, S_IWUSR | S_IRUGO, 1609e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 10, 2); 1610e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR_2(temp3_auto_offset12, S_IWUSR | S_IRUGO, 1611e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset, store_temp_auto_offset, 11, 2); 1612e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1613e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_pwm_min(struct device *dev, 1614e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1615e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1616e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1617e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg, ctl4; 1618e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1619e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->auto_pwm_min_hyst[nr/2] >> 4 & 0x0f; 1620e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl4 = data->block9[nr][LM93_PWM_CTL4]; 16212804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_PWM_FROM_REG(reg, (ctl4 & 0x07) ? 1622e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); 1623e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1624e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1625e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_pwm_min(struct device *dev, 1626e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1627e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1628e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1629e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1630e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1631e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1632e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg, ctl4; 16332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 16342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 16352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 16362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 16372804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 16382804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1639e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1640e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1641e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_PWM_MIN_HYST(nr)); 16422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); 1643e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (reg & 0x0f) | 1644e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? 1645e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : 1646e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_HI_FREQ) << 4; 1647e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->auto_pwm_min_hyst[nr/2] = reg; 1648e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); 1649e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1650e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1651e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1652e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1653e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_auto_pwm_min, S_IWUSR | S_IRUGO, 1654e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_pwm_min, 1655e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_pwm_min, 0); 1656e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_auto_pwm_min, S_IWUSR | S_IRUGO, 1657e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_pwm_min, 1658e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_pwm_min, 1); 1659e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_auto_pwm_min, S_IWUSR | S_IRUGO, 1660e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_pwm_min, 1661e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_pwm_min, 2); 1662e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1663e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_temp_auto_offset_hyst(struct device *dev, 1664e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1665e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1666e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1667e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1668e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mode = LM93_TEMP_OFFSET_MODE_FROM_REG(data->sfc2, nr); 16692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_TEMP_OFFSET_FROM_REG( 16702804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck data->auto_pwm_min_hyst[nr / 2], mode)); 1671e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1672e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1673e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_temp_auto_offset_hyst(struct device *dev, 1674e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1675e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1676e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1677e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1678e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1679e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1680e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg; 16812804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 16822804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 16832804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 16842804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 16852804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 16862804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1687e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1688e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1689e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* force 0.5C/bit mode */ 1690e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 1691e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 |= ((nr < 2) ? 0x10 : 0x20); 1692e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 1693e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = data->auto_pwm_min_hyst[nr/2]; 1694e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = (reg & 0xf0) | (LM93_TEMP_OFFSET_TO_REG(val, 1) & 0x0f); 1695e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->auto_pwm_min_hyst[nr/2] = reg; 1696e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PWM_MIN_HYST(nr), reg); 1697e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1698e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1699e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1700e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1701e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp1_auto_offset_hyst, S_IWUSR | S_IRUGO, 1702e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset_hyst, 1703e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_offset_hyst, 0); 1704e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp2_auto_offset_hyst, S_IWUSR | S_IRUGO, 1705e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset_hyst, 1706e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_offset_hyst, 1); 1707e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(temp3_auto_offset_hyst, S_IWUSR | S_IRUGO, 1708e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_temp_auto_offset_hyst, 1709e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_temp_auto_offset_hyst, 2); 1710e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1711e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_fan_input(struct device *dev, 1712e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1713e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1714e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct sensor_device_attribute *s_attr = to_sensor_dev_attr(attr); 1715e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = s_attr->index; 1716e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1717e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 17182804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block5[nr])); 1719e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1720e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1721e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0); 1722e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1); 1723e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2); 1724e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan_input, NULL, 3); 1725e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1726e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_fan_min(struct device *dev, 1727e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1728e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1729e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1730e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1731e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 17322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_FAN_FROM_REG(data->block8[nr])); 1733e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1734e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1735e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_fan_min(struct device *dev, struct device_attribute *attr, 1736e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1737e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1738e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1739e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1740e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 17412804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 17422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 17432804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 17442804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 17452804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 17462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1747e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1748e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1749e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block8[nr] = LM93_FAN_TO_REG(val); 17502804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_word(client, LM93_REG_FAN_MIN(nr), data->block8[nr]); 1751e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1752e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1753e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1754e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1755e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, 1756e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_min, store_fan_min, 0); 1757e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, 1758e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_min, store_fan_min, 1); 1759e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, 1760e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_min, store_fan_min, 2); 1761e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, 1762e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_min, store_fan_min, 3); 1763e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 17642804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 17652804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * some tedious bit-twiddling here to deal with the register format: 17662804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 17672804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * data->sf_tach_to_pwm: (tach to pwm mapping bits) 17682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 17692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 17702804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 17712804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 17722804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * data->sfc2: (enable bits) 17732804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * 17742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * bit | 3 | 2 | 1 | 0 17752804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * T4 T3 T2 T1 17762804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 1777e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1778e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_fan_smart_tach(struct device *dev, 1779e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1780e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1781e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1782e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1783e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long rc = 0; 1784e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mapping; 1785e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1786e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* extract the relevant mapping */ 1787e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mapping = (data->sf_tach_to_pwm >> (nr * 2)) & 0x03; 1788e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1789e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* if there's a mapping and it's enabled */ 1790e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (mapping && ((data->sfc2 >> nr) & 0x01)) 1791e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = mapping; 17922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%ld\n", rc); 1793e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1794e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 17952804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 17962804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * helper function - must grab data->update_lock before calling 17972804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * fan is 0-3, indicating fan1-fan4 17982804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 1799e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_write_fan_smart_tach(struct i2c_client *client, 1800e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data, int fan, long value) 1801e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1802e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* insert the new mapping and write it out */ 1803e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sf_tach_to_pwm = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); 1804e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sf_tach_to_pwm &= ~(0x3 << fan * 2); 1805e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sf_tach_to_pwm |= value << fan * 2; 1806e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, data->sf_tach_to_pwm); 1807e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1808e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* insert the enable bit and write it out */ 1809e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 1810e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (value) 1811e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 |= 1 << fan; 1812e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 1813e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 &= ~(1 << fan); 1814e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 1815e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1816e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1817e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_fan_smart_tach(struct device *dev, 1818e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1819e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1820e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1821e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1822e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1823e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 18242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 18252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 18262804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 18272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 18282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 18292804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1830e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1831e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 1832e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* sanity test, ignore the write otherwise */ 1833e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (0 <= val && val <= 2) { 1834e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* can't enable if pwm freq is 22.5KHz */ 1835e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (val) { 1836e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl4 = lm93_read_byte(client, 18372804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck LM93_REG_PWM_CTL(val - 1, LM93_PWM_CTL4)); 1838e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if ((ctl4 & 0x07) == 0) 1839e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch val = 0; 1840e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1841e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_fan_smart_tach(client, data, nr, val); 1842e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1843e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1844e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1845e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1846e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1847e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan1_smart_tach, S_IWUSR | S_IRUGO, 1848e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_smart_tach, store_fan_smart_tach, 0); 1849e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan2_smart_tach, S_IWUSR | S_IRUGO, 1850e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_smart_tach, store_fan_smart_tach, 1); 1851e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan3_smart_tach, S_IWUSR | S_IRUGO, 1852e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_smart_tach, store_fan_smart_tach, 2); 1853e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(fan4_smart_tach, S_IWUSR | S_IRUGO, 1854e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_fan_smart_tach, store_fan_smart_tach, 3); 1855e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1856e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm(struct device *dev, struct device_attribute *attr, 1857e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 1858e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1859e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1860e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1861e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl2, ctl4; 1862e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long rc; 1863e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1864e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl2 = data->block9[nr][LM93_PWM_CTL2]; 1865e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl4 = data->block9[nr][LM93_PWM_CTL4]; 1866e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (ctl2 & 0x01) /* show user commanded value if enabled */ 1867e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = data->pwm_override[nr]; 1868e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else /* show present h/w value if manual pwm disabled */ 1869e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? 1870e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); 18712804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%ld\n", rc); 1872e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1873e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1874e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm(struct device *dev, struct device_attribute *attr, 1875e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1876e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1877e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1878e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1879e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1880e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl2, ctl4; 18812804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 18822804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 18832804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 18842804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 18852804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 18862804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1887e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1888e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 18892804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2)); 18902804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); 18912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? 1892e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4; 1893e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* save user commanded value */ 1894e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4, 1895e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : 1896e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_HI_FREQ); 18972804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2); 1898e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1899e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1900e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1901e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1902e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0); 1903e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1); 1904e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1905e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_enable(struct device *dev, 1906e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 1907e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1908e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1909e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1910e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl2; 1911e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch long rc; 1912e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1913e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl2 = data->block9[nr][LM93_PWM_CTL2]; 1914e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (ctl2 & 0x01) /* manual override enabled ? */ 1915e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1; 1916e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 1917e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch rc = 2; 19182804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%ld\n", rc); 1919e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1920e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1921e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_enable(struct device *dev, 1922e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 1923e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 1924e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1925e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1926e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 1927e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 1928e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl2; 19292804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 19302804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 19312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 19322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 19332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 19342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 1935e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1936e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 19372804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl2 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2)); 1938e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1939e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch switch (val) { 1940e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch case 0: 1941e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl2 |= 0xF1; /* enable manual override, set PWM to max */ 1942e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 19432804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck case 1: 19442804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl2 |= 0x01; /* enable manual override */ 1945e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 19462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck case 2: 19472804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl2 &= ~0x01; /* disable manual override */ 1948e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch break; 1949e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch default: 1950e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1951e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return -EINVAL; 1952e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 1953e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 19542804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL2), ctl2); 1955e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 1956e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 1957e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1958e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1959e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, 1960e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_enable, store_pwm_enable, 0); 1961e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, 1962e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_enable, store_pwm_enable, 1); 1963e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1964e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, 1965e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 1966e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1967e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 1968e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 1969e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl4; 1970e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1971e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl4 = data->block9[nr][LM93_PWM_CTL4]; 19722804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_PWM_FREQ_FROM_REG(ctl4)); 1973e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1974e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 19752804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck/* 19762804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * helper function - must grab data->update_lock before calling 19772804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * pwm is 0-1, indicating pwm1-pwm2 19782804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck * this disables smart tach for all tach channels bound to the given pwm 19792804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck */ 1980e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_disable_fan_smart_tach(struct i2c_client *client, 1981e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data, int pwm) 1982e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 1983e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mapping = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); 1984e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int mask; 1985e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1986e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* collapse the mapping into a mask of enable bits */ 1987e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mapping = (mapping >> pwm) & 0x55; 1988e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mask = mapping & 0x01; 1989e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mask |= (mapping & 0x04) >> 1; 1990e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mask |= (mapping & 0x10) >> 2; 1991e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mask |= (mapping & 0x40) >> 3; 1992e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1993e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* disable smart tach according to the mask */ 1994e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); 1995e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->sfc2 &= ~mask; 1996e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SFC2, data->sfc2); 1997e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 1998e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 1999e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_freq(struct device *dev, 2000e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2001e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2002e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2003e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2004e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2005e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2006e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl4; 20072804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 20082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 20092804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 20102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 20112804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 20122804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2013e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2014e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 20152804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); 2016e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val); 2017e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL4] = ctl4; 2018e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ 2019e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (!ctl4) 2020e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_disable_fan_smart_tach(client, data, nr); 20212804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4), ctl4); 2022e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2023e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2024e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2025e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2026e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO, 2027e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_freq, store_pwm_freq, 0); 2028e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2_freq, S_IWUSR | S_IRUGO, 2029e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_freq, store_pwm_freq, 1); 2030e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2031e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_auto_channels(struct device *dev, 2032e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2033e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2034e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2035e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 20362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", data->block9[nr][LM93_PWM_CTL1]); 2037e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2038e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2039e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_auto_channels(struct device *dev, 2040e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2041e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2042e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2043e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2044e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2045e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 20462804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 20472804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 20482804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 20492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 20502804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 20512804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2052e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2053e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2054e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255); 20552804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL1), 2056e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL1]); 2057e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2058e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2059e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2060e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2061e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1_auto_channels, S_IWUSR | S_IRUGO, 2062e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_channels, store_pwm_auto_channels, 0); 2063e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO, 2064e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_channels, store_pwm_auto_channels, 1); 2065e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2066e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_auto_spinup_min(struct device *dev, 20672804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck struct device_attribute *attr, char *buf) 2068e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2069e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2070e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 2071e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl3, ctl4; 2072e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2073e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl3 = data->block9[nr][LM93_PWM_CTL3]; 2074e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl4 = data->block9[nr][LM93_PWM_CTL4]; 20752804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 2076e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ? 2077e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ)); 2078e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2079e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2080e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_auto_spinup_min(struct device *dev, 2081e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2082e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2083e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2084e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2085e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2086e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2087e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl3, ctl4; 20882804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 20892804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 20902804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 20912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 20922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 20932804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2094e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2095e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 20962804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); 20972804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); 20982804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? 2099e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_LO_FREQ : 2100e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_PWM_MAP_HI_FREQ); 2101e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL3] = ctl3; 21022804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); 2103e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2104e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2105e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2106e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2107e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1_auto_spinup_min, S_IWUSR | S_IRUGO, 2108e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_spinup_min, 2109e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_spinup_min, 0); 2110e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2_auto_spinup_min, S_IWUSR | S_IRUGO, 2111e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_spinup_min, 2112e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_spinup_min, 1); 2113e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2114e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_auto_spinup_time(struct device *dev, 2115e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2116e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2117e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2118e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 21192804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_SPINUP_TIME_FROM_REG( 2120e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL3])); 2121e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2122e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2123e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_auto_spinup_time(struct device *dev, 2124e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2125e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2126e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2127e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2128e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2129e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2130e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ctl3; 21312804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 21322804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 21332804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 21342804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 21352804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 21362804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2137e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2138e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 21392804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck ctl3 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); 2140e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0); 2141e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->block9[nr][LM93_PWM_CTL3] = ctl3; 21422804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck lm93_write_byte(client, LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); 2143e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2144e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2145e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2146e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2147e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm1_auto_spinup_time, S_IWUSR | S_IRUGO, 2148e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_spinup_time, 2149e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_spinup_time, 0); 2150e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(pwm2_auto_spinup_time, S_IWUSR | S_IRUGO, 2151e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_spinup_time, 2152e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_spinup_time, 1); 2153e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2154e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_auto_prochot_ramp(struct device *dev, 2155e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2156e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2157e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 21582804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 2159e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f)); 2160e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2161e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2162e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_auto_prochot_ramp(struct device *dev, 2163e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2164e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2165e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2166e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2167e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2168e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ramp; 21692804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 21702804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 21712804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 21722804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 21732804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 21742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2175e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2176e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2177e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); 2178e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ramp = (ramp & 0x0f) | (LM93_RAMP_TO_REG(val) << 4 & 0xf0); 2179e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); 2180e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2181e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2182e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2183e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2184e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(pwm_auto_prochot_ramp, S_IRUGO | S_IWUSR, 2185e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_prochot_ramp, 2186e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_prochot_ramp); 2187e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2188e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev, 2189e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2190e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2191e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 21922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 2193e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f)); 2194e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2195e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2196e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev, 2197e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2198e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2199e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2200e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2201e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2202e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 ramp; 22032804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 22042804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 22052804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 22062804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 22072804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 22082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2209e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2210e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2211e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); 2212e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch ramp = (ramp & 0xf0) | (LM93_RAMP_TO_REG(val) & 0x0f); 2213e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); 2214e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2215e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return 0; 2216e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2217e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2218e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(pwm_auto_vrdhot_ramp, S_IRUGO | S_IWUSR, 2219e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_pwm_auto_vrdhot_ramp, 2220e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_pwm_auto_vrdhot_ramp); 2221e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2222e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_vid(struct device *dev, struct device_attribute *attr, 2223e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2224e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2225e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2226e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 22272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_VID_FROM_REG(data->vid[nr])); 2228e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2229e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2230e7f62303b8a7f34ce6f97a1722b6907f0ddbd0a9Jean Delvarestatic SENSOR_DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL, 0); 2231e7f62303b8a7f34ce6f97a1722b6907f0ddbd0a9Jean Delvarestatic SENSOR_DEVICE_ATTR(cpu1_vid, S_IRUGO, show_vid, NULL, 1); 2232e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2233e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot(struct device *dev, struct device_attribute *attr, 2234e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2235e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2236e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2237e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 22382804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", data->block4[nr].cur); 2239e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2240e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2241e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot1, S_IRUGO, show_prochot, NULL, 0); 2242e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot2, S_IRUGO, show_prochot, NULL, 1); 2243e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2244e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_avg(struct device *dev, 2245e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2246e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2247e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2248e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 22492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", data->block4[nr].avg); 2250e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2251e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2252e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot1_avg, S_IRUGO, show_prochot_avg, NULL, 0); 2253e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot2_avg, S_IRUGO, show_prochot_avg, NULL, 1); 2254e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2255e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_max(struct device *dev, 2256e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2257e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2258e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2259e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 22602804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", data->prochot_max[nr]); 2261e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2262e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2263e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_prochot_max(struct device *dev, 2264e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2265e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2266e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2267e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2268e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2269e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 22702804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 22712804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 22722804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 22732804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 22742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 22752804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2276e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2277e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2278e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_max[nr] = LM93_PROCHOT_TO_REG(val); 2279e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PROCHOT_MAX(nr), 2280e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_max[nr]); 2281e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2282e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2283e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2284e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2285e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot1_max, S_IWUSR | S_IRUGO, 2286e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_max, store_prochot_max, 0); 2287e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot2_max, S_IWUSR | S_IRUGO, 2288e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_max, store_prochot_max, 1); 2289e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2290e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic const u8 prochot_override_mask[] = { 0x80, 0x40 }; 2291e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2292e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_override(struct device *dev, 2293e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2294e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2295e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2296e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 22972804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 2298e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch (data->prochot_override & prochot_override_mask[nr]) ? 1 : 0); 2299e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2300e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2301e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_prochot_override(struct device *dev, 2302e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2303e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2304e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2305e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2306e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2307e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 23082804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 23092804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 23102804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 23112804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 23122804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 23132804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2314e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2315e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2316e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (val) 2317e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override |= prochot_override_mask[nr]; 2318e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 2319e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override &= (~prochot_override_mask[nr]); 2320e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, 2321e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override); 2322e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2323e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2324e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2325e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2326e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot1_override, S_IWUSR | S_IRUGO, 2327e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_override, store_prochot_override, 0); 2328e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot2_override, S_IWUSR | S_IRUGO, 2329e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_override, store_prochot_override, 1); 2330e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2331e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_interval(struct device *dev, 2332e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2333e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2334e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2335e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 2336e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 tmp; 23372804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (nr == 1) 2338e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch tmp = (data->prochot_interval & 0xf0) >> 4; 2339e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 2340e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch tmp = data->prochot_interval & 0x0f; 23412804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_INTERVAL_FROM_REG(tmp)); 2342e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2343e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2344e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_prochot_interval(struct device *dev, 2345e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2346e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2347e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2348e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2349e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2350e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2351e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 tmp; 23522804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 23532804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 23542804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 23552804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 23562804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 23572804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2358e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2359e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2360e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch tmp = lm93_read_byte(client, LM93_REG_PROCHOT_INTERVAL); 23612804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (nr == 1) 2362e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch tmp = (tmp & 0x0f) | (LM93_INTERVAL_TO_REG(val) << 4); 2363e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 2364e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch tmp = (tmp & 0xf0) | LM93_INTERVAL_TO_REG(val); 2365e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_interval = tmp; 2366e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PROCHOT_INTERVAL, tmp); 2367e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2368e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2369e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2370e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2371e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot1_interval, S_IWUSR | S_IRUGO, 2372e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_interval, store_prochot_interval, 0); 2373e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(prochot2_interval, S_IWUSR | S_IRUGO, 2374e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_interval, store_prochot_interval, 1); 2375e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2376e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_override_duty_cycle(struct device *dev, 2377e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2378e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2379e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2380e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 23812804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", data->prochot_override & 0x0f); 2382e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2383e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2384e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_prochot_override_duty_cycle(struct device *dev, 2385e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2386e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2387e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2388e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2389e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 23902804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 23912804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 23922804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 23932804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 23942804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 23952804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2396e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2397e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2398e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override = (data->prochot_override & 0xf0) | 2399e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch SENSORS_LIMIT(val, 0, 15); 2400e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_PROCHOT_OVERRIDE, 2401e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->prochot_override); 2402e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2403e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2404e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2405e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2406e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(prochot_override_duty_cycle, S_IRUGO | S_IWUSR, 2407e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_override_duty_cycle, 2408e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch store_prochot_override_duty_cycle); 2409e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2410e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_prochot_short(struct device *dev, 2411e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, char *buf) 2412e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2413e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 24142804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", (data->config & 0x10) ? 1 : 0); 2415e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2416e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2417e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t store_prochot_short(struct device *dev, 2418e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct device_attribute *attr, 2419e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch const char *buf, size_t count) 2420e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2421e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct i2c_client *client = to_i2c_client(dev); 2422e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 24232804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck unsigned long val; 24242804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck int err; 24252804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck 24262804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck err = kstrtoul(buf, 10, &val); 24272804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (err) 24282804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return err; 2429e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2430e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_lock(&data->update_lock); 2431e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (val) 2432e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->config |= 0x10; 2433e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch else 2434e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->config &= ~0x10; 2435e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_CONFIG, data->config); 2436e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_unlock(&data->update_lock); 2437e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return count; 2438e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2439e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2440e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(prochot_short, S_IRUGO | S_IWUSR, 2441e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch show_prochot_short, store_prochot_short); 2442e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2443e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_vrdhot(struct device *dev, struct device_attribute *attr, 2444e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2445e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2446e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int nr = (to_sensor_dev_attr(attr))->index; 2447e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 24482804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", 24492804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck data->block1.host_status_1 & (1 << (nr + 4)) ? 1 : 0); 2450e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2451e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2452e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(vrdhot1, S_IRUGO, show_vrdhot, NULL, 0); 2453e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic SENSOR_DEVICE_ATTR(vrdhot2, S_IRUGO, show_vrdhot, NULL, 1); 2454e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2455e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_gpio(struct device *dev, struct device_attribute *attr, 2456e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2457e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2458e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 24592804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_GPI_FROM_REG(data->gpi)); 2460e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2461e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2462e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(gpio, S_IRUGO, show_gpio, NULL); 2463e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2464e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic ssize_t show_alarms(struct device *dev, struct device_attribute *attr, 2465e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch char *buf) 2466e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2467e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = lm93_update_device(dev); 24682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck return sprintf(buf, "%d\n", LM93_ALARMS_FROM_REG(data->block1)); 2469e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2470e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2471e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 2472e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2473e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic struct attribute *lm93_attrs[] = { 2474e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in1_input.dev_attr.attr, 2475e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in2_input.dev_attr.attr, 2476e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in3_input.dev_attr.attr, 2477e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in4_input.dev_attr.attr, 2478e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in5_input.dev_attr.attr, 2479e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in6_input.dev_attr.attr, 2480e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in7_input.dev_attr.attr, 2481e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in8_input.dev_attr.attr, 2482e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in9_input.dev_attr.attr, 2483e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in10_input.dev_attr.attr, 2484e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in11_input.dev_attr.attr, 2485e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in12_input.dev_attr.attr, 2486e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in13_input.dev_attr.attr, 2487e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in14_input.dev_attr.attr, 2488e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in15_input.dev_attr.attr, 2489e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in16_input.dev_attr.attr, 2490e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in1_min.dev_attr.attr, 2491e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in2_min.dev_attr.attr, 2492e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in3_min.dev_attr.attr, 2493e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in4_min.dev_attr.attr, 2494e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in5_min.dev_attr.attr, 2495e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in6_min.dev_attr.attr, 2496e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in7_min.dev_attr.attr, 2497e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in8_min.dev_attr.attr, 2498e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in9_min.dev_attr.attr, 2499e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in10_min.dev_attr.attr, 2500e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in11_min.dev_attr.attr, 2501e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in12_min.dev_attr.attr, 2502e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in13_min.dev_attr.attr, 2503e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in14_min.dev_attr.attr, 2504e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in15_min.dev_attr.attr, 2505e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in16_min.dev_attr.attr, 2506e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in1_max.dev_attr.attr, 2507e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in2_max.dev_attr.attr, 2508e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in3_max.dev_attr.attr, 2509e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in4_max.dev_attr.attr, 2510e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in5_max.dev_attr.attr, 2511e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in6_max.dev_attr.attr, 2512e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in7_max.dev_attr.attr, 2513e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in8_max.dev_attr.attr, 2514e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in9_max.dev_attr.attr, 2515e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in10_max.dev_attr.attr, 2516e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in11_max.dev_attr.attr, 2517e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in12_max.dev_attr.attr, 2518e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in13_max.dev_attr.attr, 2519e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in14_max.dev_attr.attr, 2520e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in15_max.dev_attr.attr, 2521e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_in16_max.dev_attr.attr, 2522e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_input.dev_attr.attr, 2523e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_input.dev_attr.attr, 2524e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_input.dev_attr.attr, 2525e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_min.dev_attr.attr, 2526e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_min.dev_attr.attr, 2527e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_min.dev_attr.attr, 2528e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_max.dev_attr.attr, 2529e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_max.dev_attr.attr, 2530e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_max.dev_attr.attr, 2531e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_base.dev_attr.attr, 2532e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_base.dev_attr.attr, 2533e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_base.dev_attr.attr, 2534e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_boost.dev_attr.attr, 2535e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_boost.dev_attr.attr, 2536e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_boost.dev_attr.attr, 2537e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_boost_hyst.dev_attr.attr, 2538e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_boost_hyst.dev_attr.attr, 2539e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_boost_hyst.dev_attr.attr, 2540e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset1.dev_attr.attr, 2541e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset2.dev_attr.attr, 2542e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset3.dev_attr.attr, 2543e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset4.dev_attr.attr, 2544e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset5.dev_attr.attr, 2545e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset6.dev_attr.attr, 2546e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset7.dev_attr.attr, 2547e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset8.dev_attr.attr, 2548e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset9.dev_attr.attr, 2549e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset10.dev_attr.attr, 2550e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset11.dev_attr.attr, 2551e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset12.dev_attr.attr, 2552e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset1.dev_attr.attr, 2553e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset2.dev_attr.attr, 2554e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset3.dev_attr.attr, 2555e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset4.dev_attr.attr, 2556e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset5.dev_attr.attr, 2557e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset6.dev_attr.attr, 2558e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset7.dev_attr.attr, 2559e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset8.dev_attr.attr, 2560e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset9.dev_attr.attr, 2561e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset10.dev_attr.attr, 2562e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset11.dev_attr.attr, 2563e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset12.dev_attr.attr, 2564e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset1.dev_attr.attr, 2565e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset2.dev_attr.attr, 2566e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset3.dev_attr.attr, 2567e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset4.dev_attr.attr, 2568e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset5.dev_attr.attr, 2569e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset6.dev_attr.attr, 2570e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset7.dev_attr.attr, 2571e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset8.dev_attr.attr, 2572e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset9.dev_attr.attr, 2573e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset10.dev_attr.attr, 2574e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset11.dev_attr.attr, 2575e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset12.dev_attr.attr, 2576e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_pwm_min.dev_attr.attr, 2577e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_pwm_min.dev_attr.attr, 2578e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_pwm_min.dev_attr.attr, 2579e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp1_auto_offset_hyst.dev_attr.attr, 2580e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp2_auto_offset_hyst.dev_attr.attr, 2581e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_temp3_auto_offset_hyst.dev_attr.attr, 2582e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan1_input.dev_attr.attr, 2583e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan2_input.dev_attr.attr, 2584e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan3_input.dev_attr.attr, 2585e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan4_input.dev_attr.attr, 2586e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan1_min.dev_attr.attr, 2587e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan2_min.dev_attr.attr, 2588e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan3_min.dev_attr.attr, 2589e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan4_min.dev_attr.attr, 2590e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan1_smart_tach.dev_attr.attr, 2591e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan2_smart_tach.dev_attr.attr, 2592e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan3_smart_tach.dev_attr.attr, 2593e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_fan4_smart_tach.dev_attr.attr, 2594e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1.dev_attr.attr, 2595e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2.dev_attr.attr, 2596e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1_enable.dev_attr.attr, 2597e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2_enable.dev_attr.attr, 2598e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1_freq.dev_attr.attr, 2599e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2_freq.dev_attr.attr, 2600e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, 2601e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, 2602e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1_auto_spinup_min.dev_attr.attr, 2603e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2_auto_spinup_min.dev_attr.attr, 2604e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm1_auto_spinup_time.dev_attr.attr, 2605e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_pwm2_auto_spinup_time.dev_attr.attr, 2606e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_pwm_auto_prochot_ramp.attr, 2607e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_pwm_auto_vrdhot_ramp.attr, 2608e7f62303b8a7f34ce6f97a1722b6907f0ddbd0a9Jean Delvare &sensor_dev_attr_cpu0_vid.dev_attr.attr, 2609e7f62303b8a7f34ce6f97a1722b6907f0ddbd0a9Jean Delvare &sensor_dev_attr_cpu1_vid.dev_attr.attr, 2610e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot1.dev_attr.attr, 2611e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot2.dev_attr.attr, 2612e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot1_avg.dev_attr.attr, 2613e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot2_avg.dev_attr.attr, 2614e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot1_max.dev_attr.attr, 2615e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot2_max.dev_attr.attr, 2616e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot1_override.dev_attr.attr, 2617e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot2_override.dev_attr.attr, 2618e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot1_interval.dev_attr.attr, 2619e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_prochot2_interval.dev_attr.attr, 2620e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_prochot_override_duty_cycle.attr, 2621e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_prochot_short.attr, 2622e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_vrdhot1.dev_attr.attr, 2623e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &sensor_dev_attr_vrdhot2.dev_attr.attr, 2624e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_gpio.attr, 2625e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch &dev_attr_alarms.attr, 2626e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch NULL 2627e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 2628e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2629e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic struct attribute_group lm93_attr_grp = { 2630e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch .attrs = lm93_attrs, 2631e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 2632e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2633e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic void lm93_init_client(struct i2c_client *client) 2634e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2635e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch int i; 2636e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch u8 reg; 2637e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2638e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* configure VID pin input thresholds */ 2639e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_GPI_VID_CTL); 2640e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_GPI_VID_CTL, 2641e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg | (vid_agtl ? 0x03 : 0x00)); 2642e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2643e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (init) { 2644e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* enable #ALERT pin */ 2645e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_CONFIG); 2646e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x08); 2647e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2648e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* enable ASF mode for BMC status registers */ 2649e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_STATUS_CONTROL); 2650e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_STATUS_CONTROL, reg | 0x02); 2651e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2652e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* set sleep state to S0 */ 2653e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_SLEEP_CONTROL, 0); 2654e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2655e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* unmask #VRDHOT and dynamic VCCP (if nec) error events */ 2656e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_MISC_ERR_MASK); 2657e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg &= ~0x03; 2658e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg &= ~(vccp_limit_type[0] ? 0x10 : 0); 2659e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg &= ~(vccp_limit_type[1] ? 0x20 : 0); 2660e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_MISC_ERR_MASK, reg); 2661e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 2662e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2663e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* start monitoring */ 2664e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch reg = lm93_read_byte(client, LM93_REG_CONFIG); 2665e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_write_byte(client, LM93_REG_CONFIG, reg | 0x01); 2666e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2667e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* spin until ready */ 26682804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck for (i = 0; i < 20; i++) { 2669e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch msleep(10); 2670e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if ((lm93_read_byte(client, LM93_REG_CONFIG) & 0x80) == 0x80) 2671e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return; 2672e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 2673e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 26742804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_warn(&client->dev, "timed out waiting for sensor " 2675e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch "chip to signal ready!\n"); 2676e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2677e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 267870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare/* Return 0 if detection is successful, -ENODEV otherwise */ 2679310ec79210d754afe51e2e4a983e846b60179abdJean Delvarestatic int lm93_detect(struct i2c_client *client, struct i2c_board_info *info) 2680e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 268170b724063f789a443aff1e1a6f0f04d971342116Jean Delvare struct i2c_adapter *adapter = client->adapter; 268252df6440a29123eed912183fe785bbe174ef14b9Jean Delvare int mfr, ver; 2683c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck const char *name; 2684e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 268570b724063f789a443aff1e1a6f0f04d971342116Jean Delvare if (!i2c_check_functionality(adapter, LM93_SMBUS_FUNC_MIN)) 268670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare return -ENODEV; 2687e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2688e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* detection */ 268952df6440a29123eed912183fe785bbe174ef14b9Jean Delvare mfr = lm93_read_byte(client, LM93_REG_MFR_ID); 269052df6440a29123eed912183fe785bbe174ef14b9Jean Delvare if (mfr != 0x01) { 269152df6440a29123eed912183fe785bbe174ef14b9Jean Delvare dev_dbg(&adapter->dev, 269252df6440a29123eed912183fe785bbe174ef14b9Jean Delvare "detect failed, bad manufacturer id 0x%02x!\n", mfr); 269352df6440a29123eed912183fe785bbe174ef14b9Jean Delvare return -ENODEV; 2694e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 2695e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 269652df6440a29123eed912183fe785bbe174ef14b9Jean Delvare ver = lm93_read_byte(client, LM93_REG_VER); 2697c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck switch (ver) { 2698c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck case LM93_MFR_ID: 2699c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck case LM93_MFR_ID_PROTOTYPE: 2700c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck name = "lm93"; 2701c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck break; 2702c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck case LM94_MFR_ID_2: 2703c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck case LM94_MFR_ID: 2704c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck case LM94_MFR_ID_PROTOTYPE: 2705c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck name = "lm94"; 2706c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck break; 2707c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck default: 270852df6440a29123eed912183fe785bbe174ef14b9Jean Delvare dev_dbg(&adapter->dev, 270952df6440a29123eed912183fe785bbe174ef14b9Jean Delvare "detect failed, bad version id 0x%02x!\n", ver); 271052df6440a29123eed912183fe785bbe174ef14b9Jean Delvare return -ENODEV; 2711e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch } 2712e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2713c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck strlcpy(info->type, name, I2C_NAME_SIZE); 27142804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck dev_dbg(&adapter->dev, "loading %s at %d, 0x%02x\n", 2715e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch client->name, i2c_adapter_id(client->adapter), 2716e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch client->addr); 2717e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 271870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare return 0; 271970b724063f789a443aff1e1a6f0f04d971342116Jean Delvare} 272070b724063f789a443aff1e1a6f0f04d971342116Jean Delvare 272170b724063f789a443aff1e1a6f0f04d971342116Jean Delvarestatic int lm93_probe(struct i2c_client *client, 272270b724063f789a443aff1e1a6f0f04d971342116Jean Delvare const struct i2c_device_id *id) 272370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare{ 272470b724063f789a443aff1e1a6f0f04d971342116Jean Delvare struct lm93_data *data; 272570b724063f789a443aff1e1a6f0f04d971342116Jean Delvare int err, func; 272670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare void (*update)(struct lm93_data *, struct i2c_client *); 272770b724063f789a443aff1e1a6f0f04d971342116Jean Delvare 272870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare /* choose update routine based on bus capabilities */ 272970b724063f789a443aff1e1a6f0f04d971342116Jean Delvare func = i2c_get_functionality(client->adapter); 273070b724063f789a443aff1e1a6f0f04d971342116Jean Delvare if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) && 273170b724063f789a443aff1e1a6f0f04d971342116Jean Delvare (!disable_block)) { 273270b724063f789a443aff1e1a6f0f04d971342116Jean Delvare dev_dbg(&client->dev, "using SMBus block data transactions\n"); 273370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare update = lm93_update_client_full; 273470b724063f789a443aff1e1a6f0f04d971342116Jean Delvare } else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) { 273570b724063f789a443aff1e1a6f0f04d971342116Jean Delvare dev_dbg(&client->dev, "disabled SMBus block data " 273670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare "transactions\n"); 273770b724063f789a443aff1e1a6f0f04d971342116Jean Delvare update = lm93_update_client_min; 273870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare } else { 273970b724063f789a443aff1e1a6f0f04d971342116Jean Delvare dev_dbg(&client->dev, "detect failed, " 274070b724063f789a443aff1e1a6f0f04d971342116Jean Delvare "smbus byte and/or word data not supported!\n"); 274170b724063f789a443aff1e1a6f0f04d971342116Jean Delvare err = -ENODEV; 274270b724063f789a443aff1e1a6f0f04d971342116Jean Delvare goto err_out; 274370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare } 274470b724063f789a443aff1e1a6f0f04d971342116Jean Delvare 274570b724063f789a443aff1e1a6f0f04d971342116Jean Delvare data = kzalloc(sizeof(struct lm93_data), GFP_KERNEL); 274670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare if (!data) { 274770b724063f789a443aff1e1a6f0f04d971342116Jean Delvare dev_dbg(&client->dev, "out of memory!\n"); 274870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare err = -ENOMEM; 274970b724063f789a443aff1e1a6f0f04d971342116Jean Delvare goto err_out; 275070b724063f789a443aff1e1a6f0f04d971342116Jean Delvare } 275170b724063f789a443aff1e1a6f0f04d971342116Jean Delvare i2c_set_clientdata(client, data); 275270b724063f789a443aff1e1a6f0f04d971342116Jean Delvare 2753e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* housekeeping */ 2754e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->valid = 0; 2755e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch data->update = update; 2756e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch mutex_init(&data->update_lock); 2757e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2758e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* initialize the chip */ 2759e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch lm93_init_client(client); 2760e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2761e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp); 2762e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch if (err) 276370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare goto err_free; 2764e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2765e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch /* Register hwmon driver class */ 27661beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones data->hwmon_dev = hwmon_device_register(&client->dev); 27672804a4cfcdef5f0d4f412b31ab9d4a4a9aa3057aGuenter Roeck if (!IS_ERR(data->hwmon_dev)) 2768e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return 0; 2769e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 27701beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones err = PTR_ERR(data->hwmon_dev); 2771e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch dev_err(&client->dev, "error registering hwmon device.\n"); 2772e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); 2773e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kocherr_free: 2774e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch kfree(data); 2775e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kocherr_out: 2776e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch return err; 2777e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2778e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 277970b724063f789a443aff1e1a6f0f04d971342116Jean Delvarestatic int lm93_remove(struct i2c_client *client) 2780e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch{ 2781e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch struct lm93_data *data = i2c_get_clientdata(client); 2782e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 27831beeffe43311f64df8dd0ab08ff6b1858c58363fTony Jones hwmon_device_unregister(data->hwmon_dev); 2784e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp); 2785e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 278670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare kfree(data); 278770b724063f789a443aff1e1a6f0f04d971342116Jean Delvare return 0; 2788e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch} 2789e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 279070b724063f789a443aff1e1a6f0f04d971342116Jean Delvarestatic const struct i2c_device_id lm93_id[] = { 27911f86df49ddfd0067cce941187d57b2fd2f749a9eJean Delvare { "lm93", 0 }, 2792c7bf71c517abfc3b15970d67910e0f62e0522939Guenter Roeck { "lm94", 0 }, 279370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare { } 279470b724063f789a443aff1e1a6f0f04d971342116Jean Delvare}; 279570b724063f789a443aff1e1a6f0f04d971342116Jean DelvareMODULE_DEVICE_TABLE(i2c, lm93_id); 279670b724063f789a443aff1e1a6f0f04d971342116Jean Delvare 2797e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Kochstatic struct i2c_driver lm93_driver = { 279870b724063f789a443aff1e1a6f0f04d971342116Jean Delvare .class = I2C_CLASS_HWMON, 2799e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch .driver = { 2800e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch .name = "lm93", 2801e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch }, 280270b724063f789a443aff1e1a6f0f04d971342116Jean Delvare .probe = lm93_probe, 280370b724063f789a443aff1e1a6f0f04d971342116Jean Delvare .remove = lm93_remove, 280470b724063f789a443aff1e1a6f0f04d971342116Jean Delvare .id_table = lm93_id, 280570b724063f789a443aff1e1a6f0f04d971342116Jean Delvare .detect = lm93_detect, 2806c3813d6af177fab19e322f3114b1f64fbcf08d71Jean Delvare .address_list = normal_i2c, 2807e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch}; 2808e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2809f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm93_driver); 2810e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen Koch 2811e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>, " 28122aa25c22c445df63b5961883f28767643122f935Hans J. Koch "Hans J. Koch <hjk@hansjkoch.de>"); 2813e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_DESCRIPTION("LM93 driver"); 2814e46957edfb85e3054ed49350777833e18564c9ffHans-Jürgen KochMODULE_LICENSE("GPL"); 2815