diff --git a/doc/chips/adm1021 b/doc/chips/adm1021 index 9c8fb50c..ec4caf9c 100644 --- a/doc/chips/adm1021 +++ b/doc/chips/adm1021 @@ -1,3 +1,151 @@ +Kernel driver `adm1021.o' +========================= + +Status: Complete; tested for the ADM1021 and MAX1617, untested for the MAX1617A. + +Supported chips: + * Analog Devices ADM1021 + Prefix `adm1021' + Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e (inclusive) + Datasheet: Publicly available at the Analog Devices website + * Maxim MAX1617 + Prefix `max1617' + Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e (inclusive) + Datasheet: Publicly available at the Maxim website + * Maxim MAX1617A + Prefix `max1617a' + Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e (inclusive) + Datasheet: Publicly available at the Maxim website + + +Author: Frodo Looijaard and Philip Edelbrock + + + +Module Parameters +----------------- + +* force: short array (min = 1, max = 48) + List of adapter,address pairs to boldly assume to be present +* force_adm1021: short array (min = 1, max = 48) + List of adapter,address pairs which are unquestionably assumed to contain + a `adm1021' chip +* force_max1617: short array (min = 1, max = 48) + List of adapter,address pairs which are unquestionably assumed to contain + a `max1617' chip +* force_max1617a: short array (min = 1, max = 48) + List of adapter,address pairs which are unquestionably assumed to contain + a `max1617a' chip +* ignore: short array (min = 1, max = 48) + List of adapter,address pairs not to scan +* ignore_range: short array (min = 1, max = 48) + List of adapter,start-addr,end-addr triples not to scan +* probe: short array (min = 1, max = 48) + List of adapter,address pairs to scan additionally +* probe_range: short array (min = 1, max = 48) + List of adapter,start-addr,end-addr triples to scan additionally + + +Description +----------- + +The chips supported by this driver are very similar. The Maxim MAX1617 +is the oldest; it has the problem that it is not very well detectable. +The MAX1617A solves that. The ADM1021 is a straight clone of the MAX1617A. +From here on, we will refer to all these chips as ADM1021-clones. + +ADM1021-clones implement two temperature sensors. One of them is internal, +and measures the temperature of the chip itself; the other is external +and is realised in the form of a transistor-like device. A special alarm +indicates whether the remote sensor is connected. + +Each sensor has its own low and high limits. When they are crossed, the +corresponding alarm is set and remains on as long as the temperature stays +out of range. Temperatures are measured in degrees Celcius. Measurements +are possible between -65 and +127 degrees, with a resolution of one degree. + +The ADM1021 reports a die code, which is a sort of revision code. This +can help us pinpoint problems; it is not very useful otherwise. + +If an alarm triggers, it will remain triggered until the hardware register +is read at least once. This means that the cause for the alarm may +already have disappeared! + +This driver only updates its values each 1.5 seconds; reading it more often +will do no harm, but will return 'old' values. It is possible to make +ADM1021-clones do faster measurements, but there is really no good reason +for that. + + +Chip Features +------------- + +Chip `adm1021' + LABEL LABEL CLASS COMPUTE CLASS ACCESS MAGNITUDE + temp NONE NONE R 0 + temp_low temp temp RW 0 + temp_over temp temp RW 0 + remote_temp NONE NONE R 0 + remote_temp_low remote_temp remote_temp RW 0 + remote_temp_over remote_temp remote_temp RW 0 + alarms NONE NONE R 0 + die_code NONE NONE R 0 + + LABEL FEATURE SYMBOL SYSCTL FILE:NR + temp SENSORS_ADM1021_TEMP temp:3 + temp_low SENSORS_ADM1021_TEMP_HYST temp:2 + temp_over SENSORS_ADM1021_TEMP_OVER temp:1 + remote_temp SENSORS_ADM1021_REMOTE_TEMP remote_temp:3 + remote_temp_low SENSORS_ADM1021_REMOTE_TEMP_HYST remote_temp:2 + remote_temp_over SENSORS_ADM1021_REMOTE_TEMP_OVER remote_temp:1 + alarms SENSORS_ADM1021_ALARMS alarms:1 + die_code SENSORS_ADM1021_DIE_CODE die_code:1 + + +Chip `max1617' + LABEL LABEL CLASS COMPUTE CLASS ACCESS MAGNITUDE + temp NONE NONE R 0 + temp_low temp temp RW 0 + temp_over temp temp RW 0 + remote_temp NONE NONE R 0 + remote_temp_low remote_temp remote_temp RW 0 + remote_temp_over remote_temp remote_temp RW 0 + alarms NONE NONE R 0 + + LABEL FEATURE SYMBOL SYSCTL FILE:NR + temp SENSORS_MAX1617_TEMP temp:3 + temp_low SENSORS_MAX1617_TEMP_HYST temp:2 + temp_over SENSORS_MAX1617_TEMP_OVER temp:1 + remote_temp SENSORS_MAX1617_REMOTE_TEMP remote_temp:3 + remote_temp_low SENSORS_MAX1617_REMOTE_TEMP_HYST remote_temp:2 + remote_temp_over SENSORS_MAX1617_REMOTE_TEMP_OVER remote_temp:1 + alarms SENSORS_MAX1617_ALARMS alarms:1 + + +Chip `max1617a' + LABEL LABEL CLASS COMPUTE CLASS ACCESS MAGNITUDE + temp NONE NONE R 0 + temp_low temp temp RW 0 + temp_over temp temp RW 0 + remote_temp NONE NONE R 0 + remote_temp_low remote_temp remote_temp RW 0 + remote_temp_over remote_temp remote_temp RW 0 + alarms NONE NONE R 0 + + LABEL FEATURE SYMBOL SYSCTL FILE:NR + temp SENSORS_MAX1617A_TEMP temp:3 + temp_low SENSORS_MAX1617A_TEMP_HYST temp:2 + temp_over SENSORS_MAX1617A_TEMP_OVER temp:1 + remote_temp SENSORS_MAX1617A_REMOTE_TEMP remote_temp:3 + remote_temp_low SENSORS_MAX1617A_REMOTE_TEMP_HYST remote_temp:2 + remote_temp_over SENSORS_MAX1617A_REMOTE_TEMP_OVER remote_temp:1 + alarms SENSORS_MAX1617A_ALARMS alarms:1 + + + +Old Documentation (may be outdated) +----------------------------------- + This file documents the adm1021 directories for the Analog Devices ADM1021 and MAX1617 temperature sensor chip. Note that this last chip should be fully compatible; it is not yet well-tested, though. diff --git a/kernel/chips/adm1021.c b/kernel/chips/adm1021.c index e0c168de..5e43a5cf 100644 --- a/kernel/chips/adm1021.c +++ b/kernel/chips/adm1021.c @@ -93,7 +93,7 @@ struct adm1021_data { unsigned long last_updated; /* In jiffies */ u8 temp,temp_os,temp_hyst; /* Register values */ - u8 remote_temp,remote_temp_os,remote_temp_hyst,status,die_code; + u8 remote_temp,remote_temp_os,remote_temp_hyst,alarms,die_code; }; #ifdef MODULE @@ -117,7 +117,7 @@ static void adm1021_temp(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); static void adm1021_remote_temp(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); -static void adm1021_status(struct i2c_client *client, int operation, int ctl_name, +static void adm1021_alarms(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); static void adm1021_die_code(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results); @@ -148,8 +148,8 @@ static ctl_table adm1021_dir_table_template[] = { &sensors_sysctl_real, NULL, &adm1021_remote_temp }, {ADM1021_SYSCTL_DIE_CODE, "die_code", NULL, 0, 0444, NULL, &sensors_proc_real, &sensors_sysctl_real, NULL, &adm1021_die_code }, - {ADM1021_SYSCTL_STATUS, "status", NULL, 0, 0444, NULL, &sensors_proc_real, - &sensors_sysctl_real, NULL, &adm1021_status }, + {ADM1021_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &adm1021_alarms }, { 0 } }; @@ -158,8 +158,8 @@ static ctl_table adm1021_max_dir_table_template[] = { &sensors_sysctl_real, NULL, &adm1021_temp }, {ADM1021_SYSCTL_REMOTE_TEMP, "remote_temp", NULL, 0, 0644, NULL, &sensors_proc_real, &sensors_sysctl_real, NULL, &adm1021_remote_temp }, - {ADM1021_SYSCTL_STATUS, "status", NULL, 0, 0444, NULL, &sensors_proc_real, - &sensors_sysctl_real, NULL, &adm1021_status }, + {ADM1021_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &adm1021_alarms }, { 0 } }; @@ -217,6 +217,13 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind) new_client->adapter = adapter; new_client->driver = &adm1021_driver; + /* Now, we do the remaining detection. */ + + if (kind < 0) { + if ((adm1021_read_value(new_client,ADM1021_REG_STATUS) & 0x03) != 0x00) + goto ERROR1; + } + /* Determine the chip type. */ if (kind <= 0) { @@ -393,7 +400,7 @@ void adm1021_update_client(struct i2c_client *client) data->remote_temp = adm1021_read_value(client,ADM1021_REG_REMOTE_TEMP); data->remote_temp_os = adm1021_read_value(client,ADM1021_REG_REMOTE_TOS_R); data->remote_temp_hyst = adm1021_read_value(client,ADM1021_REG_REMOTE_THYST_R); - data->status = adm1021_read_value(client,ADM1021_REG_STATUS); + data->alarms = adm1021_read_value(client,ADM1021_REG_STATUS) & 0xec; if (data->type == adm1021) data->die_code = adm1021_read_value(client,ADM1021_REG_DIE_CODE); data->last_updated = jiffies; @@ -467,7 +474,7 @@ void adm1021_die_code(struct i2c_client *client, int operation, int ctl_name, } } -void adm1021_status(struct i2c_client *client, int operation, int ctl_name, +void adm1021_alarms(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { struct adm1021_data *data = client->data; @@ -475,7 +482,7 @@ void adm1021_status(struct i2c_client *client, int operation, int ctl_name, *nrels_mag = 0; else if (operation == SENSORS_PROC_REAL_READ) { adm1021_update_client(client); - results[0] = data->status; + results[0] = data->alarms; *nrels_mag = 1; } else if (operation == SENSORS_PROC_REAL_WRITE) { /* Can't write to it */ diff --git a/kernel/include/sensors.h b/kernel/include/sensors.h index d71cd703..2f611355 100644 --- a/kernel/include/sensors.h +++ b/kernel/include/sensors.h @@ -411,7 +411,13 @@ struct sensors_chips_data { #define ADM1021_SYSCTL_TEMP 1200 #define ADM1021_SYSCTL_REMOTE_TEMP 1201 #define ADM1021_SYSCTL_DIE_CODE 1202 -#define ADM1021_SYSCTL_STATUS 1203 +#define ADM1021_SYSCTL_ALARMS 1203 + +#define ADM1021_ALARM_TEMP_HIGH 0x40 +#define ADM1021_ALARM_TEMP_LOW 0x20 +#define ADM1021_ALARM_RTEMP_HIGH 0x10 +#define ADM1021_ALARM_RTEMP_LOW 0x08 +#define ADM1021_ALARM_RTEMP_NA 0x04 #define GL518_SYSCTL_VDD 1000 /* Volts * 100 */ #define GL518_SYSCTL_VIN1 1001 diff --git a/lib/chips.c b/lib/chips.c index 47a3f3a4..e6711e20 100644 --- a/lib/chips.c +++ b/lib/chips.c @@ -295,28 +295,90 @@ static sensors_chip_feature lm75_features[] = { 0 } }; - static sensors_chip_feature adm1021_features[] = { { SENSORS_ADM1021_TEMP, "temp", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, - SENSORS_MODE_R, ADM1021_SYSCTL_TEMP, VALUE(3), 0 }, + SENSORS_MODE_R, ADM1021_SYSCTL_TEMP, VALUE(3), + 0 }, { SENSORS_ADM1021_TEMP_HYST, "temp_low", SENSORS_ADM1021_TEMP, SENSORS_ADM1021_TEMP, SENSORS_MODE_RW, ADM1021_SYSCTL_TEMP, VALUE(2), 0 }, { SENSORS_ADM1021_TEMP_OVER, "temp_over", SENSORS_ADM1021_TEMP, SENSORS_ADM1021_TEMP, SENSORS_MODE_RW, ADM1021_SYSCTL_TEMP, VALUE(1), 0 }, - { SENSORS_ADM1021_REMOTE_TEMP, "remote_temp", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, - SENSORS_MODE_R, ADM1021_SYSCTL_REMOTE_TEMP, VALUE(3), 0 }, - { SENSORS_ADM1021_REMOTE_TEMP_HYST, "remote_temp_low", SENSORS_ADM1021_REMOTE_TEMP, + { SENSORS_ADM1021_REMOTE_TEMP, "remote_temp", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(3), 0 }, + { SENSORS_ADM1021_REMOTE_TEMP_HYST, "remote_temp_low", + SENSORS_ADM1021_REMOTE_TEMP, SENSORS_ADM1021_REMOTE_TEMP, SENSORS_MODE_RW, ADM1021_SYSCTL_REMOTE_TEMP, VALUE(2), 0 }, - { SENSORS_ADM1021_REMOTE_TEMP_OVER, "remote_temp_over", SENSORS_ADM1021_REMOTE_TEMP, + { SENSORS_ADM1021_REMOTE_TEMP_OVER, "remote_temp_over", + SENSORS_ADM1021_REMOTE_TEMP, SENSORS_ADM1021_REMOTE_TEMP, SENSORS_MODE_RW, ADM1021_SYSCTL_REMOTE_TEMP, VALUE(1), 0 }, - { SENSORS_ADM1021_STATUS, "status", SENSORS_NO_MAPPING, + { SENSORS_ADM1021_ALARMS, "alarms", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, SENSORS_MODE_R, - ADM1021_SYSCTL_STATUS, VALUE(1), 0 }, + ADM1021_SYSCTL_ALARMS, VALUE(1), 0 }, + { SENSORS_ADM1021_DIE_CODE, "die_code", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_DIE_CODE, VALUE(1), 0 }, + { 0 } + }; + +static sensors_chip_feature max1617_features[] = + { + { SENSORS_MAX1617_TEMP, "temp", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_R, ADM1021_SYSCTL_TEMP, VALUE(3), + 0 }, + { SENSORS_MAX1617_TEMP_HYST, "temp_low", SENSORS_MAX1617_TEMP, + SENSORS_MAX1617_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_TEMP, VALUE(2), 0 }, + { SENSORS_MAX1617_TEMP_OVER, "temp_over", SENSORS_MAX1617_TEMP, + SENSORS_MAX1617_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_TEMP, VALUE(1), 0 }, + { SENSORS_MAX1617_REMOTE_TEMP, "remote_temp", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(3), 0 }, + { SENSORS_MAX1617_REMOTE_TEMP_HYST, "remote_temp_low", + SENSORS_MAX1617_REMOTE_TEMP, + SENSORS_MAX1617_REMOTE_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(2), 0 }, + { SENSORS_MAX1617_REMOTE_TEMP_OVER, "remote_temp_over", + SENSORS_MAX1617_REMOTE_TEMP, + SENSORS_MAX1617_REMOTE_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(1), 0 }, + { SENSORS_MAX1617_ALARMS, "alarms", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_ALARMS, VALUE(1), 0 }, + { 0 } + }; + +static sensors_chip_feature max1617a_features[] = + { + { SENSORS_MAX1617A_TEMP, "temp", SENSORS_NO_MAPPING, SENSORS_NO_MAPPING, + SENSORS_MODE_R, ADM1021_SYSCTL_TEMP, VALUE(3), + 0 }, + { SENSORS_MAX1617A_TEMP_HYST, "temp_low", SENSORS_MAX1617A_TEMP, + SENSORS_MAX1617A_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_TEMP, VALUE(2), 0 }, + { SENSORS_MAX1617A_TEMP_OVER, "temp_over", SENSORS_MAX1617A_TEMP, + SENSORS_MAX1617A_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_TEMP, VALUE(1), 0 }, + { SENSORS_MAX1617A_REMOTE_TEMP, "remote_temp", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(3), 0 }, + { SENSORS_MAX1617A_REMOTE_TEMP_HYST, "remote_temp_low", + SENSORS_MAX1617A_REMOTE_TEMP, + SENSORS_MAX1617A_REMOTE_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(2), 0 }, + { SENSORS_MAX1617A_REMOTE_TEMP_OVER, "remote_temp_over", + SENSORS_MAX1617A_REMOTE_TEMP, + SENSORS_MAX1617A_REMOTE_TEMP, SENSORS_MODE_RW, + ADM1021_SYSCTL_REMOTE_TEMP, VALUE(1), 0 }, + { SENSORS_MAX1617A_ALARMS, "alarms", SENSORS_NO_MAPPING, + SENSORS_NO_MAPPING, SENSORS_MODE_R, + ADM1021_SYSCTL_ALARMS, VALUE(1), 0 }, { 0 } }; @@ -1186,6 +1248,8 @@ sensors_chip_features sensors_chip_features_list[] = { SENSORS_W83783S_PREFIX, w83783s_features }, { SENSORS_ADM9240_PREFIX, adm9240_features }, { SENSORS_ADM1021_PREFIX, adm1021_features }, + { SENSORS_MAX1617_PREFIX, max1617_features }, + { SENSORS_MAX1617A_PREFIX, max1617a_features }, { SENSORS_SIS5595_PREFIX, sis5595_features }, { SENSORS_MAXI_CG_PREFIX, maxi_features }, { SENSORS_MAXI_CO_PREFIX, maxi_features }, diff --git a/lib/chips.h b/lib/chips.h index 0dee19f2..4d040565 100644 --- a/lib/chips.h +++ b/lib/chips.h @@ -176,7 +176,32 @@ #define SENSORS_ADM1021_REMOTE_TEMP 54 /* R */ #define SENSORS_ADM1021_REMOTE_TEMP_HYST 55 /* RW */ #define SENSORS_ADM1021_REMOTE_TEMP_OVER 56 /* RW */ -#define SENSORS_ADM1021_STATUS 81 /* R */ +#define SENSORS_ADM1021_ALARMS 81 /* R */ +#define SENSORS_ADM1021_DIE_CODE 90 /* R */ + +/* MAX1617 chips. */ + +#define SENSORS_MAX1617_PREFIX "max1617" + +#define SENSORS_MAX1617_TEMP 51 /* R */ +#define SENSORS_MAX1617_TEMP_HYST 52 /* RW */ +#define SENSORS_MAX1617_TEMP_OVER 53 /* RW */ +#define SENSORS_MAX1617_REMOTE_TEMP 54 /* R */ +#define SENSORS_MAX1617_REMOTE_TEMP_HYST 55 /* RW */ +#define SENSORS_MAX1617_REMOTE_TEMP_OVER 56 /* RW */ +#define SENSORS_MAX1617_ALARMS 81 /* R */ + +/* MAX1617A chips. */ + +#define SENSORS_MAX1617A_PREFIX "max1617a" + +#define SENSORS_MAX1617A_TEMP 51 /* R */ +#define SENSORS_MAX1617A_TEMP_HYST 52 /* RW */ +#define SENSORS_MAX1617A_TEMP_OVER 53 /* RW */ +#define SENSORS_MAX1617A_REMOTE_TEMP 54 /* R */ +#define SENSORS_MAX1617A_REMOTE_TEMP_HYST 55 /* RW */ +#define SENSORS_MAX1617A_REMOTE_TEMP_OVER 56 /* RW */ +#define SENSORS_MAX1617A_ALARMS 81 /* R */ /* GL518SM revision 0x00 chips. You may also use the revision 0x80 defines, but note that some features are unaccessible in revision 0x00. */ diff --git a/prog/doc/doc-features.pl b/prog/doc/doc-features.pl index 1d7953e3..b56ede09 100755 --- a/prog/doc/doc-features.pl +++ b/prog/doc/doc-features.pl @@ -232,7 +232,8 @@ sub output_data my ($feature,$data,$read_write); $feature = $features{$index}; printf "Chip `%s'\n",$feature->{prefix}; - print " LABEL LABEL CLASS COMPUTE CLASS ACCESS MAGNITUDE\n"; + print " LABEL LABEL CLASS COMPUTE CLASS ACCESS ". + "MAGNITUDE\n"; foreach $data (@{$feature->{features}}) { $read_write = $data->{mode_read} + 2 * $data->{mode_write}; if ($read_write == 0) { @@ -244,16 +245,16 @@ sub output_data } else { $read_write = "RW"; } - printf "%15s %15s %15s %2s %2s\n", + printf "%18s %18s %18s %2s %2s\n", $data->{name}, $feature_name{$data->{logical_mapping}}, $feature_name{$data->{compute_mapping}}, $read_write,$data->{magnitude}; } print "\n"; - print " LABEL FEATURE SYMBOL ". - "SYSCTL FILE:OFFSET\n"; + print " LABEL FEATURE SYMBOL ". + " SYSCTL FILE:NR\n"; foreach $data (@{$feature->{features}}) { - printf "%15s %40s %15s:%1d\n",$data->{name}, $data->{number}, + printf "%18s %39s %18s:%1d\n",$data->{name}, $data->{number}, $sysctls{$data->{sysctl}}, $data->{offset}, $data->{magnitude}; } } diff --git a/prog/doc/doc-insmod.pl b/prog/doc/doc-insmod.pl index 78419e01..790463a6 100755 --- a/prog/doc/doc-insmod.pl +++ b/prog/doc/doc-insmod.pl @@ -51,7 +51,7 @@ sub print_info { my ($modname) = @_; my (@lines,$line,$option,$type,$desc); - print "Author: ", wrap("Author: "," ",`modinfo -a $modname`), "\n\n"; + print wrap("Author: "," ",`modinfo -a $modname`), "\n\n"; print "Module Parameters\n"; print "-----------------\n"; print "\n";