1fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* 2fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * Copyright (C) 2011 Alexander Stein <alexander.stein@systec-electronic.com> 3fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * 4fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * The LM95245 is a sensor chip made by National Semiconductors. 5fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * It reports up to two temperatures (its own plus an external one). 6fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * Complete datasheet can be obtained from National's website at: 7fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * http://www.national.com/ds.cgi/LM/LM95245.pdf 8fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * 9fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * This driver is based on lm95241.c 10fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * 11fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * This program is free software; you can redistribute it and/or modify 12fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * it under the terms of the GNU General Public License as published by 13fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * the Free Software Foundation; either version 2 of the License, or 14fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * (at your option) any later version. 15fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * 16fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * This program is distributed in the hope that it will be useful, 17fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * but WITHOUT ANY WARRANTY; without even the implied warranty of 18fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * GNU General Public License for more details. 20fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * 21fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * You should have received a copy of the GNU General Public License 22fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * along with this program; if not, write to the Free Software 23fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein */ 25fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 26fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/module.h> 27fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/init.h> 28fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/slab.h> 29fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/jiffies.h> 30fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/i2c.h> 31fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/hwmon.h> 32fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/hwmon-sysfs.h> 33fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/err.h> 34fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/mutex.h> 35fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#include <linux/sysfs.h> 36fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 37fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define DEVNAME "lm95245" 38fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 39fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic const unsigned short normal_i2c[] = { 40fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 0x18, 0x19, 0x29, 0x4c, 0x4d, I2C_CLIENT_END }; 41fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 42fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* LM95245 registers */ 43fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* general registers */ 44fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_CONFIG1 0x03 45fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_CONVERS_RATE 0x04 46fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_W_ONE_SHOT 0x0F 47fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 48fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* diode configuration */ 49fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_CONFIG2 0xBF 50fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_REMOTE_OFFH 0x11 51fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_REMOTE_OFFL 0x12 52fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 53fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* status registers */ 54fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_STATUS1 0x02 55fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_STATUS2 0x33 56fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 57fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* limit registers */ 58fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_REMOTE_OS_LIMIT 0x07 59fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT 0x20 60fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_REMOTE_TCRIT_LIMIT 0x19 61fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_RW_COMMON_HYSTERESIS 0x21 62fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 63fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* temperature signed */ 64fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_LOCAL_TEMPH_S 0x00 65fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_LOCAL_TEMPL_S 0x30 66fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_REMOTE_TEMPH_S 0x01 67fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_REMOTE_TEMPL_S 0x10 68fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* temperature unsigned */ 69fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_REMOTE_TEMPH_U 0x31 70fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_REMOTE_TEMPL_U 0x32 71fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 72fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* id registers */ 73fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_MAN_ID 0xFE 74fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define LM95245_REG_R_CHIP_ID 0xFF 75fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 76fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* LM95245 specific bitfields */ 77fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG_STOP 0x40 78fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG_REMOTE_TCRIT_MASK 0x10 79fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG_REMOTE_OS_MASK 0x08 80fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG_LOCAL_TCRIT_MASK 0x04 81fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG_LOCAL_OS_MASK 0x02 82fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 83fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_OS_A0 0x40 84fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_DIODE_FAULT_OS 0x20 85fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_DIODE_FAULT_TCRIT 0x10 86fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_REMOTE_TT 0x08 87fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_REMOTE_FILTER_DIS 0x00 88fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define CFG2_REMOTE_FILTER_EN 0x06 89fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 90fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* conversation rate in ms */ 91fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define RATE_CR0063 0x00 92fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define RATE_CR0364 0x01 93fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define RATE_CR1000 0x02 94fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define RATE_CR2500 0x03 95fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 96fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define STATUS1_DIODE_FAULT 0x04 97fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define STATUS1_RTCRIT 0x02 98fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define STATUS1_LOC 0x01 99fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 100fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define MANUFACTURER_ID 0x01 101fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein#define DEFAULT_REVISION 0xB3 102fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 103fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic const u8 lm95245_reg_address[] = { 104fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_LOCAL_TEMPH_S, 105fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_LOCAL_TEMPL_S, 106fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_REMOTE_TEMPH_S, 107fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_REMOTE_TEMPL_S, 108fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_REMOTE_TEMPH_U, 109fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_REMOTE_TEMPL_U, 110fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_RW_LOCAL_OS_TCRIT_LIMIT, 111fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_RW_REMOTE_TCRIT_LIMIT, 112fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_RW_COMMON_HYSTERESIS, 113fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_R_STATUS1, 114fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein}; 115fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 116fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* Client data (each client gets its own) */ 117fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstruct lm95245_data { 1187276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client; 119fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct mutex update_lock; 120fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long last_updated; /* in jiffies */ 121fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long interval; /* in msecs */ 122fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein bool valid; /* zero until following fields are valid */ 123fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein /* registers values */ 124fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein u8 regs[ARRAY_SIZE(lm95245_reg_address)]; 125fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein u8 config1, config2; 126fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein}; 127fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 128fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* Conversions */ 129fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic int temp_from_reg_unsigned(u8 val_h, u8 val_l) 130fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 131fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return val_h * 1000 + val_l * 1000 / 256; 132fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 133fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 134fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic int temp_from_reg_signed(u8 val_h, u8 val_l) 135fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 136fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (val_h & 0x80) 137fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return (val_h - 0x100) * 1000; 138fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return temp_from_reg_unsigned(val_h, val_l); 139fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 140fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 141fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic struct lm95245_data *lm95245_update_device(struct device *dev) 142fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 1437276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 1447276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client = data->client; 145fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 146fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_lock(&data->update_lock); 147fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 148fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (time_after(jiffies, data->last_updated 149fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein + msecs_to_jiffies(data->interval)) || !data->valid) { 150fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int i; 151fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 152fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein for (i = 0; i < ARRAY_SIZE(lm95245_reg_address); i++) 153fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->regs[i] 154fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein = i2c_smbus_read_byte_data(client, 155fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein lm95245_reg_address[i]); 156fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->last_updated = jiffies; 157fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->valid = 1; 158fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } 159fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 160fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_unlock(&data->update_lock); 161fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 162fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return data; 163fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 164fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 165fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic unsigned long lm95245_read_conversion_rate(struct i2c_client *client) 166fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 167fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int rate; 168fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long interval; 169fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 170fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein rate = i2c_smbus_read_byte_data(client, LM95245_REG_RW_CONVERS_RATE); 171fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 172fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein switch (rate) { 173fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein case RATE_CR0063: 174fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 63; 175fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein break; 176fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein case RATE_CR0364: 177fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 364; 178fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein break; 179fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein case RATE_CR1000: 180fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 1000; 181fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein break; 182fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein case RATE_CR2500: 183fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein default: 184fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 2500; 185fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein break; 186fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } 187fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 188fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return interval; 189fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 190fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 191fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic unsigned long lm95245_set_conversion_rate(struct i2c_client *client, 192fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long interval) 193fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 194fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int rate; 195fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 196fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (interval <= 63) { 197fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 63; 198fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein rate = RATE_CR0063; 199fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } else if (interval <= 364) { 200fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 364; 201fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein rate = RATE_CR0364; 202fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } else if (interval <= 1000) { 203fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 1000; 204fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein rate = RATE_CR1000; 205fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } else { 206fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein interval = 2500; 207fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein rate = RATE_CR2500; 208fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } 209fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 210fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONVERS_RATE, rate); 211fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 212fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return interval; 213fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 214fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 215fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* Sysfs stuff */ 216fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t show_input(struct device *dev, struct device_attribute *attr, 217fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein char *buf) 218fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 219fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct lm95245_data *data = lm95245_update_device(dev); 220fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int temp; 221fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int index = to_sensor_dev_attr(attr)->index; 222fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 223fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein /* 224fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * Index 0 (Local temp) is always signed 225fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * Index 2 (Remote temp) has both signed and unsigned data 226fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein * use signed calculation for remote if signed bit is set 227fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein */ 228fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (index == 0 || data->regs[index] & 0x80) 229fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein temp = temp_from_reg_signed(data->regs[index], 230fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->regs[index + 1]); 231fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein else 232fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein temp = temp_from_reg_unsigned(data->regs[index + 2], 233fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->regs[index + 3]); 234fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 235fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return snprintf(buf, PAGE_SIZE - 1, "%d\n", temp); 236fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 237fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 238fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t show_limit(struct device *dev, struct device_attribute *attr, 239fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein char *buf) 240fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 241fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct lm95245_data *data = lm95245_update_device(dev); 242fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int index = to_sensor_dev_attr(attr)->index; 243fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 244fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return snprintf(buf, PAGE_SIZE - 1, "%d\n", 245fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->regs[index] * 1000); 246fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 247fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 248fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t set_limit(struct device *dev, struct device_attribute *attr, 249fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein const char *buf, size_t count) 250fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 2517276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 252fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int index = to_sensor_dev_attr(attr)->index; 2537276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client = data->client; 254fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long val; 255fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 256179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks if (kstrtoul(buf, 10, &val) < 0) 257fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -EINVAL; 258fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 259fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein val /= 1000; 260fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 2612a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck val = clamp_val(val, 0, (index == 6 ? 127 : 255)); 262fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 263fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_lock(&data->update_lock); 264fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 265fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->valid = 0; 266fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 267fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein i2c_smbus_write_byte_data(client, lm95245_reg_address[index], val); 268fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 269fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_unlock(&data->update_lock); 270fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 271fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return count; 272fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 273fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 274408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeckstatic ssize_t show_crit_hyst(struct device *dev, struct device_attribute *attr, 275408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck char *buf) 276408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck{ 277408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck struct lm95245_data *data = lm95245_update_device(dev); 278408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck int index = to_sensor_dev_attr(attr)->index; 279408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck int hyst = data->regs[index] - data->regs[8]; 280408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck 281408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck return snprintf(buf, PAGE_SIZE - 1, "%d\n", hyst * 1000); 282408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck} 283408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck 284fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t set_crit_hyst(struct device *dev, struct device_attribute *attr, 285fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein const char *buf, size_t count) 286fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 2877276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 288408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck int index = to_sensor_dev_attr(attr)->index; 2897276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client = data->client; 290fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long val; 291408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck int hyst, limit; 292fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 293179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks if (kstrtoul(buf, 10, &val) < 0) 294fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -EINVAL; 295fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 296fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_lock(&data->update_lock); 297fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 298408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck limit = i2c_smbus_read_byte_data(client, lm95245_reg_address[index]); 299408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck hyst = limit - val / 1000; 300408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck hyst = clamp_val(hyst, 0, 31); 301408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck data->regs[8] = hyst; 302fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 303fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein /* shared crit hysteresis */ 304fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein i2c_smbus_write_byte_data(client, LM95245_REG_RW_COMMON_HYSTERESIS, 305408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck hyst); 306fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 307fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_unlock(&data->update_lock); 308fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 309fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return count; 310fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 311fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 312fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t show_type(struct device *dev, struct device_attribute *attr, 313fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein char *buf) 314fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 3157276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 316fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 317fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return snprintf(buf, PAGE_SIZE - 1, 318fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config2 & CFG2_REMOTE_TT ? "1\n" : "2\n"); 319fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 320fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 321fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t set_type(struct device *dev, struct device_attribute *attr, 322fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein const char *buf, size_t count) 323fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 3247276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 3257276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client = data->client; 326fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long val; 327fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 328179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks if (kstrtoul(buf, 10, &val) < 0) 329fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -EINVAL; 330fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (val != 1 && val != 2) 331fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -EINVAL; 332fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 333fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_lock(&data->update_lock); 334fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 335fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (val == 1) 336fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config2 |= CFG2_REMOTE_TT; 337fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein else 338fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config2 &= ~CFG2_REMOTE_TT; 339fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 340fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->valid = 0; 341fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 342fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONFIG2, 343fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config2); 344fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 345fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_unlock(&data->update_lock); 346fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 347fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return count; 348fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 349fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 350fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr, 351fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein char *buf) 352fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 353fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct lm95245_data *data = lm95245_update_device(dev); 354fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein int index = to_sensor_dev_attr(attr)->index; 355fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 356fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return snprintf(buf, PAGE_SIZE - 1, "%d\n", 357fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein !!(data->regs[9] & index)); 358fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 359fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 360fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t show_interval(struct device *dev, struct device_attribute *attr, 361fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein char *buf) 362fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 363fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct lm95245_data *data = lm95245_update_device(dev); 364fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 365fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return snprintf(buf, PAGE_SIZE - 1, "%lu\n", data->interval); 366fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 367fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 368fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic ssize_t set_interval(struct device *dev, struct device_attribute *attr, 369fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein const char *buf, size_t count) 370fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 3717276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data = dev_get_drvdata(dev); 3727276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct i2c_client *client = data->client; 373fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein unsigned long val; 374fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 375179c4fdb565dd2157e5dfe89318b74868e3b523dFrans Meulenbroeks if (kstrtoul(buf, 10, &val) < 0) 376fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -EINVAL; 377fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 378fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_lock(&data->update_lock); 379fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 380fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->interval = lm95245_set_conversion_rate(client, val); 381fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 382fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_unlock(&data->update_lock); 383fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 384fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return count; 385fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 386fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 387fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0); 388fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_limit, 389fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein set_limit, 6); 390408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeckstatic SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_crit_hyst, 391408c15eaca71ab01b7fb30a271687c6cc5dc4d8eGuenter Roeck set_crit_hyst, 6); 392fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL, 393fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein STATUS1_LOC); 394fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 395fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2); 396fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_limit, 397fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein set_limit, 7); 398a41a8927e7adfa5de607d5bd43fa8fbbef44d6f2Guenter Roeckstatic SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_crit_hyst, NULL, 7); 399fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp2_crit_alarm, S_IRUGO, show_alarm, NULL, 400fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein STATUS1_RTCRIT); 401fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, 402fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein set_type, 0); 403fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 404fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein STATUS1_DIODE_FAULT); 405fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 406fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, 407fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein set_interval); 408fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4097276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeckstatic struct attribute *lm95245_attrs[] = { 410fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp1_input.dev_attr.attr, 411fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp1_crit.dev_attr.attr, 412fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, 413fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr, 414fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_input.dev_attr.attr, 415fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_crit.dev_attr.attr, 416fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_crit_hyst.dev_attr.attr, 417fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr, 418fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_type.dev_attr.attr, 419fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &sensor_dev_attr_temp2_fault.dev_attr.attr, 420fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein &dev_attr_update_interval.attr, 421fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein NULL 422fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein}; 4237276d55e62f79f2b81d2c414e48de43edea5aa78Guenter RoeckATTRIBUTE_GROUPS(lm95245); 424fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 425fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* Return 0 if detection is successful, -ENODEV otherwise */ 426fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic int lm95245_detect(struct i2c_client *new_client, 427fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct i2c_board_info *info) 428fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 429fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct i2c_adapter *adapter = new_client->adapter; 430fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 431fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 432fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -ENODEV; 433fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 434fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (i2c_smbus_read_byte_data(new_client, LM95245_REG_R_MAN_ID) 435fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein != MANUFACTURER_ID 436fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein || i2c_smbus_read_byte_data(new_client, LM95245_REG_R_CHIP_ID) 437fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein != DEFAULT_REVISION) 438fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return -ENODEV; 439fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 440fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein strlcpy(info->type, DEVNAME, I2C_NAME_SIZE); 441fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein return 0; 442fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 443fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4447276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeckstatic void lm95245_init_client(struct i2c_client *client, 4457276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct lm95245_data *data) 446fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 447fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->interval = lm95245_read_conversion_rate(client); 448fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 449fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config1 = i2c_smbus_read_byte_data(client, 450fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_RW_CONFIG1); 451fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config2 = i2c_smbus_read_byte_data(client, 452fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein LM95245_REG_RW_CONFIG2); 453fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 454fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein if (data->config1 & CFG_STOP) { 455fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein /* Clear the standby bit */ 456fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config1 &= ~CFG_STOP; 457fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein i2c_smbus_write_byte_data(client, LM95245_REG_RW_CONFIG1, 458fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein data->config1); 459fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein } 460fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 461fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4627276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeckstatic int lm95245_probe(struct i2c_client *client, 463fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein const struct i2c_device_id *id) 464fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein{ 4657276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct device *dev = &client->dev; 466fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein struct lm95245_data *data; 4677276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck struct device *hwmon_dev; 468fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4697276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck data = devm_kzalloc(dev, sizeof(struct lm95245_data), GFP_KERNEL); 470a8dd946c420781fd7a70fec8b75e0daf67c4a681Guenter Roeck if (!data) 471a8dd946c420781fd7a70fec8b75e0daf67c4a681Guenter Roeck return -ENOMEM; 472fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4737276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck data->client = client; 474fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein mutex_init(&data->update_lock); 475fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 476fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein /* Initialize the LM95245 chip */ 4777276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck lm95245_init_client(client, data); 478fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 4797276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 4807276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck data, 4817276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck lm95245_groups); 4827276d55e62f79f2b81d2c414e48de43edea5aa78Guenter Roeck return PTR_ERR_OR_ZERO(hwmon_dev); 483fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein} 484fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 485fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein/* Driver data (common to all clients) */ 486fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic const struct i2c_device_id lm95245_id[] = { 487fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein { DEVNAME, 0 }, 488fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein { } 489fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein}; 490fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander SteinMODULE_DEVICE_TABLE(i2c, lm95245_id); 491fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 492fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Steinstatic struct i2c_driver lm95245_driver = { 493fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .class = I2C_CLASS_HWMON, 494fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .driver = { 495fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .name = DEVNAME, 496fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein }, 497fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .probe = lm95245_probe, 498fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .id_table = lm95245_id, 499fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .detect = lm95245_detect, 500fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein .address_list = normal_i2c, 501fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein}; 502fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 503f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm95245_driver); 504fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander Stein 505fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander SteinMODULE_AUTHOR("Alexander Stein <alexander.stein@systec-electronic.com>"); 506fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander SteinMODULE_DESCRIPTION("LM95245 sensor driver"); 507fffd80ccc1e6c7e5f13741e17a7d80582ae21fccAlexander SteinMODULE_LICENSE("GPL"); 508