[PATCH] I2C: add EMC6D100 support in lm85 driver

From: Greg KH
Date: Mon Jan 17 2005 - 17:16:45 EST


ChangeSet 1.2329.2.8, 2005/01/14 14:43:50-08:00, rafael.espindola@xxxxxxxxx

[PATCH] I2C: add EMC6D100 support in lm85 driver

I have ported the support for the EMC6D100 sensor from kernel 2.4 to kernel
2.6. In the process I received some comments from Jean Delvare.

Signed-off-by: Rafael �vila de Espíndola <rafael.espindola@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <greg@xxxxxxxxx>


drivers/i2c/chips/lm85.c | 76 ++++++++++++++++++++++++++++++++++++++---------
1 files changed, 62 insertions(+), 14 deletions(-)


diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c 2005-01-17 13:20:15 -08:00
+++ b/drivers/i2c/chips/lm85.c 2005-01-17 13:20:15 -08:00
@@ -36,7 +36,7 @@
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };

/* Insmod parameters */
-SENSORS_INSMOD_4(lm85b, lm85c, adm1027, adt7463);
+SENSORS_INSMOD_5(lm85b, lm85c, adm1027, adt7463, emc6d100);

/* The LM85 registers */

@@ -66,11 +66,15 @@
#define LM85_DEVICE_ADX 0x27
#define LM85_COMPANY_NATIONAL 0x01
#define LM85_COMPANY_ANALOG_DEV 0x41
+#define LM85_COMPANY_SMSC 0x5c
+#define LM85_VERSTEP_VMASK 0xf0
#define LM85_VERSTEP_GENERIC 0x60
#define LM85_VERSTEP_LM85C 0x60
#define LM85_VERSTEP_LM85B 0x62
#define LM85_VERSTEP_ADM1027 0x60
#define LM85_VERSTEP_ADT7463 0x62
+#define LM85_VERSTEP_EMC6D100_A0 0x60
+#define LM85_VERSTEP_EMC6D100_A1 0x61

#define LM85_REG_CONFIG 0x40

@@ -105,6 +109,12 @@
#define ADT7463_REG_THERM 0x79
#define ADT7463_REG_THERM_LIMIT 0x7A

+#define EMC6D100_REG_ALARM3 0x7d
+/* IN5, IN6 and IN7 */
+#define EMC6D100_REG_IN(nr) (0x70 + ((nr)-5))
+#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr)-5) * 2)
+#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr)-5) * 2)
+
#define LM85_ALARM_IN0 0x0001
#define LM85_ALARM_IN1 0x0002
#define LM85_ALARM_IN2 0x0004
@@ -135,7 +145,8 @@

/* IN are scaled acording to built-in resistors */
static int lm85_scaling[] = { /* .001 Volts */
- 2500, 2250, 3300, 5000, 12000
+ 2500, 2250, 3300, 5000, 12000,
+ 3300, 1500, 1800 /*EMC6D100*/
};
#define SCALE(val,from,to) (((val)*(to) + ((from)/2))/(from))
#define INS_TO_REG(n,val) (SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
@@ -331,9 +342,9 @@
unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */

- u8 in[5]; /* Register value */
- u8 in_max[5]; /* Register value */
- u8 in_min[5]; /* Register value */
+ u8 in[8]; /* Register value */
+ u8 in_max[8]; /* Register value */
+ u8 in_min[8]; /* Register value */
s8 temp[3]; /* Register value */
s8 temp_min[3]; /* Register value */
s8 temp_max[3]; /* Register value */
@@ -353,7 +364,7 @@
u16 tmin_ctl; /* Register value */
unsigned long therm_total; /* Cummulative therm count */
u8 therm_limit; /* Register value */
- u16 alarms; /* Register encoding, combined */
+ u32 alarms; /* Register encoding, combined */
struct lm85_autofan autofan[3];
struct lm85_zone zone[3];
};
@@ -1072,7 +1083,7 @@
&& verstep == LM85_VERSTEP_LM85B ) {
kind = lm85b ;
} else if( company == LM85_COMPANY_NATIONAL
- && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
" Defaulting to LM85.\n", verstep);
kind = any_chip ;
@@ -1083,17 +1094,34 @@
&& verstep == LM85_VERSTEP_ADT7463 ) {
kind = adt7463 ;
} else if( company == LM85_COMPANY_ANALOG_DEV
- && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) {
+ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC ) {
dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
- " Defaulting to ADM1027.\n", verstep);
- kind = adm1027 ;
- } else if( kind == 0 && (verstep & 0xf0) == 0x60) {
+ " Defaulting to Generic LM85.\n", verstep );
+ kind = any_chip ;
+ } else if( company == LM85_COMPANY_SMSC
+ && (verstep == LM85_VERSTEP_EMC6D100_A0
+ || verstep == LM85_VERSTEP_EMC6D100_A1) ) {
+ /* Unfortunately, we can't tell a '100 from a '101
+ * from the registers. Since a '101 is a '100
+ * in a package with fewer pins and therefore no
+ * 3.3V, 1.5V or 1.8V inputs, perhaps if those
+ * inputs read 0, then it's a '101.
+ */
+ kind = emc6d100 ;
+ } else if( company == LM85_COMPANY_SMSC
+ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
+ dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
+ dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
+ " Defaulting to Generic LM85.\n", verstep );
+ kind = any_chip ;
+ } else if( kind == any_chip
+ && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
/* Leave kind as "any_chip" */
} else {
dev_dbg(&adapter->dev, "Autodetection failed\n");
/* Not an LM85 ... */
- if( kind == 0 ) { /* User used force=x,y */
+ if( kind == any_chip ) { /* User used force=x,y */
dev_err(&adapter->dev, "Generic LM85 Version 6 not"
" found at %d,0x%02x. Try force_lm85c.\n",
i2c_adapter_id(adapter), address );
@@ -1114,6 +1142,8 @@
type_name = "adm1027";
} else if ( kind == adt7463 ) {
type_name = "adt7463";
+ } else if ( kind == emc6d100){
+ type_name = "emc6d100";
}
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);

@@ -1365,15 +1395,24 @@
lm85_read_value(client, LM85_REG_PWM(i));
}

+ data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
+
if ( data->type == adt7463 ) {
if( data->therm_total < ULONG_MAX - 256 ) {
data->therm_total +=
lm85_read_value(client, ADT7463_REG_THERM );
}
+ } else if ( data->type == emc6d100 ) {
+ /* Three more voltage sensors */
+ for (i = 5; i <= 7; ++i) {
+ data->in[i] =
+ lm85_read_value(client, EMC6D100_REG_IN(i));
+ }
+ /* More alarm bits */
+ data->alarms |=
+ lm85_read_value(client, EMC6D100_REG_ALARM3) << 16;
}

- data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
data->last_reading = jiffies ;
}; /* last_reading */

@@ -1387,6 +1426,15 @@
lm85_read_value(client, LM85_REG_IN_MIN(i));
data->in_max[i] =
lm85_read_value(client, LM85_REG_IN_MAX(i));
+ }
+
+ if ( data->type == emc6d100 ) {
+ for (i = 5; i <= 7; ++i) {
+ data->in_min[i] =
+ lm85_read_value(client, EMC6D100_REG_IN_MIN(i));
+ data->in_max[i] =
+ lm85_read_value(client, EMC6D100_REG_IN_MAX(i));
+ }
}

for (i = 0; i <= 3; ++i) {

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/