diff -Nru a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/i2c/porting-clients Thu Dec 4 14:32:37 2003 @@ -0,0 +1,121 @@ +Revision 3, 2003-10-04 +Jean Delvare +Greg KH + +This is a guide on how to convert I2C chip drivers from Linux 2.4 to +Linux 2.6. I have been using existing drivers (lm75, lm78) as examples. +Then I converted a driver myself (lm83) and updated this document. + +There are two sets of points below. The first set concerns technical +changes. The second set concerns coding policy. Both are mandatory. + +Although reading this guide will help you porting drivers, I suggest +you keep an eye on an already ported driver while porting your own +driver. This will help you a lot understanding what this guide +exactly means. Choose the chip driver that is the more similar to +yours for best results. + +Technical changes: + +* [Includes] Get rid of "version.h". Replace with + . Includes typically look like that: + #include + #include + #include + #include + #include + #include /* if you need VRM support */ + #include /* if you have I/O operations */ + Some extra headers may be required for a given driver. + +* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, SENSORS_ISA_END + becomes I2C_CLIENT_ISA_END. + +* [Client data] Get rid of sysctl_id. Try using standard names for + register values (for example, temp_os becomes temp_max). You're + still relatively free here, but you *have* to follow the standard + names for sysfs files (see the Sysctl section below). + +* [Function prototypes] The detect functions loses its flags + parameter. Sysctl (e.g. lm75_temp) and miscellaneous (e.g. + swap_bytes) functions are off the list of prototypes. This + usually leaves five prototypes: + static int lm75_attach_adapter(struct i2c_adapter *adapter); + static int lm75_detect(struct i2c_adapter *adapter, int address, + int kind); + static void lm75_init_client(struct i2c_client *client); + static int lm75_detach_client(struct i2c_client *client); + static void lm75_update_client(struct i2c_client *client); + +* [Sysctl] All sysctl stuff is of course gone (defines, ctl_table + and functions). Instead, right after the static id definition + line, you have to define show and set functions for each sysfs + file. Only define set for writable values. Take a look at an + existing 2.6 driver for details (lm78 for example). Don't forget + to define the attributes for each file (this is that step that + links callback functions). Use the file names specified in + Documentation/i2c/sysfs-interface for the individual files. Also + convert the units these files read and write to the specified ones. + If you need to add a new type of file, please discuss it on the + sensors mailing list by providing a + patch to the Documentation/i2c/sysfs-interface file. + +* [Attach] For I2C drivers, the attach function should make sure + that the adapter's class has I2C_ADAP_CLASS_SMBUS, using the + following construct: + if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + return 0; + ISA-only drivers of course don't need this. + +* [Detect] As mentioned earlier, the flags parameter is gone. + The type_name and client_name strings are replaced by a single + name string, which will be filled with a lowercase, short string + (typically the driver name, e.g. "lm75"). The errorN labels are + reduced to the number needed. If that number is 2 (i2c-only + drivers), it is advised that the labels are named exit and + exit_free. For i2c+isa drivers, labels should be named ERROR0, + ERROR1 and ERROR2. Don't forget to properly set err before + jumping to error labels. By the way, labels should be + left-aligned. + Use memset to fill the client and data area with 0x00. + Use i2c_set_clientdata to set the client data (as opposed to + a direct access to client->data). + Use strlcpy instead of strcpy to copy the client name. + Replace the sysctl directory registration by calls to + device_create_file. Move the driver initialization before any + sysfs file creation. + +* [Detach] Get rid of data, remove the call to + i2c_deregister_entry. + +* [Update] Don't access client->data directly, use + i2c_get_clientdata(client) instead. + +* [Interface] Init function should not print anything. Make sure + there is a MODULE_LICENSE() line. + +Coding policy: + +* [Copyright] Use (C), not (c), for copyright. + +* [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you + can. Calls to printk/pr_debug for debugging purposes are replaced + by calls to dev_dbg. Here is an example on how to call it (taken + from lm75_detect): + dev_dbg(&adapter->dev, + "lm75_detect called for an ISA bus adapter?!?\n"); + Replace other printk calls with the dev_info, dev_err or dev_warn + function, as appropriate. + +* [Constants] Constants defines (registers, conversions, initial + values) should be aligned. This greatly improves readability. + Same goes for variables declarations. Alignments are achieved by the + means of tabs, not spaces. Remember that tabs are set to 8 in the + Linux kernel code. + +* [Structure definition] The name field should be standardized. All + lowercase and as simple as the driver name itself (e.g. "lm75"). + +* [Layout] Avoid extra empty lines between comments and what they + comment. Respect the coding style (see Documentation/CodingStyle), + in particular when it comes to placing curly braces. diff -Nru a/Documentation/i2c/sysfs-interface b/Documentation/i2c/sysfs-interface --- a/Documentation/i2c/sysfs-interface Thu Dec 4 14:32:37 2003 +++ b/Documentation/i2c/sysfs-interface Thu Dec 4 14:32:37 2003 @@ -68,9 +68,7 @@ Fixed point XXXXX, divide by 1000 to get Amps. Read/Write. -curr_min[1-n] Current min or hysteresis value. - Preferably a hysteresis value, reported as a absolute - current, NOT a delta from the max value. +curr_min[1-n] Current min value. Fixed point XXXXX, divide by 1000 to get Amps. Read/Write. @@ -144,25 +142,38 @@ Integers 1,2,3, or thermistor Beta value (3435) Read/Write. -temp_max[1-3] Temperature max value. +temp_max[1-4] Temperature max value. Fixed point value in form XXXXX and should be divided by 1000 to get degrees Celsius. Read/Write value. -temp_min[1-3] Temperature min or hysteresis value. +temp_min[1-3] Temperature min value. Fixed point value in form XXXXX and should be divided by - 1000 to get degrees Celsius. This is preferably a - hysteresis value, reported as a absolute temperature, - NOT a delta from the max value. + 1000 to get degrees Celsius. Read/Write value. -temp_input[1-3] Temperature input value. +temp_hyst[1-3] Temperature hysteresis value. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. Must be reported as an + absolute temperature, NOT a delta from the max value. + Read/Write value. + +temp_input[1-4] Temperature input value. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. Read only value. +temp_crit Temperature critical value, typically greater than all + temp_max values. + Fixed point value in form XXXXX and should be divided by + 1000 to get degrees Celsius. + Common to all temperature channels. + Read/Write value. + If there are multiple temperature sensors, temp_*1 is generally the sensor inside the chip itself, generally - reported as "motherboard temperature". temp_*2 and - temp_*3 are generally sensors external to the chip + reported as "motherboard temperature". temp_*2 to + temp_*4 are generally sensors external to the chip itself, for example the thermal diode inside the CPU or a thermistor nearby. diff -Nru a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients --- a/Documentation/i2c/writing-clients Thu Dec 4 14:32:37 2003 +++ b/Documentation/i2c/writing-clients Thu Dec 4 14:32:37 2003 @@ -24,16 +24,14 @@ routines, a client structure specific information like the actual I2C address. - struct i2c_driver foo_driver - { - /* name */ "Foo version 2.3 and later driver", - /* id */ I2C_DRIVERID_FOO, - /* flags */ I2C_DF_NOTIFY, - /* attach_adapter */ &foo_attach_adapter, - /* detach_client */ &foo_detach_client, - /* command */ &foo_command, /* May be NULL */ - /* inc_use */ &foo_inc_use, /* May be NULL */ - /* dec_use */ &foo_dec_use /* May be NULL */ + static struct i2c_driver foo_driver = { + .owner = THIS_MODULE, + .name = "Foo version 2.3 driver", + .id = I2C_DRIVERID_FOO, /* usually from i2c-id.h */ + .flags = I2C_DF_NOTIFY, + .attach_adapter = &foo_attach_adapter, + .detach_client = &foo_detach_client, + .command = &foo_command /* may be NULL */ } The name can be chosen freely, and may be upto 40 characters long. Please @@ -50,43 +48,8 @@ All other fields are for call-back functions which will be explained below. - -Module usage count -================== - -If your driver can also be compiled as a module, there are moments at -which the module can not be removed from memory. For example, when you -are doing a lengthy transaction, or when you create a /proc directory, -and some process has entered that directory (this last case is the -main reason why these call-backs were introduced). - -To increase or decrease the module usage count, you can use the -MOD_{INC,DEC}_USE_COUNT macros. They must be called from the module -which needs to get its usage count changed; that is why each driver -module has to implement its own callback. - - void foo_inc_use (struct i2c_client *client) - { - #ifdef MODULE - MOD_INC_USE_COUNT; - #endif - } - - void foo_dec_use (struct i2c_client *client) - { - #ifdef MODULE - MOD_DEC_USE_COUNT; - #endif - } - -Do not call these call-back functions directly; instead, use one of the -following functions defined in i2c.h: - void i2c_inc_use_client(struct i2c_client *); - void i2c_dec_use_client(struct i2c_client *); - -You should *not* increase the module count just because a device is -detected and a client created. This would make it impossible to remove -an adapter driver! +There use to be two additional fields in this structure, inc_use et dec_use, +for module usage count, but these fields were obsoleted and removed. Extra client data diff -Nru a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c --- a/drivers/i2c/algos/i2c-algo-bit.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/algos/i2c-algo-bit.c Thu Dec 4 14:32:37 2003 @@ -18,10 +18,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ -/* With some changes from Kyösti Mälkki and even - Frodo Looijaard */ - -/* $Id: i2c-algo-bit.c,v 1.44 2003/01/21 08:08:16 kmalkki Exp $ */ +/* With some changes from Frodo Looijaard , Kyösti Mälkki + and Jean Delvare */ /* #define DEBUG 1 */ @@ -87,8 +85,10 @@ setscl(adap,1); /* Not all adapters have scl sense line... */ - if (adap->getscl == NULL ) + if (adap->getscl == NULL ) { + udelay(adap->udelay); return 0; + } start=jiffies; while (! getscl(adap) ) { @@ -222,68 +222,72 @@ */ static int test_bus(struct i2c_algo_bit_data *adap, char* name) { int scl,sda; + + if (adap->getscl==NULL) + printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, " + "SCL is not readable.\n"); + sda=getsda(adap); - if (adap->getscl==NULL) { - printk(KERN_WARNING "i2c-algo-bit.o: Warning: Adapter can't read from clock line - skipping test.\n"); - return 0; - } - scl=getscl(adap); - printk(KERN_INFO "i2c-algo-bit.o: Adapter: %s scl: %d sda: %d -- testing...\n", - name,getscl(adap),getsda(adap)); + scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda); if (!scl || !sda ) { - printk(KERN_INFO " i2c-algo-bit.o: %s seems to be busy.\n",name); + printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name); goto bailout; } + sdalo(adap); - printk(KERN_DEBUG "i2c-algo-bit.o:1 scl: %d sda: %d \n",getscl(adap), - getsda(adap)); - if ( 0 != getsda(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SDA stuck high!\n",name); - sdahi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda); + if ( 0 != sda ) { + printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n"); goto bailout; } - if ( 0 == getscl(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SCL unexpected low while pulling SDA low!\n", - name); + if ( 0 == scl ) { + printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " + "while pulling SDA low!\n"); goto bailout; } + sdahi(adap); - printk(KERN_DEBUG "i2c-algo-bit.o:2 scl: %d sda: %d \n",getscl(adap), - getsda(adap)); - if ( 0 == getsda(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SDA stuck low!\n",name); - sdahi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda); + if ( 0 == sda ) { + printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n"); goto bailout; } - if ( 0 == getscl(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SCL unexpected low while SDA high!\n", - name); - goto bailout; + if ( 0 == scl ) { + printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " + "while pulling SDA high!\n"); + goto bailout; } + scllo(adap); - printk(KERN_DEBUG "i2c-algo-bit.o:3 scl: %d sda: %d \n",getscl(adap), - getsda(adap)); - if ( 0 != getscl(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SCL stuck high!\n",name); - sclhi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?0:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda); + if ( 0 != scl ) { + printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n"); goto bailout; } - if ( 0 == getsda(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SDA unexpected low while pulling SCL low!\n", - name); + if ( 0 == sda ) { + printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " + "while pulling SCL low!\n"); goto bailout; } + sclhi(adap); - printk(KERN_DEBUG "i2c-algo-bit.o:4 scl: %d sda: %d \n",getscl(adap), - getsda(adap)); - if ( 0 == getscl(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SCL stuck low!\n",name); - sclhi(adap); + sda=getsda(adap); + scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda); + if ( 0 == scl ) { + printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n"); goto bailout; } - if ( 0 == getsda(adap) ) { - printk(KERN_WARNING "i2c-algo-bit.o: %s SDA unexpected low while SCL high!\n", - name); + if ( 0 == sda ) { + printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " + "while pulling SCL high!\n"); goto bailout; } printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name); diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig --- a/drivers/i2c/busses/Kconfig Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/busses/Kconfig Thu Dec 4 14:32:37 2003 @@ -161,11 +161,12 @@ help If you say yes to this option, support will be included for the Intel PIIX4 family of mainboard I2C interfaces. Specifically, the following - versions of the chipset is supported: + versions of the chipset are supported: Intel PIIX4 Intel 440MX Serverworks OSB4 Serverworks CSB5 + Serverworks CSB6 SMSC Victory66 This driver can also be built as a module. If so, the module @@ -309,6 +310,7 @@ 8233 8233A 8235 + 8237 This driver can also be built as a module. If so, the module will be called i2c-viapro. diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c --- a/drivers/i2c/busses/i2c-piix4.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/busses/i2c-piix4.c Thu Dec 4 14:32:37 2003 @@ -22,7 +22,7 @@ /* Supports: Intel PIIX4, 440MX - Serverworks OSB4, CSB5 + Serverworks OSB4, CSB5, CSB6 SMSC Victory66 Note: we assume there can only be one device, with one SMBus interface. @@ -418,6 +418,13 @@ { .vendor = PCI_VENDOR_ID_SERVERWORKS, .device = PCI_DEVICE_ID_SERVERWORKS_CSB5, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = 0, + }, + { + .vendor = PCI_VENDOR_ID_SERVERWORKS, + .device = PCI_DEVICE_ID_SERVERWORKS_CSB6, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = 0, diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c --- a/drivers/i2c/busses/i2c-savage4.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/busses/i2c-savage4.c Thu Dec 4 14:32:37 2003 @@ -1,13 +1,11 @@ /* i2c-savage4.c - Part of lm_sensors, Linux kernel modules for hardware monitoring - Copyright (c) 1998, 1999 Frodo Looijaard , - Philip Edelbrock , - Ralph Metzler , and + Copyright (C) 1998-2003 The LM Sensors Team + Alexander Wold Mark D. Studebaker - Based on code written by Ralph Metzler and - Simon Vogl + Based on i2c-voodoo3.c. 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 @@ -195,9 +193,7 @@ pci_unregister_driver(&savage4_driver); } -MODULE_AUTHOR("Frodo Looijaard , " - "Philip Edelbrock , " - "Ralph Metzler , " +MODULE_AUTHOR("Alexander Wold " "and Mark D. Studebaker "); MODULE_DESCRIPTION("Savage4 I2C/SMBus driver"); MODULE_LICENSE("GPL"); diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c --- a/drivers/i2c/busses/i2c-viapro.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/busses/i2c-viapro.c Thu Dec 4 14:32:37 2003 @@ -29,6 +29,7 @@ 8233 8233A (0x3147 and 0x3177) 8235 + 8237 Note: we assume there can only be one device, with one SMBus interface. */ @@ -430,6 +431,13 @@ { .vendor = PCI_VENDOR_ID_VIA, .device = PCI_DEVICE_ID_VIA_8235, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = SMBBA3 + }, + { + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_8237, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = SMBBA3 diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig --- a/drivers/i2c/chips/Kconfig Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/Kconfig Thu Dec 4 14:32:37 2003 @@ -68,6 +68,17 @@ This driver can also be built as a module. If so, the module will be called lm78. +config SENSORS_LM83 + tristate "National Semiconductor LM83" + depends on I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for National Semiconductor + LM83 sensor chips. + + This driver can also be built as a module. If so, the module + will be called lm83. + config SENSORS_LM85 tristate "National Semiconductor LM85 and compatibles" depends on I2C && EXPERIMENTAL diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile --- a/drivers/i2c/chips/Makefile Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/Makefile Thu Dec 4 14:32:37 2003 @@ -10,5 +10,6 @@ obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_LM75) += lm75.o obj-$(CONFIG_SENSORS_LM78) += lm78.o +obj-$(CONFIG_SENSORS_LM83) += lm83.o obj-$(CONFIG_SENSORS_LM85) += lm85.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c --- a/drivers/i2c/chips/it87.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/it87.c Thu Dec 4 14:32:37 2003 @@ -343,7 +343,6 @@ it87_update_client(client); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr])*100 ); } -/* more like overshoot temperature */ static ssize_t show_temp_max(struct device *dev, char *buf, int nr) { struct i2c_client *client = to_i2c_client(dev); @@ -351,7 +350,6 @@ it87_update_client(client); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[nr])*100); } -/* more like hysteresis temperature */ static ssize_t show_temp_min(struct device *dev, char *buf, int nr) { struct i2c_client *client = to_i2c_client(dev); @@ -414,7 +412,6 @@ show_temp_offset(2); show_temp_offset(3); -/* more like overshoot temperature */ static ssize_t show_sensor(struct device *dev, char *buf, int nr) { struct i2c_client *client = to_i2c_client(dev); @@ -563,15 +560,15 @@ show_fan_offset(2); show_fan_offset(3); -/* Alarm */ -static ssize_t show_alarm(struct device *dev, char *buf) +/* Alarms */ +static ssize_t show_alarms(struct device *dev, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct it87_data *data = i2c_get_clientdata(client); it87_update_client(client); return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms)); } -static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, show_alarm, NULL); +static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL); /* This function is called when: * it87_driver is inserted (when this module is loaded), for each @@ -751,7 +748,7 @@ device_create_file(&new_client->dev, &dev_attr_fan_div1); device_create_file(&new_client->dev, &dev_attr_fan_div2); device_create_file(&new_client->dev, &dev_attr_fan_div3); - device_create_file(&new_client->dev, &dev_attr_alarm); + device_create_file(&new_client->dev, &dev_attr_alarms); return 0; diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c --- a/drivers/i2c/chips/lm75.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/lm75.c Thu Dec 4 14:32:37 2003 @@ -116,7 +116,7 @@ set(temp_hyst, LM75_REG_TEMP_HYST); static DEVICE_ATTR(temp_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); -static DEVICE_ATTR(temp_min, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); +static DEVICE_ATTR(temp_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); static DEVICE_ATTR(temp_input, S_IRUGO, show_temp_input, NULL); static int lm75_attach_adapter(struct i2c_adapter *adapter) @@ -209,7 +209,7 @@ /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_temp_max); - device_create_file(&new_client->dev, &dev_attr_temp_min); + device_create_file(&new_client->dev, &dev_attr_temp_hyst); device_create_file(&new_client->dev, &dev_attr_temp_input); return 0; diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c --- a/drivers/i2c/chips/lm78.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/lm78.c Thu Dec 4 14:32:37 2003 @@ -367,7 +367,7 @@ static DEVICE_ATTR(temp_input, S_IRUGO, show_temp, NULL) static DEVICE_ATTR(temp_max, S_IRUGO | S_IWUSR, show_temp_over, set_temp_over) -static DEVICE_ATTR(temp_min, S_IRUGO | S_IWUSR, +static DEVICE_ATTR(temp_hyst, S_IRUGO | S_IWUSR, show_temp_hyst, set_temp_hyst) /* 3 Fans */ @@ -674,8 +674,8 @@ device_create_file(&new_client->dev, &dev_attr_in_min6); device_create_file(&new_client->dev, &dev_attr_in_max6); device_create_file(&new_client->dev, &dev_attr_temp_input); - device_create_file(&new_client->dev, &dev_attr_temp_min); device_create_file(&new_client->dev, &dev_attr_temp_max); + device_create_file(&new_client->dev, &dev_attr_temp_hyst); device_create_file(&new_client->dev, &dev_attr_fan_input1); device_create_file(&new_client->dev, &dev_attr_fan_min1); device_create_file(&new_client->dev, &dev_attr_fan_div1); diff -Nru a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/i2c/chips/lm83.c Thu Dec 4 14:32:37 2003 @@ -0,0 +1,413 @@ +/* + * lm83.c - Part of lm_sensors, Linux kernel modules for hardware + * monitoring + * Copyright (C) 2003 Jean Delvare + * + * Heavily inspired from the lm78, lm75 and adm1021 drivers. The LM83 is + * a sensor chip made by National Semiconductor. It reports up to four + * temperatures (its own plus up to three external ones) with a 1 deg + * resolution and a 3-4 deg accuracy. Complete datasheet can be obtained + * from National's website at: + * http://www.national.com/pf/LM/LM83.html + * Since the datasheet omits to give the chip stepping code, I give it + * here: 0x03 (at register 0xff). + * + * 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. + */ + +#include +#include +#include +#include +#include + +/* + * Addresses to scan + * Address is selected using 2 three-level pins, resulting in 9 possible + * addresses. + */ + +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { 0x18, 0x1a, 0x29, 0x2b, + 0x4c, 0x4e, I2C_CLIENT_END }; +static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; +static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; + +/* + * Insmod parameters + */ + +SENSORS_INSMOD_1(lm83); + +/* + * The LM83 registers + * Manufacturer ID is 0x01 for National Semiconductor. + */ + +#define LM83_REG_R_MAN_ID 0xFE +#define LM83_REG_R_CHIP_ID 0xFF +#define LM83_REG_R_CONFIG 0x03 +#define LM83_REG_W_CONFIG 0x09 +#define LM83_REG_R_STATUS1 0x02 +#define LM83_REG_R_STATUS2 0x35 +#define LM83_REG_R_LOCAL_TEMP 0x00 +#define LM83_REG_R_LOCAL_HIGH 0x05 +#define LM83_REG_W_LOCAL_HIGH 0x0B +#define LM83_REG_R_REMOTE1_TEMP 0x30 +#define LM83_REG_R_REMOTE1_HIGH 0x38 +#define LM83_REG_W_REMOTE1_HIGH 0x50 +#define LM83_REG_R_REMOTE2_TEMP 0x01 +#define LM83_REG_R_REMOTE2_HIGH 0x07 +#define LM83_REG_W_REMOTE2_HIGH 0x0D +#define LM83_REG_R_REMOTE3_TEMP 0x31 +#define LM83_REG_R_REMOTE3_HIGH 0x3A +#define LM83_REG_W_REMOTE3_HIGH 0x52 +#define LM83_REG_R_TCRIT 0x42 +#define LM83_REG_W_TCRIT 0x5A + +/* + * Conversions, initial values and various macros + * The LM83 uses signed 8-bit values. + */ + +#define TEMP_FROM_REG(val) ((val > 127 ? val-256 : val) * 1000) +#define TEMP_TO_REG(val) ((val < 0 ? val+256 : val) / 1000) + +#define LM83_INIT_HIGH 100 +#define LM83_INIT_CRIT 120 + +static const u8 LM83_REG_R_TEMP[] = { + LM83_REG_R_LOCAL_TEMP, + LM83_REG_R_REMOTE1_TEMP, + LM83_REG_R_REMOTE2_TEMP, + LM83_REG_R_REMOTE3_TEMP +}; + +static const u8 LM83_REG_R_HIGH[] = { + LM83_REG_R_LOCAL_HIGH, + LM83_REG_R_REMOTE1_HIGH, + LM83_REG_R_REMOTE2_HIGH, + LM83_REG_R_REMOTE3_HIGH +}; + +static const u8 LM83_REG_W_HIGH[] = { + LM83_REG_W_LOCAL_HIGH, + LM83_REG_W_REMOTE1_HIGH, + LM83_REG_W_REMOTE2_HIGH, + LM83_REG_W_REMOTE3_HIGH +}; + +/* + * Functions declaration + */ + +static int lm83_attach_adapter(struct i2c_adapter *adapter); +static int lm83_detect(struct i2c_adapter *adapter, int address, + int kind); +static void lm83_init_client(struct i2c_client *client); +static int lm83_detach_client(struct i2c_client *client); +static void lm83_update_client(struct i2c_client *client); + +/* + * Driver data (common to all clients) + */ + +static struct i2c_driver lm83_driver = { + .owner = THIS_MODULE, + .name = "lm83", + .id = I2C_DRIVERID_LM83, + .flags = I2C_DF_NOTIFY, + .attach_adapter = lm83_attach_adapter, + .detach_client = lm83_detach_client, +}; + +/* + * Client data (each client gets its own) + */ + +struct lm83_data +{ + struct semaphore update_lock; + char valid; /* zero until following fields are valid */ + unsigned long last_updated; /* in jiffies */ + + /* registers values */ + u8 temp_input[4]; + u8 temp_high[4]; + u8 temp_crit; + u16 alarms; /* bitvector, combined */ +}; + +/* + * Internal variables + */ + +static int lm83_id = 0; + +/* + * Sysfs stuff + */ + +#define show_temp(suffix, value) \ +static ssize_t show_temp_##suffix(struct device *dev, char *buf) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm83_data *data = i2c_get_clientdata(client); \ + lm83_update_client(client); \ + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \ +} +show_temp(input1, temp_input[0]); +show_temp(input2, temp_input[1]); +show_temp(input3, temp_input[2]); +show_temp(input4, temp_input[3]); +show_temp(high1, temp_high[0]); +show_temp(high2, temp_high[1]); +show_temp(high3, temp_high[2]); +show_temp(high4, temp_high[3]); +show_temp(crit, temp_crit); + +#define set_temp(suffix, value, reg) \ +static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \ + size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm83_data *data = i2c_get_clientdata(client); \ + data->value = TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \ + i2c_smbus_write_byte_data(client, reg, data->value); \ + return count; \ +} +set_temp(high1, temp_high[0], LM83_REG_W_LOCAL_HIGH); +set_temp(high2, temp_high[1], LM83_REG_W_REMOTE1_HIGH); +set_temp(high3, temp_high[2], LM83_REG_W_REMOTE2_HIGH); +set_temp(high4, temp_high[3], LM83_REG_W_REMOTE3_HIGH); +set_temp(crit, temp_crit, LM83_REG_W_TCRIT); + +static ssize_t show_alarms(struct device *dev, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct lm83_data *data = i2c_get_clientdata(client); + lm83_update_client(client); + return sprintf(buf, "%d\n", data->alarms); +} + +static DEVICE_ATTR(temp_input1, S_IRUGO, show_temp_input1, NULL); +static DEVICE_ATTR(temp_input2, S_IRUGO, show_temp_input2, NULL); +static DEVICE_ATTR(temp_input3, S_IRUGO, show_temp_input3, NULL); +static DEVICE_ATTR(temp_input4, S_IRUGO, show_temp_input4, NULL); +static DEVICE_ATTR(temp_max1, S_IWUSR | S_IRUGO, show_temp_high1, + set_temp_high1); +static DEVICE_ATTR(temp_max2, S_IWUSR | S_IRUGO, show_temp_high2, + set_temp_high2); +static DEVICE_ATTR(temp_max3, S_IWUSR | S_IRUGO, show_temp_high3, + set_temp_high3); +static DEVICE_ATTR(temp_max4, S_IWUSR | S_IRUGO, show_temp_high4, + set_temp_high4); +static DEVICE_ATTR(temp_crit, S_IWUSR | S_IRUGO, show_temp_crit, + set_temp_crit); +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + +/* + * Real code + */ + +static int lm83_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + return 0; + return i2c_detect(adapter, &addr_data, lm83_detect); +} + +/* + * The following function does more than just detection. If detection + * succeeds, it also registers the new chip. + */ +static int lm83_detect(struct i2c_adapter *adapter, int address, + int kind) +{ + struct i2c_client *new_client; + struct lm83_data *data; + int err = 0; + const char *name = ""; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + goto exit; + + if (!(new_client = kmalloc(sizeof(struct i2c_client) + + sizeof(struct lm83_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + memset(new_client, 0x00, sizeof(struct i2c_client) + + sizeof(struct lm83_data)); + + /* The LM83-specific data is placed right after the common I2C + * client data. */ + data = (struct lm83_data *) (new_client + 1); + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &lm83_driver; + new_client->flags = 0; + + /* Now we do the detection and identification. A negative kind + * means that the driver was loaded with no force parameter + * (default), so we must both detect and identify the chip + * (actually there is only one possible kind of chip for now, LM83). + * A zero kind means that the driver was loaded with the force + * parameter, the detection step shall be skipped. A positive kind + * means that the driver was loaded with the force parameter and a + * given kind of chip is requested, so both the detection and the + * identification steps are skipped. */ + if (kind < 0) { /* detection */ + if (((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS1) + & 0xA8) != 0x00) || + ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_STATUS2) + & 0x48) != 0x00) || + ((i2c_smbus_read_byte_data(new_client, LM83_REG_R_CONFIG) + & 0x41) != 0x00)) { + dev_dbg(&client->dev, + "LM83 detection failed at 0x%02x.\n", address); + goto exit_free; + } + } + + if (kind <= 0) { /* identification */ + u8 man_id, chip_id; + + man_id = i2c_smbus_read_byte_data(new_client, + LM83_REG_R_MAN_ID); + chip_id = i2c_smbus_read_byte_data(new_client, + LM83_REG_R_CHIP_ID); + if (man_id == 0x01) { /* National Semiconductor */ + if (chip_id == 0x03) { + kind = lm83; + name = "lm83"; + } + } + + if (kind <= 0) { /* identification failed */ + dev_info(&adapter->dev, + "Unsupported chip (man_id=0x%02X, " + "chip_id=0x%02X).\n", man_id, chip_id); + goto exit_free; + } + } + + /* We can fill in the remaining client fields */ + strlcpy(new_client->name, name, I2C_NAME_SIZE); + new_client->id = lm83_id++; + data->valid = 0; + init_MUTEX(&data->update_lock); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) + goto exit_free; + + /* Initialize the LM83 chip */ + lm83_init_client(new_client); + + /* Register sysfs hooks */ + device_create_file(&new_client->dev, &dev_attr_temp_input1); + device_create_file(&new_client->dev, &dev_attr_temp_input2); + device_create_file(&new_client->dev, &dev_attr_temp_input3); + device_create_file(&new_client->dev, &dev_attr_temp_input4); + device_create_file(&new_client->dev, &dev_attr_temp_max1); + device_create_file(&new_client->dev, &dev_attr_temp_max2); + device_create_file(&new_client->dev, &dev_attr_temp_max3); + device_create_file(&new_client->dev, &dev_attr_temp_max4); + device_create_file(&new_client->dev, &dev_attr_temp_crit); + device_create_file(&new_client->dev, &dev_attr_alarms); + + return 0; + +exit_free: + kfree(new_client); +exit: + return err; +} + +static void lm83_init_client(struct i2c_client *client) +{ + int nr; + + for (nr = 0; nr < 4; nr++) + i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr], + TEMP_TO_REG(LM83_INIT_HIGH)); + i2c_smbus_write_byte_data(client, LM83_REG_W_TCRIT, + TEMP_TO_REG(LM83_INIT_CRIT)); +} + +static int lm83_detach_client(struct i2c_client *client) +{ + int err; + + if ((err = i2c_detach_client(client))) { + dev_err(&client->dev, + "Client deregistration failed, client not detached.\n"); + return err; + } + + kfree(client); + return 0; +} + +static void lm83_update_client(struct i2c_client *client) +{ + struct lm83_data *data = i2c_get_clientdata(client); + + down(&data->update_lock); + + if ((jiffies - data->last_updated > HZ * 2) || + (jiffies < data->last_updated) || + !data->valid) { + int nr; + dev_dbg(&client->dev, "Updating lm83 data.\n"); + for (nr = 0; nr < 4 ; nr++) { + data->temp_input[nr] = + i2c_smbus_read_byte_data(client, + LM83_REG_R_TEMP[nr]); + data->temp_high[nr] = + i2c_smbus_read_byte_data(client, + LM83_REG_R_HIGH[nr]); + } + data->temp_crit = + i2c_smbus_read_byte_data(client, LM83_REG_R_TCRIT); + data->alarms = + i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS1) + + (i2c_smbus_read_byte_data(client, LM83_REG_R_STATUS2) + << 8); + data->last_updated = jiffies; + data->valid = 1; + } + + up(&data->update_lock); +} + +static int __init sensors_lm83_init(void) +{ + return i2c_add_driver(&lm83_driver); +} + +static void __exit sensors_lm83_exit(void) +{ + i2c_del_driver(&lm83_driver); +} + +MODULE_AUTHOR("Jean Delvare "); +MODULE_DESCRIPTION("LM83 driver"); +MODULE_LICENSE("GPL"); + +module_init(sensors_lm83_init); +module_exit(sensors_lm83_exit); diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c --- a/drivers/i2c/chips/via686a.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/via686a.c Thu Dec 4 14:32:37 2003 @@ -496,21 +496,19 @@ via686a_update_client(client); return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])*100 ); } -/* more like overshoot temperature */ -static ssize_t show_temp_max(struct device *dev, char *buf, int nr) { +static ssize_t show_temp_over(struct device *dev, char *buf, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); via686a_update_client(client); return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])*100); } -/* more like hysteresis temperature */ -static ssize_t show_temp_min(struct device *dev, char *buf, int nr) { +static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); via686a_update_client(client); return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])*100); } -static ssize_t set_temp_max(struct device *dev, const char *buf, +static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); @@ -519,7 +517,7 @@ via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr), data->temp_over[nr]); return count; } -static ssize_t set_temp_min(struct device *dev, const char *buf, +static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); @@ -534,30 +532,30 @@ return show_temp(dev, buf, 0x##offset - 1); \ } \ static ssize_t \ -show_temp_##offset##_max (struct device *dev, char *buf) \ +show_temp_##offset##_over (struct device *dev, char *buf) \ { \ - return show_temp_max(dev, buf, 0x##offset - 1); \ + return show_temp_over(dev, buf, 0x##offset - 1); \ } \ static ssize_t \ -show_temp_##offset##_min (struct device *dev, char *buf) \ +show_temp_##offset##_hyst (struct device *dev, char *buf) \ { \ - return show_temp_min(dev, buf, 0x##offset - 1); \ + return show_temp_hyst(dev, buf, 0x##offset - 1); \ } \ -static ssize_t set_temp_##offset##_max (struct device *dev, \ +static ssize_t set_temp_##offset##_over (struct device *dev, \ const char *buf, size_t count) \ { \ - return set_temp_max(dev, buf, count, 0x##offset - 1); \ + return set_temp_over(dev, buf, count, 0x##offset - 1); \ } \ -static ssize_t set_temp_##offset##_min (struct device *dev, \ +static ssize_t set_temp_##offset##_hyst (struct device *dev, \ const char *buf, size_t count) \ { \ - return set_temp_min(dev, buf, count, 0x##offset - 1); \ + return set_temp_hyst(dev, buf, count, 0x##offset - 1); \ } \ static DEVICE_ATTR(temp_input##offset, S_IRUGO, show_temp_##offset, NULL) \ static DEVICE_ATTR(temp_max##offset, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_max, set_temp_##offset##_max) \ -static DEVICE_ATTR(temp_min##offset, S_IRUGO | S_IWUSR, \ - show_temp_##offset##_min, set_temp_##offset##_min) + show_temp_##offset##_over, set_temp_##offset##_over) \ +static DEVICE_ATTR(temp_hyst##offset, S_IRUGO | S_IWUSR, \ + show_temp_##offset##_hyst, set_temp_##offset##_hyst) show_temp_offset(1); show_temp_offset(2); @@ -637,14 +635,14 @@ show_fan_offset(1); show_fan_offset(2); -/* Alarm */ -static ssize_t show_alarm(struct device *dev, char *buf) { +/* Alarms */ +static ssize_t show_alarms(struct device *dev, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); via686a_update_client(client); return sprintf(buf,"%d\n", ALARMS_FROM_REG(data->alarms)); } -static DEVICE_ATTR(alarm, S_IRUGO | S_IWUSR, show_alarm, NULL); +static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL); /* The driver. I choose to use type i2c_driver, as at is identical to both smbus_driver and isa_driver, and clients could be of either kind */ @@ -760,16 +758,16 @@ device_create_file(&new_client->dev, &dev_attr_temp_max1); device_create_file(&new_client->dev, &dev_attr_temp_max2); device_create_file(&new_client->dev, &dev_attr_temp_max3); - device_create_file(&new_client->dev, &dev_attr_temp_min1); - device_create_file(&new_client->dev, &dev_attr_temp_min2); - device_create_file(&new_client->dev, &dev_attr_temp_min3); + device_create_file(&new_client->dev, &dev_attr_temp_hyst1); + device_create_file(&new_client->dev, &dev_attr_temp_hyst2); + device_create_file(&new_client->dev, &dev_attr_temp_hyst3); device_create_file(&new_client->dev, &dev_attr_fan_input1); device_create_file(&new_client->dev, &dev_attr_fan_input2); device_create_file(&new_client->dev, &dev_attr_fan_min1); device_create_file(&new_client->dev, &dev_attr_fan_min2); device_create_file(&new_client->dev, &dev_attr_fan_div1); device_create_file(&new_client->dev, &dev_attr_fan_div2); - device_create_file(&new_client->dev, &dev_attr_alarm); + device_create_file(&new_client->dev, &dev_attr_alarms); return 0; diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c --- a/drivers/i2c/chips/w83781d.c Thu Dec 4 14:32:37 2003 +++ b/drivers/i2c/chips/w83781d.c Thu Dec 4 14:32:37 2003 @@ -309,11 +309,11 @@ u8 fan[3]; /* Register value */ u8 fan_min[3]; /* Register value */ u8 temp; - u8 temp_min; /* Register value */ u8 temp_max; /* Register value */ + u8 temp_hyst; /* Register value */ u16 temp_add[2]; /* Register value */ u16 temp_max_add[2]; /* Register value */ - u16 temp_min_add[2]; /* Register value */ + u16 temp_hyst_add[2]; /* Register value */ u8 fan_div[3]; /* Register encoding, shifted right */ u8 vid; /* Register encoding, combined */ u32 alarms; /* Register encoding, combined */ @@ -510,8 +510,8 @@ } \ } show_temp_reg(temp); -show_temp_reg(temp_min); show_temp_reg(temp_max); +show_temp_reg(temp_hyst); #define store_temp_reg(REG, reg) \ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ @@ -538,8 +538,8 @@ \ return count; \ } -store_temp_reg(OVER, min); -store_temp_reg(HYST, max); +store_temp_reg(OVER, max); +store_temp_reg(HYST, hyst); #define sysfs_temp_offset(offset) \ static ssize_t \ @@ -562,8 +562,8 @@ #define sysfs_temp_offsets(offset) \ sysfs_temp_offset(offset); \ -sysfs_temp_reg_offset(min, offset); \ -sysfs_temp_reg_offset(max, offset); +sysfs_temp_reg_offset(max, offset); \ +sysfs_temp_reg_offset(hyst, offset); sysfs_temp_offsets(1); sysfs_temp_offsets(2); @@ -573,7 +573,7 @@ do { \ device_create_file(&client->dev, &dev_attr_temp_input##offset); \ device_create_file(&client->dev, &dev_attr_temp_max##offset); \ -device_create_file(&client->dev, &dev_attr_temp_min##offset); \ +device_create_file(&client->dev, &dev_attr_temp_hyst##offset); \ } while (0) static ssize_t @@ -1865,15 +1865,15 @@ } data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1)); - data->temp_min = - w83781d_read_value(client, W83781D_REG_TEMP_OVER(1)); data->temp_max = + w83781d_read_value(client, W83781D_REG_TEMP_OVER(1)); + data->temp_hyst = w83781d_read_value(client, W83781D_REG_TEMP_HYST(1)); data->temp_add[0] = w83781d_read_value(client, W83781D_REG_TEMP(2)); data->temp_max_add[0] = w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); - data->temp_min_add[0] = + data->temp_hyst_add[0] = w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); if (data->type != w83783s && data->type != w83697hf) { data->temp_add[1] = @@ -1881,7 +1881,7 @@ data->temp_max_add[1] = w83781d_read_value(client, W83781D_REG_TEMP_OVER(3)); - data->temp_min_add[1] = + data->temp_hyst_add[1] = w83781d_read_value(client, W83781D_REG_TEMP_HYST(3)); } diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h --- a/include/linux/i2c-id.h Thu Dec 4 14:32:37 2003 +++ b/include/linux/i2c-id.h Thu Dec 4 14:32:37 2003 @@ -153,6 +153,7 @@ #define I2C_DRIVERID_FS451 1037 #define I2C_DRIVERID_W83627HF 1038 #define I2C_DRIVERID_LM85 1039 +#define I2C_DRIVERID_LM83 1040 /* * ---- Adapter types ----------------------------------------------------