diff --git a/kernel/chips/lm75.c b/kernel/chips/lm75.c index 0fc8d0a8..2a7a75cd 100644 --- a/kernel/chips/lm75.c +++ b/kernel/chips/lm75.c @@ -24,6 +24,7 @@ #include #include #include "version.h" +#include "lm75.h" /* Addresses to scan */ static unsigned short normal_i2c[] = { SENSORS_I2C_END }; @@ -42,13 +43,6 @@ SENSORS_INSMOD_1(lm75); #define LM75_REG_TEMP_HYST 0x02 #define LM75_REG_TEMP_OS 0x03 -/* Conversions. Rounding and limit checking is only done on the TO_REG - variants. Note that you should be a bit careful with which arguments - these macros are called: arguments may be evaluated more than once. - Fixing this is just not worth it. */ -#define TEMP_FROM_REG(val) ((((val & 0x7fff) >> 7) * 5) | ((val & 0x8000)?-256:0)) -#define TEMP_TO_REG(val) (SENSORS_LIMIT((val<0?(0x200+((val)/5))<<7:(((val) + 2) / 5) << 7),0,0xffff)) - /* Each client has this additional data */ struct lm75_data { int sysctl_id; @@ -288,18 +282,18 @@ void lm75_temp(struct i2c_client *client, int operation, int ctl_name, *nrels_mag = 1; else if (operation == SENSORS_PROC_REAL_READ) { lm75_update_client(client); - results[0] = TEMP_FROM_REG(data->temp_os); - results[1] = TEMP_FROM_REG(data->temp_hyst); - results[2] = TEMP_FROM_REG(data->temp); + results[0] = LM75_TEMP_FROM_REG(data->temp_os); + results[1] = LM75_TEMP_FROM_REG(data->temp_hyst); + results[2] = LM75_TEMP_FROM_REG(data->temp); *nrels_mag = 3; } else if (operation == SENSORS_PROC_REAL_WRITE) { if (*nrels_mag >= 1) { - data->temp_os = TEMP_TO_REG(results[0]); + data->temp_os = LM75_TEMP_TO_REG(results[0]); lm75_write_value(client, LM75_REG_TEMP_OS, data->temp_os); } if (*nrels_mag >= 2) { - data->temp_hyst = TEMP_TO_REG(results[1]); + data->temp_hyst = LM75_TEMP_TO_REG(results[1]); lm75_write_value(client, LM75_REG_TEMP_HYST, data->temp_hyst); } diff --git a/kernel/chips/lm75.h b/kernel/chips/lm75.h new file mode 100644 index 00000000..2180f976 --- /dev/null +++ b/kernel/chips/lm75.h @@ -0,0 +1,49 @@ +/* + lm75.h - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (c) 2003 Mark M. Hoffman + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + This file contains common code for encoding/decoding LM75 type + temperature readings, which are emulated by many of the chips + we support. As the user is unlikely to load more than one driver + which contains this code, we don't worry about the wasted space. +*/ + +#include + +/* straight from the datasheet */ +#define LM75_TEMP_MIN (-550) +#define LM75_TEMP_MAX 1250 + +/* TEMP: 0.1C/bit (-55C to +125C) + REG: (0.5C/bit, two's complement) << 7 */ +static inline u16 LM75_TEMP_TO_REG(int temp) +{ + int ntemp = SENSORS_LIMIT(temp, LM75_TEMP_MIN, LM75_TEMP_MAX); + ntemp += (ntemp<0 ? -2 : 2); + return (u16)((ntemp / 5) << 7); +} + +static inline int LM75_TEMP_FROM_REG(u16 reg) +{ + /* use integer division instead of equivalent right shift to + guarantee arithmetic shift and preserve the sign */ + return ((s16)reg / 128) * 5; +} +