Backport ADT7461 support from Linux 2.6.

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@2954 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2005-03-27 13:34:47 +00:00
1 parent 09804db12d
commit 4d165ff285
1 file changed
+59 -7
+59 -7
View File
@@ -43,6 +43,14 @@
* variants. The extra address and features of the MAX6659 are not
* supported by this driver.
*
* This driver also supports the ADT7461 chip from Analog Devices but
* only in its "compatability mode". If an ADT7461 chip is found but
* is configured in non-compatible mode (where its temperature
* register values are decoded differently) it is ignored by this
* driver. Complete datasheet can be obtained from Analog's website
* at:
* http://products.analog.com/products/info.asp?product=ADT7461
*
* Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and
* concern all supported chipsets, unless mentioned otherwise.
@@ -80,6 +88,7 @@
* LM86, LM89, LM90, LM99, ADM1032, MAX6657 and MAX6658 have address 0x4c.
* LM89-1, and LM99-1 have address 0x4d.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
* ADT7461 always has address 0x4c.
*/
static unsigned short normal_i2c[] = { 0x4c, 0x4d, SENSORS_I2C_END };
@@ -91,7 +100,7 @@ static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
* Insmod parameters
*/
SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657);
SENSORS_INSMOD_6(lm90, adm1032, lm99, lm86, max6657, adt7461);
/*
* The LM90 registers
@@ -150,6 +159,18 @@ SENSORS_INSMOD_5(lm90, adm1032, lm99, lm86, max6657);
#define HYST_TO_REG(val) ((val) <= 0 ? 0 : \
(val) >= 31 ? 31 : (val))
/*
* ADT7461 is almost identical to LM90 except that attempts to write
* values that are outside the range 0 < temp < 127 are treated as
* the boundary value.
*/
#define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
(val) >= 127 ? 127 : (val))
#define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
(val) >= 1277 ? 0x7FC0 : \
((val) * 100 / 250 * 64))
/*
* Functions declaration
*/
@@ -198,6 +219,7 @@ struct lm90_data
struct semaphore update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
int kind;
/* registers values */
s8 local_temp, local_high, local_low;
@@ -366,6 +388,12 @@ static int lm90_detect(struct i2c_adapter *adapter, int address,
&& (reg_config1 & 0x3F) == 0x00
&& reg_convrate <= 0x0A)
kind = adm1032;
else
if (address == 0x4c
&& chip_id == 0x51 /* ADT7461 */
&& (reg_config1 & 0x1F) == 0x00 /* check compat mode */
&& reg_convrate <= 0x0A)
kind = adt7461;
}
else if (man_id == 0x4D) /* Maxim */
{
@@ -416,6 +444,11 @@ static int lm90_detect(struct i2c_adapter *adapter, int address,
type_name = "max6657";
client_name = "MAX6657 chip";
}
else if (kind == adt7461)
{
type_name = "adt7461";
client_name = "ADT7561 chip";
}
else
{
printk("lm90.o: Unknown kind %d.\n", kind);
@@ -429,6 +462,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address,
strcpy(new_client->name, client_name);
data->valid = 0;
data->kind = kind;
init_MUTEX(&data->update_lock);
/*
@@ -600,13 +634,19 @@ static void lm90_local_temp(struct i2c_client *client, int operation,
{
if (*nrels_mag >= 1)
{
data->local_high = TEMP1_TO_REG(results[0]);
if (data->kind == adt7461)
data->local_high = TEMP1_TO_REG_ADT7461(results[0]);
else
data->local_high = TEMP1_TO_REG(results[0]);
i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_HIGH,
data->local_high);
}
if (*nrels_mag >= 2)
{
data->local_low = TEMP1_TO_REG(results[1]);
if (data->kind == adt7461)
data->local_low = TEMP1_TO_REG_ADT7461(results[1]);
else
data->local_low = TEMP1_TO_REG(results[1]);
i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_LOW,
data->local_low);
}
@@ -632,7 +672,10 @@ static void lm90_remote_temp(struct i2c_client *client, int operation,
{
if (*nrels_mag >= 1)
{
data->remote_high = TEMP2_TO_REG(results[0]);
if (data->kind == adt7461)
data->remote_high = TEMP2_TO_REG_ADT7461(results[0]);
else
data->remote_high = TEMP2_TO_REG(results[0]);
i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_HIGHH,
data->remote_high >> 8);
i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_HIGHL,
@@ -640,7 +683,10 @@ static void lm90_remote_temp(struct i2c_client *client, int operation,
}
if (*nrels_mag >= 2)
{
data->remote_low = TEMP2_TO_REG(results[1]);
if (data->kind == adt7461)
data->remote_low = TEMP2_TO_REG_ADT7461(results[1]);
else
data->remote_low = TEMP2_TO_REG(results[1]);
i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_LOWH,
data->remote_low >> 8);
i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_LOWL,
@@ -666,7 +712,10 @@ static void lm90_local_tcrit(struct i2c_client *client, int operation,
{
if (*nrels_mag >= 1)
{
data->local_crit = TEMP1_TO_REG(results[0]);
if (data->kind == adt7461)
data->local_crit = TEMP1_TO_REG_ADT7461(results[0]);
else
data->local_crit = TEMP1_TO_REG(results[0]);
i2c_smbus_write_byte_data(client, LM90_REG_W_LOCAL_CRIT,
data->local_crit);
}
@@ -690,7 +739,10 @@ static void lm90_remote_tcrit(struct i2c_client *client, int operation,
{
if (*nrels_mag >= 1)
{
data->remote_crit = TEMP1_TO_REG(results[0]);
if (data->kind == adt7461)
data->remote_crit = TEMP1_TO_REG_ADT7461(results[0]);
else
data->remote_crit = TEMP1_TO_REG(results[0]);
i2c_smbus_write_byte_data(client, LM90_REG_W_REMOTE_CRIT,
data->remote_crit);
}