bk://kernel.bkbits.net/gregkh/linux/i2c-2.6 khali@linux-fr.org[gregkh]|ChangeSet|20050303001345|58372 khali # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/02 16:13:45-08:00 khali@linux-fr.org # [PATCH] I2C: Trivial indentation fix in i2c/chips/Kconfig # # Hi Greg, # # Quoting myself: # # > (...) I also think I see an indentation issue on the "tristate" line, # > seemingly copied from the SENSORS_DS1621 section which would need to # > be fixed as well. # # Here is the trivial patch fixing that, if you want to apply it. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/Kconfig # 2005/03/02 07:15:12-08:00 khali@linux-fr.org +1 -1 # I2C: Trivial indentation fix in i2c/chips/Kconfig # # ChangeSet # 2005/03/02 16:13:14-08:00 khali@linux-fr.org # [PATCH] I2C: Change of i2c co-maintainer # # Since I am working more actively than Philip (or anyone else, for that # matter) on the i2c subsystem these days, it would probably make sense # that I am listed as the co-maintainer instead of him. # # Signed-off-by: Jean Delvare # Acked-by: Philip Edelbrock # Signed-off-by: Greg Kroah-Hartman # # MAINTAINERS # 2005/03/02 10:50:04-08:00 khali@linux-fr.org +2 -2 # I2C: Change of i2c co-maintainer # # ChangeSet # 2005/03/02 15:50:42-08:00 gregkh@suse.de # [PATCH] I2C: fixed up the i2c-id.h algo ids. # # Thanks to Jean Delvare for the help with this. # # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c-id.h # 2005/03/02 15:48:37-08:00 gregkh@suse.de +9 -6 # I2C: fixed up the i2c-id.h algo ids. # # ChangeSet # 2005/03/02 15:03:48-08:00 khali@linux-fr.org # [PATCH] I2C: w83627hf needs i2c-isa # # The w83627hf driver is useless unless i2c-isa is present. All other # drivers in this case do select I2C_ISA through Kconfig, so this one # should as well do. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/Kconfig # 2005/03/02 09:54:07-08:00 khali@linux-fr.org +1 -0 # I2C: w83627hf needs i2c-isa # # ChangeSet # 2005/03/02 15:03:32-08:00 akpm@osdl.org # [PATCH] I2C: saa7146 build fix # # include/media/saa7146.h:160: parse error before `*' # include/media/saa7146.h:160: warning: function declaration isn't a prototype # # # Signed-off-by: Andrew Morton # Signed-off-by: Greg Kroah-Hartman # # include/media/saa7146.h # 2005/03/02 09:54:20-08:00 akpm@osdl.org +1 -1 # I2C: saa7146 build fix # # ChangeSet # 2005/03/02 15:03:15-08:00 khali@linux-fr.org # [PATCH] Add class definition to the elektor bus driver # # Hi Frank, all, # # > > Which bus driver are you using? It obviously lacks class declaration, # > > so the correct fix is to add the class there. # > # > The modules that are loading are (in reverse order): # > adm1031 # > ad5321 # > mic184 # > pca9540 # > i2c_sensor # > i2c_elektor # > i2c_algo_pcf # > i2c_core # > # > So I believe what you are asking for is the i2c_elektor driver for the # > PCF8584 ISA to I2C chip. # # Correct, I just checked and this one actually lacks its class. Patch # follows. # # This patch adds a class definition to the elektor i2c bus driver. # Without this definition, hardware monitoring chips located on such # busses cannot possibly be driven. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/busses/i2c-elektor.c # 2005/03/02 09:54:29-08:00 khali@linux-fr.org +1 -0 # Add class definition to the elektor bus driver # # ChangeSet # 2005/03/02 15:03:00-08:00 minyard@acm.org # [PATCH] I2C: minor I2C cleanups # # This is one in a series of patches for adding a non-blocking interface # to the I2C driver for supporting the IPMI SMBus driver. This patch is a # simply some minor cleanups and is in addition to the patch by Mickey # Stein (http://marc.theaimsgroup.com/?l=linux-kernel&m=110919738708916&w=2). # # Clean up some general I2C things. Fix some grammar and put () # around all the #defines that are compound to avoid nasty # side-effects. # # Signed-off-by: Corey Minyard # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c.h # 2005/03/02 09:54:36-08:00 minyard@acm.org +25 -25 # I2C: minor I2C cleanups # # ChangeSet # 2005/03/02 15:02:43-08:00 ben-linux@fluff.org # [PATCH] I2C: S3C2410 missing I2C_CLASS_HWMON # # None of the standard sensor drivers currently recognise the s3c24xx # I2C controller as it does not have I2C_CLASS_HWMON set in the # adapter class field. # # The attached patch initialises the adapter class to I2C_CLASS_HWMON # # Signed-off-by: Ben Dooks # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/busses/i2c-s3c2410.c # 2005/03/02 09:54:46-08:00 ben-linux@fluff.org +1 -0 # I2C: S3C2410 missing I2C_CLASS_HWMON # # ChangeSet # 2005/03/02 15:02:27-08:00 yekkim@pacbell.net # [PATCH] I2C: Fix some gcc 4.0 compile failures and warnings # # gcc 4.0.x cvs seems to dislike "include/linux/i2c.h file" and others due # to a current gcc 4.0.x change having to do with array declarations. # # Example error msg: include/linux/i2c.h:{55,194} error: array type has # incomplete element type # # A. Daplas has recently done a workaround for this on another header # file. A thread discussing this can be found by following the link below: # # http://gcc.gnu.org/ml/gcc/2005-02/msg00053.html # # The patch changes the array(struct i2c_msg) declaration used by # *i2c_transfer and *master_xfer from "struct i2c_msg msg[]" format to # "struct i2c_msg *msg". # # After some grepping, I came up with about a dozen files that used the # format disliked by gcc4 that're addressed by the attached patch. # Tested on gcc 3.x & gcc 4.x by configuring kernel with all i2c switches # enabled as module, and saw no errors or warnings in i2c. # # Signed-off-by: Mickey Stein # Signed-off-by: Greg Kroah-Hartman # # include/media/saa7146.h # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # include/linux/i2c.h # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +2 -2 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/video/saa7134/saa7134-i2c.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/video/bttv-i2c.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/dvb/b2c2/skystar2.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/media/common/saa7146_i2c.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +4 -4 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/i2c-core.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-s3c2410.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +2 -2 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-mpc.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-keywest.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-iop3xx.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-ibm_iic.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/busses/i2c-au1550.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/algos/i2c-algo-sgi.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/algos/i2c-algo-pcf.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/algos/i2c-algo-pca.c # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # drivers/i2c/algos/i2c-algo-ite.c # 2005/03/02 09:55:03-08:00 yekkim@pacbell.net +2 -2 # I2C: Fix some gcc 4.0 compile failures and warnings # # Documentation/i2c/writing-clients # 2005/03/02 09:55:02-08:00 yekkim@pacbell.net +1 -1 # I2C: Fix some gcc 4.0 compile failures and warnings # # ChangeSet # 2005/03/02 15:02:10-08:00 khali@linux-fr.org # [PATCH] I2C: Make i2c list terminators explicitely unsigned # # Shouldn't the i2c list terminators be explicitely declared as unsigned? # I'd hope it to help code analysis tools and possibly avoid false # positives. Coverity's SWAT pointed my attention to these constants. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c.h # 2005/03/02 09:55:12-08:00 khali@linux-fr.org +2 -2 # I2C: Make i2c list terminators explicitely unsigned # # ChangeSet # 2005/03/02 15:01:52-08:00 khali@linux-fr.org # [PATCH] I2C: Remove NULL client checks in rtc8564 driver # # Several functions in your rtc8564 driver verify the non-NULLity of the # i2c client that is passed to them. It doesn't seem to be necessary, as I # can't think of any case where these functions could possibly be called # with a NULL i2c client. As a matter of fact, I couldn't find any similar # driver doing such checks. # # My attention was brought on this by Coverity's SWAT which correctly # noticed that three of these functions contain explicit or hidden # dereferences of the i2c client pointer *before* the NULL check. I guess # it wasn't a problem because the NULL case cannot happen (unless I miss # something), but this still is confusing code. # # Thus I propose the following changes: # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/rtc8564.c # 2005/03/02 09:55:20-08:00 khali@linux-fr.org +8 -8 # I2C: Remove NULL client checks in rtc8564 driver # # ChangeSet # 2005/03/02 12:18:53-08:00 hfvogt@gmx.net # [PATCH] I2C i2c-nforce2: add support for nForce4 (patch against 2.6.11-rc4) # # can you please apply the attached patch (against 2.6.11-rc4, but works # as well for 2.6.11-rc3-mm2), that adds support for the two SMBusses of # the nForce4 to the i2c-nforce2 i2c bus driver. The patch is reported to # work on the standard nForce4 (i.e. non-Ultra, non-SLI), but I expect # that it works as well for the other nForce4 chipsets, that seem to have # the same PCI-id for the SMBus-device. # # This patch was proposed by Chuck , thanks to him for the # information, testing and his patch. # # Signed-off-by: Hans-Frieder Vogt # Signed-off-by: Greg Kroah-Hartman # # include/linux/pci_ids.h # 2005/03/02 09:55:27-08:00 hfvogt@gmx.net +1 -0 # I2C i2c-nforce2: add support for nForce4 (patch against 2.6.11-rc4) # # drivers/i2c/busses/i2c-nforce2.c # 2005/03/02 09:55:27-08:00 hfvogt@gmx.net +4 -2 # I2C i2c-nforce2: add support for nForce4 (patch against 2.6.11-rc4) # # ChangeSet # 2005/03/02 12:18:36-08:00 icampbell@arcom.com # [PATCH] I2C: fix typo in drivers/i2c/busses/i2c-ixp4xx.c # # I was looking at your ixp4xx gpio i2c driver for inspiration (for a # similar pxa2xx one) and I just happened to notice a tiny typo. # # Signed-off-by: Ian Campbell # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/busses/i2c-ixp4xx.c # 2005/03/02 09:55:39-08:00 icampbell@arcom.com +2 -2 # I2C: fix typo in drivers/i2c/busses/i2c-ixp4xx.c # # ChangeSet # 2005/03/02 12:18:19-08:00 macro@linux-mips.org # [PATCH] I2C: Enable I2C_PIIX4 for 64-bit platforms # # Is there any specific reason for the PIIX4 SMBus driver to be disabled on # 64-bit platforms? If not, then please apply the following change. The # MIPS Technologies Malta development board has the 82371EB chip and # supports 64-bit configurations. I've verified the driver to work # correctly using 64-bit kernels for both endiannesses. # # Signed-off-by: Maciej W. Rozycki # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/busses/Kconfig # 2005/03/02 09:55:46-08:00 macro@linux-mips.org +1 -1 # I2C: Enable I2C_PIIX4 for 64-bit platforms # # ChangeSet # 2005/03/02 12:18:03-08:00 icampbell@arcom.com # [PATCH] I2C: improve debugging output # # Rework the pca_xfer() function to always print the number of # successfully completed transfers in a series when debugging, even when # exiting with an error. # # Signed-off-by: Ian Campbell # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/algos/i2c-algo-pca.c # 2005/03/02 09:55:52-08:00 icampbell@arcom.com +16 -12 # I2C: improve debugging output # # ChangeSet # 2005/03/02 12:17:46-08:00 maartendeprez@scarlet.be # [PATCH] I2C: add GL520SM Sensor Chip driver # # Port of the Genesys Logic 520SM sensor chip driver from linux 2.4 # # Signed-off-by: Maarten Deprez # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/gl520sm.c # 2005/03/02 09:55:58-08:00 maartendeprez@scarlet.be +754 -0 # I2C: add GL520SM Sensor Chip driver # # drivers/i2c/chips/Makefile # 2005/03/02 09:55:58-08:00 maartendeprez@scarlet.be +1 -0 # I2C: add GL520SM Sensor Chip driver # # drivers/i2c/chips/Kconfig # 2005/03/02 09:55:58-08:00 maartendeprez@scarlet.be +11 -0 # I2C: add GL520SM Sensor Chip driver # # drivers/i2c/chips/gl520sm.c # 2005/03/02 09:55:58-08:00 maartendeprez@scarlet.be +0 -0 # BitKeeper file /home/greg/linux/BK/do/i2c-2.6/drivers/i2c/chips/gl520sm.c # # ChangeSet # 2005/03/02 12:17:29-08:00 mgreer@mvista.com # [PATCH] I2C: add Marvell mv64xxx i2c driver # # Marvell makes a line of host bridge for PPC and MIPS systems. On those # bridges is an i2c controller. This patch adds the driver for that i2c # controller. # # Please apply. # # Depends on patch submitted by Jean Delvare: # http://archives.andrew.net.au/lm-sensors/msg29405.html # # Signed-off-by: Mark A. Greer # Signed-off-by: Greg Kroah-Hartman # # include/linux/mv643xx.h # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +11 -6 # I2C: add Marvell mv64xxx i2c driver # # include/linux/i2c-id.h # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +3 -0 # I2C: add Marvell mv64xxx i2c driver # # drivers/i2c/busses/i2c-mv64xxx.c # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +596 -0 # I2C: add Marvell mv64xxx i2c driver # # drivers/i2c/busses/Makefile # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +1 -0 # I2C: add Marvell mv64xxx i2c driver # # drivers/i2c/busses/Kconfig # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +10 -0 # I2C: add Marvell mv64xxx i2c driver # # drivers/i2c/busses/i2c-mv64xxx.c # 2005/03/02 09:56:05-08:00 mgreer@mvista.com +0 -0 # BitKeeper file /home/greg/linux/BK/do/i2c-2.6/drivers/i2c/busses/i2c-mv64xxx.c # # ChangeSet # 2005/03/02 12:17:12-08:00 aurelien@aurel32.net # [PATCH] I2C: New chip driver: sis5595 # # Please find below the new version of the patch against kernel # 2.6.11-rc3-mm1 to add the sis5595 driver (sensor part). # # As you suggested, I have changed the PCI part of the driver, taking the # via686a driver as an example. I have also changed the comparison of # jiffies by using time_after. # # # Signed-off-by: Aurelien Jarno # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/sis5595.c # 2005/03/02 09:56:12-08:00 aurelien@aurel32.net +794 -0 # I2C: New chip driver: sis5595 # # drivers/i2c/chips/Makefile # 2005/03/02 09:56:12-08:00 aurelien@aurel32.net +1 -0 # I2C: New chip driver: sis5595 # # drivers/i2c/chips/Kconfig # 2005/03/02 09:56:12-08:00 aurelien@aurel32.net +12 -0 # I2C: New chip driver: sis5595 # # drivers/i2c/chips/sis5595.c # 2005/03/02 09:56:12-08:00 aurelien@aurel32.net +0 -0 # BitKeeper file /home/greg/linux/BK/do/i2c-2.6/drivers/i2c/chips/sis5595.c # # ChangeSet # 2005/03/02 12:16:55-08:00 mgreer@mvista.com # [PATCH] I2C: add ST M41T00 I2C RTC chip driver # # This patch adds support for the ST M41T00 I2C RTC chip. # # This rtc chip has no mechanism to freeze it's registers while being # read; however, it will delay updating the external values of the # registers for 250ms after a register is read. To ensure that a sane # time value is read, the driver verifies that the same registers values # were read twice before returning. # # Also, when setting the rtc from an interrupt handler, a tasklet is used # to provide the context required by the i2c core code. # # # Signed-off-by: Mark A. Greer # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/m41t00.c # 2005/03/02 09:56:19-08:00 mgreer@mvista.com +247 -0 # I2C: add ST M41T00 I2C RTC chip driver # # drivers/i2c/chips/Makefile # 2005/03/02 09:56:19-08:00 mgreer@mvista.com +1 -0 # I2C: add ST M41T00 I2C RTC chip driver # # drivers/i2c/chips/Kconfig # 2005/03/02 09:56:19-08:00 mgreer@mvista.com +9 -0 # I2C: add ST M41T00 I2C RTC chip driver # # drivers/i2c/chips/m41t00.c # 2005/03/02 09:56:19-08:00 mgreer@mvista.com +0 -0 # BitKeeper file /home/greg/linux/BK/do/i2c-2.6/drivers/i2c/chips/m41t00.c # # ChangeSet # 2005/03/02 12:16:37-08:00 adobriyan@mail.ru # [PATCH] I2C: use time_after instead of comparing jiffies # # Signed-off-by: Alexey Dobriyan # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83l785ts.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/w83781d.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/w83627hf.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/via686a.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/smsc47m1.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/smsc47b397.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/pc87360.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/max1619.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -4 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm90.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm87.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm85.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm83.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm80.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm78.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm77.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm75.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/lm63.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/it87.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/gl518sm.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/fscher.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/eeprom.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/ds1621.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/asb100.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/adm1031.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/adm1026.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +4 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/adm1025.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +2 -3 # I2C: use time_after instead of comparing jiffies # # drivers/i2c/chips/adm1021.c # 2005/03/02 09:56:26-08:00 adobriyan@mail.ru +3 -2 # I2C: use time_after instead of comparing jiffies # # ChangeSet # 2005/03/02 12:12:54-08:00 bunk@stusta.de # [PATCH] i2c-core.c: make some code static # # This patch makes some needlessly global code static. # # Signed-off-by: Adrian Bunk # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c.h # 2005/03/02 09:57:42-08:00 bunk@stusta.de +0 -2 # i2c-core.c: make some code static # # drivers/i2c/i2c-core.c # 2005/03/02 09:57:42-08:00 bunk@stusta.de +39 -40 # i2c-core.c: make some code static # # ChangeSet # 2005/03/02 12:10:18-08:00 shawn.starr@rogers.com # [PATCH] I2C: lm80 driver improvement # # Description: Cleanup some cluttered macros, add error checking for fan divisor value set. # # Signed-off-by: Sytse Wielinga # Signed-off-by: Aurelien Jarno # Signed-off-by: Shawn Starr # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/lm80.c # 2005/03/02 09:58:09-08:00 shawn.starr@rogers.com +12 -5 # I2C: lm80 driver improvement # # ChangeSet # 2005/03/02 12:10:01-08:00 mhoffman@lightlink.com # [PATCH] I2C: unnecessary #includes in asb100.c # # * Jean Delvare [2005-01-25 10:14:49 +0100]: # > Any reson why asb100.c (in linux 2.6.11-rc2) includes linux/ioport.h and # > asm/io.h? As an i2c-only chip driver, I don't think it needs these. # > # > As a side note, I also wonder what the inclusions of linux/config.h, # > linux/types.h and asm/errno.h are there for. # # Because they look pretty? Here's a patch Greg, please apply... # # Signed-off-by: Mark M. Hoffman # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/asb100.c # 2005/03/02 09:58:27-08:00 mhoffman@lightlink.com +0 -5 # I2C: unnecessary #includes in asb100.c # # ChangeSet # 2005/03/02 12:09:45-08:00 khali@linux-fr.org # [PATCH] I2C: Kill unused includes in i2c-sensor-detect.c # # Looks to me like i2c-sensor-detect.c includes a handful of headers it # doesn't need at all. This patch removes them. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/i2c-sensor-detect.c # 2005/03/02 09:58:33-08:00 khali@linux-fr.org +0 -7 # I2C: Kill unused includes in i2c-sensor-detect.c # # ChangeSet # 2005/03/02 12:09:28-08:00 khali@linux-fr.org # [PATCH] I2C: Enable w83781d and w83627hf temperature channels # # The chips supported by the w83781d and w83627hf drivers might come up # with their temperature channels disabled. Currently, the w83781d driver # does so for temp3 but omits temp2, while the w83627hf driver omits both. # The following patch fixes that, and prints warning messages when the # driver has to enable the channels (normally the BIOS should do it for # us). We also skip this initialization step for the AS99127F chips, for # which we have no documentation. # # This should hopefully solve the problem reported here: # http://archives.andrew.net.au/lm-sensors/msg29150.html # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83781d.c # 2005/03/02 09:58:47-08:00 khali@linux-fr.org +20 -3 # I2C: Enable w83781d and w83627hf temperature channels # # drivers/i2c/chips/w83627hf.c # 2005/03/02 09:58:47-08:00 khali@linux-fr.org +21 -0 # I2C: Enable w83781d and w83627hf temperature channels # # ChangeSet # 2005/03/02 12:04:28-08:00 aurelien@aurel32.net # [PATCH] I2C: lm78 driver improvement # # The following patch against kernel 2.6.11-rc2-mm1 improves the lm78 # driver. I used it as a model to port the sis5595 driver to the 2.6 # kernel, and I then applied the changes suggested by Jean Delvare on # the sis5595 driver to this one. # # # Signed-off-by: Aurelien Jarno # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/lm78.c # 2005/03/02 09:58:53-08:00 aurelien@aurel32.net +24 -29 # I2C: lm78 driver improvement # # ChangeSet # 2005/03/02 12:04:12-08:00 mhoffman@lightlink.com # [PATCH] I2C: i2c-dev namespace cleanup # # This patch is namespace cleanup for the i2c-dev module. Please apply. # # Signed-off-by Mark M. Hoffman # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/i2c-dev.c # 2005/03/02 09:59:08-08:00 mhoffman@lightlink.com +4 -4 # I2C: i2c-dev namespace cleanup # # ChangeSet # 2005/03/02 11:59:41-08:00 stefan@desire.ch # [PATCH] I2C: fix for fscpos voltage values # # Multiplied the voltage multipliers by 10 in order to comply with the sysfs # guidelines. # # Signed-off-by: Stefan Ott # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/fscpos.c # 2005/03/02 10:00:05-08:00 stefan@desire.ch +3 -3 # I2C: fix for fscpos voltage values # # ChangeSet # 2005/03/02 11:58:47-08:00 greg@kroah.com # [PATCH] I2C: just delete the id field, let's not delay it any longer # # Becides, sparse keeps complaining when it sees this attribute within a structure... # # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c.h # 2005/03/02 10:00:35-08:00 greg@kroah.com +0 -1 # I2C: just delete the id field, let's not delay it any longer # # ChangeSet # 2005/03/02 11:58:29-08:00 khali@linux-fr.org # [PATCH] I2C: Kill i2c_client.id (5/5) # # > (5/5) Documentation update. # # Finally, updates are required to the i2c/writing-client and # i2c/porting-client documents. Remove any reference to i2c_client id and # invite porters to discard that struct member. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # Documentation/i2c/writing-clients # 2005/03/02 10:00:42-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (5/5) # # Documentation/i2c/porting-clients # 2005/03/02 10:00:42-08:00 khali@linux-fr.org +3 -3 # I2C: Kill i2c_client.id (5/5) # # ChangeSet # 2005/03/02 11:52:48-08:00 khali@linux-fr.org # [PATCH] I2C: Kill i2c_client.id (4/5) # # > (4/5) Deprecate i2c_client.id. # # Now that i2c_client.id has no more users in the kernel (none that I # could find at least) we could remove that struct member. I however think # that it's better to only deprecate it at the moment, in case I missed # users or any of the other patches are delayed for some reason. We could # then delete the id member definitely in a month or so. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # include/linux/i2c.h # 2005/03/02 10:00:49-08:00 khali@linux-fr.org +1 -1 # I2C: Kill i2c_client.id (4/5) # # ChangeSet # 2005/03/02 11:52:31-08:00 khali@linux-fr.org # [PATCH] I2C: Kill i2c_client.id (3/5) # # (3/5) Stop using i2c_client.id in misc drivers. # # Affected drivers: # * acorn/char/pcf8583 # * acorn/char/i2c # * i2c/i2c-dev # * macintosh/therm_windtunnel # * sound/oss/dmasound/dac3550a # * sound/ppc/keywest # # The Acorn pcf8583 driver would give the i2c_client id the same value as # the i2c_driver id, and later test that client id (in i2c). I changed it # to test the client's driver id instead. The result is the same and the # client id is then useless and can be removed. # # All other drivers here would allocate the client id to some value and # then never use it. They are unaffected by the change. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # sound/ppc/keywest.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +0 -2 # I2C: Kill i2c_client.id (3/5) # # sound/oss/dmasound/dac3550a.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (3/5) # # drivers/macintosh/therm_windtunnel.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (3/5) # # drivers/i2c/i2c-dev.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (3/5) # # drivers/acorn/char/pcf8583.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (3/5) # # drivers/acorn/char/i2c.c # 2005/03/02 10:00:56-08:00 khali@linux-fr.org +1 -1 # I2C: Kill i2c_client.id (3/5) # # ChangeSet # 2005/03/02 11:52:15-08:00 khali@linux-fr.org # [PATCH] I2C: Kill i2c_client.id (2/5) # # (2/5) Stop using i2c_client.id in media/video drivers. # # Affected drivers: # * adv7170 # * adv7175 # * bt819 # * bt856 # * bttv # * cx88 # * ovcamchip # * saa5246a # * saa5249 # * saa7110 # * saa7111 # * saa7114 # * saa7134 # * saa7185 # * tda7432 # * tda9840 # * tda9875 # * tea6415c # * tea6420 # * tuner-3036 # * vpx3220 # # Most drivers here would include the id as part of their i2c client name # (e.g. adv7170[0]). This looks more like an habit than something really # needed, so I replaced the various printf by strlcpy, which should be # slightly faster. As said earlier, clients can be differenciated thanks # to their bus id and address if needed, so I don't think that including # this information in the client name is wise anyway. # # Other drivers would either set the id to -1 or to a unique value but # then never use it. These drivers are unaffected by the changes. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/media/video/vpx3220.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +8 -11 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tuner-3036.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tea6420.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tea6415c.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tda9875.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tda9840.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/tda7432.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa7185.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa7134/saa7134-i2c.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa7114.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa7111.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa7110.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa5249.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/saa5246a.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/ovcamchip/ovcamchip_core.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/cx88/cx88-i2c.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/bttv-i2c.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/bt856.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/bt819.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +3 -8 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/adv7175.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # drivers/media/video/adv7170.c # 2005/03/02 10:01:03-08:00 khali@linux-fr.org +1 -4 # I2C: Kill i2c_client.id (2/5) # # ChangeSet # 2005/03/02 11:51:51-08:00 khali@linux-fr.org # [PATCH] I2C: Kill i2c_client.id (1/5) # # (1/5) Stop using i2c_client.id in i2c/chips drivers (mostly hardware # monitoring drivers). # # Drivers affected: # * adm1021 # * adm1025 # * adm1026 # * adm1031 # * ds1621 # * fscher # * gl518sm # * isp1301_omap # * lm75 # * lm77 # * lm80 # * lm83 # * lm85 # * lm87 # * lm90 # * max1619 # * pcf8574 # * pcf8591 # * rtc8564 # * smsc47m1 # * w83l785ts # # The vast majority of these drivers simply defined the i2c_client id # struct member but never used it, so they are not affected at all by the # change. Exceptions are: # # * lm85 and rtc8564, which would at least display the id in a debug # message when assigning it. Not really useful though, as the id was then # never used. # # * adm1026, which used the assigned id in all driver messages. However, # since dev_* calls will append the bus number and client address to these # messages, the id information is redundant and can go away. Also, the # driver would allow some GPIO reprogramming on the first client only # (id=0) and removing the id doesn't allow that anymore. I would restore a # similar functionality if needed, but the ADM1026 chip is found on very # few motherboards and none of these has more than one ADM1026 chip AFAIK, # so it doesn't seem to be worth the effort. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/w83l785ts.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/smsc47m1.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -5 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/rtc8564.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -2 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/pcf8591.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/pcf8574.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/max1619.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm90.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm87.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm85.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -9 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm83.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm80.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -8 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm77.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/lm75.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/isp1301_omap.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -1 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/gl518sm.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/fscher.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/ds1621.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/adm1031.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/adm1026.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +32 -48 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/adm1025.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -7 # I2C: Kill i2c_client.id (1/5) # # drivers/i2c/chips/adm1021.c # 2005/03/02 10:01:11-08:00 khali@linux-fr.org +0 -4 # I2C: Kill i2c_client.id (1/5) # # ChangeSet # 2005/03/02 11:51:21-08:00 greg@kroah.com # [PATCH] I2C: Fix up some build warnings in the fscpos driver. # # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/fscpos.c # 2005/03/02 10:01:19-08:00 greg@kroah.com +1 -3 # I2C: Fix up some build warnings in the fscpos driver. # # ChangeSet # 2005/03/02 11:50:10-08:00 khali@linux-fr.org # [PATCH] I2C: Allow it87 pwm reconfiguration # # Quoting myself: # # > As soon as you will have confirmed that everything worked as expected, # > Jonas and I will provide a patch adding a pwm polarity reconfiguration # > module parameter for you to test. This should give you access to the # > PWM features of your it87 chip again, but in a safe way for a change # > ;) # # Here comes this patch. The new "fix_pwm_polarity" module parameter # allows one to force the it87 chip reconfiguration. This is only # supported in the case the original PWM configuration is suspected to be # bogus, and only if we think that reconfiguring the chip is safe. # # I wish to thank Rudolf Marek and Jonas Munsin again for their testing # and review of my code. # # Signed-off-by: Jean Delvare # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/it87.c # 2005/03/02 10:01:25-08:00 khali@linux-fr.org +59 -12 # I2C: Allow it87 pwm reconfiguration # # ChangeSet # 2005/03/02 11:04:17-08:00 stefan@desire.ch # [PATCH] I2C: add fscpos chip driver # # This patch against 2.6.11-rc1 contains a driver for fscpos sensors. # # Signed-off-by: Stefan Ott # Signed-off-by: Greg Kroah-Hartman # # drivers/i2c/chips/Makefile # 2005/03/02 10:01:31-08:00 stefan@desire.ch +1 -0 # I2C: add fscpos chip driver # # drivers/i2c/chips/Kconfig # 2005/03/02 10:01:31-08:00 stefan@desire.ch +11 -0 # I2C: add fscpos chip driver # # drivers/i2c/chips/fscpos.c # 2005/03/02 10:01:31-08:00 stefan@desire.ch +633 -0 # I2C: add fscpos chip driver # # drivers/i2c/chips/fscpos.c # 2005/03/02 10:01:31-08:00 stefan@desire.ch +0 -0 # BitKeeper file /home/greg/linux/BK/do/i2c-2.6/drivers/i2c/chips/fscpos.c # diff -Nru a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients --- a/Documentation/i2c/porting-clients 2005-03-03 21:57:36 -08:00 +++ b/Documentation/i2c/porting-clients 2005-03-03 21:57:36 -08:00 @@ -49,9 +49,8 @@ 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 + and functions). Instead, 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 @@ -86,6 +85,7 @@ Replace the sysctl directory registration by calls to device_create_file. Move the driver initialization before any sysfs file creation. + Drop client->id. * [Init] Limits must not be set by the driver (can be done later in user-space). Chip should not be reset default (although a module diff -Nru a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients --- a/Documentation/i2c/writing-clients 2005-03-03 21:57:36 -08:00 +++ b/Documentation/i2c/writing-clients 2005-03-03 21:57:36 -08:00 @@ -344,9 +344,6 @@ For now, you can ignore the `flags' parameter. It is there for future use. - /* Unique ID allocation */ - static int foo_id = 0; - int foo_detect_client(struct i2c_adapter *adapter, int address, unsigned short flags, int kind) { @@ -482,7 +479,6 @@ data->type = kind; /* SENSORS ONLY END */ - new_client->id = foo_id++; /* Automatically unique */ data->valid = 0; /* Only if you use this field */ init_MUTEX(&data->update_lock); /* Only if you use this field */ @@ -642,7 +638,7 @@ parameter contains the bytes the read/write, the third the length of the buffer. Returned is the actual number of bytes read/written. - extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], + extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num); This sends a series of messages. Each message can be a read or write, diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS 2005-03-03 21:57:36 -08:00 +++ b/MAINTAINERS 2005-03-03 21:57:36 -08:00 @@ -991,8 +991,8 @@ I2C AND SENSORS DRIVERS P: Greg Kroah-Hartman M: greg@kroah.com -P: Philip Edelbrock -M: phil@netroedge.com +P: Jean Delvare +M: khali@linux-fr.org L: sensors@stimpy.netroedge.com W: http://www.lm-sensors.nu/ S: Maintained diff -Nru a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c --- a/drivers/acorn/char/i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/acorn/char/i2c.c 2005-03-03 21:57:36 -08:00 @@ -313,7 +313,7 @@ static int ioc_client_reg(struct i2c_client *client) { - if (client->id == I2C_DRIVERID_PCF8583 && + if (client->driver->id == I2C_DRIVERID_PCF8583 && client->addr == 0x50) { struct rtc_tm rtctm; unsigned int year; diff -Nru a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c --- a/drivers/acorn/char/pcf8583.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/acorn/char/pcf8583.c 2005-03-03 21:57:36 -08:00 @@ -51,7 +51,6 @@ return -ENOMEM; memset(c, 0, sizeof(*c)); - c->id = pcf8583_driver.id; c->addr = addr; c->adapter = adap; c->driver = &pcf8583_driver; diff -Nru a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c --- a/drivers/i2c/algos/i2c-algo-ite.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/algos/i2c-algo-ite.c 2005-03-03 21:57:36 -08:00 @@ -490,7 +490,7 @@ * condition. */ #if 0 -static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { int i; struct i2c_msg *pmsg; @@ -600,7 +600,7 @@ * verify that the bus is not busy or in some unknown state. */ static int iic_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], + struct i2c_msg *msgs, int num) { struct i2c_algo_iic_data *adap = i2c_adap->algo_data; diff -Nru a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c --- a/drivers/i2c/algos/i2c-algo-pca.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/algos/i2c-algo-pca.c 2005-03-03 21:57:36 -08:00 @@ -178,7 +178,7 @@ } static int pca_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], + struct i2c_msg *msgs, int num) { struct i2c_algo_pca_data *adap = i2c_adap->algo_data; @@ -186,6 +186,7 @@ int curmsg; int numbytes = 0; int state; + int ret; state = pca_status(adap); if ( state != 0xF8 ) { @@ -218,6 +219,7 @@ } curmsg = 0; + ret = -EREMOTEIO; while (curmsg < num) { state = pca_status(adap); @@ -251,7 +253,7 @@ case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+W\n"); pca_stop(adap); - return -EREMOTEIO; + goto out; case 0x40: /* SLA+R has been transmitted; ACK has been received */ pca_rx_ack(adap, msg->len > 1); @@ -263,7 +265,7 @@ numbytes++; pca_rx_ack(adap, numbytes < msg->len - 1); break; - } + } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); @@ -274,15 +276,15 @@ case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+R\n"); pca_stop(adap); - return -EREMOTEIO; + goto out; case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after data byte\n"); - return -EREMOTEIO; + goto out; case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ DEB2("Arbitration lost\n"); - return -EREMOTEIO; + goto out; case 0x58: /* Data byte has been received; NOT ACK has been returned */ if ( numbytes == msg->len - 1 ) { @@ -297,21 +299,21 @@ "Not final byte. numbytes %d. len %d\n", numbytes, msg->len); pca_stop(adap); - return -EREMOTEIO; + goto out; } break; case 0x70: /* Bus error - SDA stuck low */ DEB2("BUS ERROR - SDA Stuck low\n"); pca_reset(adap); - return -EREMOTEIO; + goto out; case 0x90: /* Bus error - SCL stuck low */ DEB2("BUS ERROR - SCL Stuck low\n"); pca_reset(adap); - return -EREMOTEIO; + goto out; case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */ DEB2("BUS ERROR - Illegal START or STOP\n"); pca_reset(adap); - return -EREMOTEIO; + goto out; default: printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state); break; @@ -319,11 +321,13 @@ } - DEB1(KERN_CRIT "}}} transfered %d messages. " + ret = curmsg; + out: + DEB1(KERN_CRIT "}}} transfered %d/%d messages. " "status is %#04x. control is %#04x\n", - num, pca_status(adap), + curmsg, num, pca_status(adap), pca_get_con(adap)); - return curmsg; + return ret; } static u32 pca_func(struct i2c_adapter *adap) diff -Nru a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c --- a/drivers/i2c/algos/i2c-algo-pcf.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/algos/i2c-algo-pcf.c 2005-03-03 21:57:36 -08:00 @@ -332,7 +332,7 @@ } static int pcf_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], + struct i2c_msg *msgs, int num) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; diff -Nru a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c --- a/drivers/i2c/algos/i2c-algo-sgi.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/algos/i2c-algo-sgi.c 2005-03-03 21:57:36 -08:00 @@ -131,7 +131,7 @@ return 0; } -static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], +static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct i2c_algo_sgi_data *adap = i2c_adap->algo_data; diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig --- a/drivers/i2c/busses/Kconfig 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/Kconfig 2005-03-03 21:57:36 -08:00 @@ -287,7 +287,7 @@ config I2C_PIIX4 tristate "Intel PIIX4" - depends on I2C && PCI && EXPERIMENTAL && !64BIT + depends on I2C && PCI && EXPERIMENTAL help If you say yes to this option, support will be included for the Intel PIIX4 family of mainboard I2C interfaces. Specifically, the following @@ -485,5 +485,15 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. + +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges. + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. endmenu diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile --- a/drivers/i2c/busses/Makefile 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/Makefile 2005-03-03 21:57:36 -08:00 @@ -21,6 +21,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o diff -Nru a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c --- a/drivers/i2c/busses/i2c-au1550.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-au1550.c 2005-03-03 21:57:36 -08:00 @@ -253,7 +253,7 @@ } static int -au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct i2c_au1550_data *adap = i2c_adap->algo_data; struct i2c_msg *p; diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c --- a/drivers/i2c/busses/i2c-elektor.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-elektor.c 2005-03-03 21:57:36 -08:00 @@ -183,6 +183,7 @@ static struct i2c_adapter pcf_isa_ops = { .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, .id = I2C_HW_P_ELEK, .algo_data = &pcf_isa_data, .name = "PCF8584 ISA adapter", diff -Nru a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c --- a/drivers/i2c/busses/i2c-ibm_iic.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-ibm_iic.c 2005-03-03 21:57:36 -08:00 @@ -549,7 +549,7 @@ * Generic master transfer entrypoint. * Returns the number of processed messages or error (<0) */ -static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap)); volatile struct iic_regs __iomem *iic = dev->vaddr; diff -Nru a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c --- a/drivers/i2c/busses/i2c-iop3xx.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-iop3xx.c 2005-03-03 21:57:36 -08:00 @@ -361,7 +361,7 @@ * master_xfer() - main read/write entry */ static int -iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], +iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; diff -Nru a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c --- a/drivers/i2c/busses/i2c-ixp4xx.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-ixp4xx.c 2005-03-03 21:57:36 -08:00 @@ -133,8 +133,8 @@ drv_data->algo_data.mdelay = 10; drv_data->algo_data.timeout = 100; - drv_data->adapter.id = I2C_HW_B_IXP4XX, - drv_data->adapter.algo_data = &drv_data->algo_data, + drv_data->adapter.id = I2C_HW_B_IXP4XX; + drv_data->adapter.algo_data = &drv_data->algo_data; drv_data->adapter.dev.parent = &plat_dev->dev; diff -Nru a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c --- a/drivers/i2c/busses/i2c-keywest.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-keywest.c 2005-03-03 21:57:36 -08:00 @@ -399,7 +399,7 @@ */ static int keywest_xfer( struct i2c_adapter *adap, - struct i2c_msg msgs[], + struct i2c_msg *msgs, int num) { struct keywest_chan* chan = i2c_get_adapdata(adap); diff -Nru a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c --- a/drivers/i2c/busses/i2c-mpc.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-mpc.c 2005-03-03 21:57:36 -08:00 @@ -233,7 +233,7 @@ return length; } -static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct i2c_msg *pmsg; int i; diff -Nru a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/i2c/busses/i2c-mv64xxx.c 2005-03-03 21:57:36 -08:00 @@ -0,0 +1,596 @@ +/* + * drivers/i2c/busses/i2c-mv64xxx.c + * + * Driver for the i2c controller on the Marvell line of host bridges for MIPS + * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). + * + * Author: Mark A. Greer + * + * 2005 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include +#include +#include +#include +#include + +/* Register defines */ +#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00 +#define MV64XXX_I2C_REG_DATA 0x04 +#define MV64XXX_I2C_REG_CONTROL 0x08 +#define MV64XXX_I2C_REG_STATUS 0x0c +#define MV64XXX_I2C_REG_BAUD 0x0c +#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10 +#define MV64XXX_I2C_REG_SOFT_RESET 0x1c + +#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004 +#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008 +#define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010 +#define MV64XXX_I2C_REG_CONTROL_START 0x00000020 +#define MV64XXX_I2C_REG_CONTROL_TWSIEN 0x00000040 +#define MV64XXX_I2C_REG_CONTROL_INTEN 0x00000080 + +/* Ctlr status values */ +#define MV64XXX_I2C_STATUS_BUS_ERR 0x00 +#define MV64XXX_I2C_STATUS_MAST_START 0x08 +#define MV64XXX_I2C_STATUS_MAST_REPEAT_START 0x10 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK 0x18 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20 +#define MV64XXX_I2C_STATUS_MAST_WR_ACK 0x28 +#define MV64XXX_I2C_STATUS_MAST_WR_NO_ACK 0x30 +#define MV64XXX_I2C_STATUS_MAST_LOST_ARB 0x38 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK 0x40 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48 +#define MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK 0x50 +#define MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8 +#define MV64XXX_I2C_STATUS_NO_STATUS 0xf8 + +/* Driver states */ +enum { + MV64XXX_I2C_STATE_INVALID, + MV64XXX_I2C_STATE_IDLE, + MV64XXX_I2C_STATE_WAITING_FOR_START_COND, + MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK, + MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, + MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, + MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, + MV64XXX_I2C_STATE_ABORTING, +}; + +/* Driver actions */ +enum { + MV64XXX_I2C_ACTION_INVALID, + MV64XXX_I2C_ACTION_CONTINUE, + MV64XXX_I2C_ACTION_SEND_START, + MV64XXX_I2C_ACTION_SEND_ADDR_1, + MV64XXX_I2C_ACTION_SEND_ADDR_2, + MV64XXX_I2C_ACTION_SEND_DATA, + MV64XXX_I2C_ACTION_RCV_DATA, + MV64XXX_I2C_ACTION_RCV_DATA_STOP, + MV64XXX_I2C_ACTION_SEND_STOP, +}; + +struct mv64xxx_i2c_data { + int irq; + u32 state; + u32 action; + u32 cntl_bits; + void __iomem *reg_base; + u32 reg_base_p; + u32 addr1; + u32 addr2; + u32 bytes_left; + u32 byte_posn; + u32 block; + int rc; + u32 freq_m; + u32 freq_n; + wait_queue_head_t waitq; + spinlock_t lock; + struct i2c_msg *msg; + struct i2c_adapter adapter; +}; + +/* + ***************************************************************************** + * + * Finite State Machine & Interrupt Routines + * + ***************************************************************************** + */ +static void +mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) +{ + /* + * If state is idle, then this is likely the remnants of an old + * operation that driver has given up on or the user has killed. + * If so, issue the stop condition and go to idle. + */ + if (drv_data->state == MV64XXX_I2C_STATE_IDLE) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + return; + } + + if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + return; + } + + /* The status from the ctlr [mostly] tells us what to do next */ + switch (status) { + /* Start condition interrupt */ + case MV64XXX_I2C_STATUS_MAST_START: /* 0x08 */ + case MV64XXX_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */ + drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_1; + drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK; + break; + + /* Performing a write */ + case MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */ + if (drv_data->msg->flags & I2C_M_TEN) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2; + drv_data->state = + MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK; + break; + } + /* FALLTHRU */ + case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ + case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ + if (drv_data->bytes_left > 0) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; + drv_data->state = + MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; + drv_data->bytes_left--; + } else { + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + } + break; + + /* Performing a read */ + case MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */ + if (drv_data->msg->flags & I2C_M_TEN) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_ADDR_2; + drv_data->state = + MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK; + break; + } + /* FALLTHRU */ + case MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */ + if (drv_data->bytes_left == 0) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + break; + } + /* FALLTHRU */ + case MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */ + if (status != MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK) + drv_data->action = MV64XXX_I2C_ACTION_CONTINUE; + else { + drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA; + drv_data->bytes_left--; + } + drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; + + if (drv_data->bytes_left == 1) + drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; + break; + + case MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */ + drv_data->action = MV64XXX_I2C_ACTION_RCV_DATA_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + break; + + case MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */ + case MV64XXX_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */ + case MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */ + /* Doesn't seem to be a device at other end */ + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + drv_data->rc = -ENODEV; + break; + + default: + dev_err(&drv_data->adapter.dev, + "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " + "status: 0x%x, addr: 0x%x, flags: 0x%x\n", + drv_data->state, status, drv_data->msg->addr, + drv_data->msg->flags); + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE; + drv_data->rc = -EIO; + } +} + +static void +mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) +{ + switch(drv_data->action) { + case MV64XXX_I2C_ACTION_CONTINUE: + writel(drv_data->cntl_bits, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_SEND_START: + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_SEND_ADDR_1: + writel(drv_data->addr1, + drv_data->reg_base + MV64XXX_I2C_REG_DATA); + writel(drv_data->cntl_bits, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_SEND_ADDR_2: + writel(drv_data->addr2, + drv_data->reg_base + MV64XXX_I2C_REG_DATA); + writel(drv_data->cntl_bits, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_SEND_DATA: + writel(drv_data->msg->buf[drv_data->byte_posn++], + drv_data->reg_base + MV64XXX_I2C_REG_DATA); + writel(drv_data->cntl_bits, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_RCV_DATA: + drv_data->msg->buf[drv_data->byte_posn++] = + readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA); + writel(drv_data->cntl_bits, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + break; + + case MV64XXX_I2C_ACTION_RCV_DATA_STOP: + drv_data->msg->buf[drv_data->byte_posn++] = + readl(drv_data->reg_base + MV64XXX_I2C_REG_DATA); + drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + drv_data->block = 0; + wake_up_interruptible(&drv_data->waitq); + break; + + case MV64XXX_I2C_ACTION_INVALID: + default: + dev_err(&drv_data->adapter.dev, + "mv64xxx_i2c_do_action: Invalid action: %d\n", + drv_data->action); + drv_data->rc = -EIO; + /* FALLTHRU */ + case MV64XXX_I2C_ACTION_SEND_STOP: + drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN; + writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + drv_data->block = 0; + wake_up_interruptible(&drv_data->waitq); + break; + } +} + +static int +mv64xxx_i2c_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct mv64xxx_i2c_data *drv_data = dev_id; + unsigned long flags; + u32 status; + int rc = IRQ_NONE; + + spin_lock_irqsave(&drv_data->lock, flags); + while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) & + MV64XXX_I2C_REG_CONTROL_IFLG) { + status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS); + mv64xxx_i2c_fsm(drv_data, status); + mv64xxx_i2c_do_action(drv_data); + rc = IRQ_HANDLED; + } + spin_unlock_irqrestore(&drv_data->lock, flags); + + return rc; +} + +/* + ***************************************************************************** + * + * I2C Msg Execution Routines + * + ***************************************************************************** + */ +static void +mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, + struct i2c_msg *msg) +{ + u32 dir = 0; + + drv_data->msg = msg; + drv_data->byte_posn = 0; + drv_data->bytes_left = msg->len; + drv_data->rc = 0; + drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | + MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; + + if (msg->flags & I2C_M_RD) + dir = 1; + + if (msg->flags & I2C_M_REV_DIR_ADDR) + dir ^= 1; + + if (msg->flags & I2C_M_TEN) { + drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir; + drv_data->addr2 = (u32)msg->addr & 0xff; + } else { + drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir; + drv_data->addr2 = 0; + } +} + +static void +mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) +{ + long time_left; + unsigned long flags; + char abort = 0; + + time_left = wait_event_interruptible_timeout(drv_data->waitq, + !drv_data->block, msecs_to_jiffies(drv_data->adapter.timeout)); + + spin_lock_irqsave(&drv_data->lock, flags); + if (!time_left) { /* Timed out */ + drv_data->rc = -ETIMEDOUT; + abort = 1; + } else if (time_left < 0) { /* Interrupted/Error */ + drv_data->rc = time_left; /* errno value */ + abort = 1; + } + + if (abort && drv_data->block) { + drv_data->state = MV64XXX_I2C_STATE_ABORTING; + spin_unlock_irqrestore(&drv_data->lock, flags); + + time_left = wait_event_timeout(drv_data->waitq, + !drv_data->block, + msecs_to_jiffies(drv_data->adapter.timeout)); + + if (time_left <= 0) { + drv_data->state = MV64XXX_I2C_STATE_IDLE; + dev_err(&drv_data->adapter.dev, + "mv64xxx: I2C bus locked\n"); + } + } else + spin_unlock_irqrestore(&drv_data->lock, flags); +} + +static int +mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg) +{ + unsigned long flags; + + spin_lock_irqsave(&drv_data->lock, flags); + mv64xxx_i2c_prepare_for_io(drv_data, msg); + + if (unlikely(msg->flags & I2C_M_NOSTART)) { /* Skip start/addr phases */ + if (drv_data->msg->flags & I2C_M_RD) { + /* No action to do, wait for slave to send a byte */ + drv_data->action = MV64XXX_I2C_ACTION_CONTINUE; + drv_data->state = + MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; + } else { + drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; + drv_data->state = + MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; + drv_data->bytes_left--; + } + } else { + drv_data->action = MV64XXX_I2C_ACTION_SEND_START; + drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; + } + + drv_data->block = 1; + mv64xxx_i2c_do_action(drv_data); + spin_unlock_irqrestore(&drv_data->lock, flags); + + mv64xxx_i2c_wait_for_completion(drv_data); + return drv_data->rc; +} + +/* + ***************************************************************************** + * + * I2C Core Support Routines (Interface to higher level I2C code) + * + ***************************************************************************** + */ +static u32 +mv64xxx_i2c_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SMBUS_EMUL; +} + +static int +mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +{ + struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); + int i, rc = 0; + + for (i=0; ireg_base + MV64XXX_I2C_REG_SOFT_RESET); + writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)), + drv_data->reg_base + MV64XXX_I2C_REG_BAUD); + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_SLAVE_ADDR); + writel(0, drv_data->reg_base + MV64XXX_I2C_REG_EXT_SLAVE_ADDR); + writel(MV64XXX_I2C_REG_CONTROL_TWSIEN | MV64XXX_I2C_REG_CONTROL_STOP, + drv_data->reg_base + MV64XXX_I2C_REG_CONTROL); + drv_data->state = MV64XXX_I2C_STATE_IDLE; +} + +static int __devinit +mv64xxx_i2c_map_regs(struct platform_device *pd, + struct mv64xxx_i2c_data *drv_data) +{ + struct resource *r; + + if ((r = platform_get_resource(pd, IORESOURCE_MEM, 0)) && + request_mem_region(r->start, MV64XXX_I2C_REG_BLOCK_SIZE, + drv_data->adapter.name)) { + + drv_data->reg_base = ioremap(r->start, + MV64XXX_I2C_REG_BLOCK_SIZE); + drv_data->reg_base_p = r->start; + } else + return -ENOMEM; + + return 0; +} + +static void __devexit +mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) +{ + if (drv_data->reg_base) { + iounmap(drv_data->reg_base); + release_mem_region(drv_data->reg_base_p, + MV64XXX_I2C_REG_BLOCK_SIZE); + } + + drv_data->reg_base = NULL; + drv_data->reg_base_p = 0; +} + +static int __devinit +mv64xxx_i2c_probe(struct device *dev) +{ + struct platform_device *pd = to_platform_device(dev); + struct mv64xxx_i2c_data *drv_data; + struct mv64xxx_i2c_pdata *pdata = dev->platform_data; + int rc; + + if ((pd->id != 0) || !pdata) + return -ENODEV; + + drv_data = kmalloc(sizeof(struct mv64xxx_i2c_data), GFP_KERNEL); + + if (!drv_data) + return -ENOMEM; + + memset(drv_data, 0, sizeof(struct mv64xxx_i2c_data)); + + if (mv64xxx_i2c_map_regs(pd, drv_data)) { + rc = -ENODEV; + goto exit_kfree; + } + + strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", + I2C_NAME_SIZE); + + init_waitqueue_head(&drv_data->waitq); + spin_lock_init(&drv_data->lock); + + drv_data->freq_m = pdata->freq_m; + drv_data->freq_n = pdata->freq_n; + drv_data->irq = platform_get_irq(pd, 0); + drv_data->adapter.id = I2C_ALGO_MV64XXX | I2C_HW_MV64XXX; + drv_data->adapter.algo = &mv64xxx_i2c_algo; + drv_data->adapter.timeout = pdata->timeout; + drv_data->adapter.retries = pdata->retries; + dev_set_drvdata(dev, drv_data); + i2c_set_adapdata(&drv_data->adapter, drv_data); + + if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0, + MV64XXX_I2C_CTLR_NAME, drv_data)) { + + dev_err(dev, "mv64xxx: Can't register intr handler " + "irq: %d\n", drv_data->irq); + rc = -EINVAL; + goto exit_unmap_regs; + } else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) { + dev_err(dev, "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc); + goto exit_free_irq; + } + + mv64xxx_i2c_hw_init(drv_data); + + return 0; + + exit_free_irq: + free_irq(drv_data->irq, drv_data); + exit_unmap_regs: + mv64xxx_i2c_unmap_regs(drv_data); + exit_kfree: + kfree(drv_data); + return rc; +} + +static int __devexit +mv64xxx_i2c_remove(struct device *dev) +{ + struct mv64xxx_i2c_data *drv_data = dev_get_drvdata(dev); + int rc; + + rc = i2c_del_adapter(&drv_data->adapter); + free_irq(drv_data->irq, drv_data); + mv64xxx_i2c_unmap_regs(drv_data); + kfree(drv_data); + + return rc; +} + +static struct device_driver mv64xxx_i2c_driver = { + .name = MV64XXX_I2C_CTLR_NAME, + .bus = &platform_bus_type, + .probe = mv64xxx_i2c_probe, + .remove = mv64xxx_i2c_remove, +}; + +static int __init +mv64xxx_i2c_init(void) +{ + return driver_register(&mv64xxx_i2c_driver); +} + +static void __exit +mv64xxx_i2c_exit(void) +{ + driver_unregister(&mv64xxx_i2c_driver); +} + +module_init(mv64xxx_i2c_init); +module_exit(mv64xxx_i2c_exit); + +MODULE_AUTHOR("Mark A. Greer "); +MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c --- a/drivers/i2c/busses/i2c-nforce2.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-nforce2.c 2005-03-03 21:57:36 -08:00 @@ -29,9 +29,10 @@ nForce2 Ultra 400 MCP 0084 nForce3 Pro150 MCP 00D4 nForce3 250Gb MCP 00E4 + nForce4 MCP 0052 - This driver supports the 2 SMBuses that are included in the MCP2 of the - nForce2 chipset. + This driver supports the 2 SMBuses that are included in the MCP of the + nForce2/3/4 chipsets. */ /* Note: we assume there can only be one nForce2, with two SMBus interfaces */ @@ -295,6 +296,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, { 0 } }; diff -Nru a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c --- a/drivers/i2c/busses/i2c-s3c2410.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/busses/i2c-s3c2410.c 2005-03-03 21:57:36 -08:00 @@ -483,7 +483,7 @@ * this starts an i2c transfer */ -static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg msgs[], int num) +static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int num) { unsigned long timeout; int ret; @@ -534,7 +534,7 @@ */ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap, - struct i2c_msg msgs[], int num) + struct i2c_msg *msgs, int num) { struct s3c24xx_i2c *i2c = (struct s3c24xx_i2c *)adap->algo_data; int retry; @@ -569,6 +569,7 @@ .name = "s3c2410-i2c", .algo = &s3c24xx_i2c_algorithm, .retries = 2, + .class = I2C_CLASS_HWMON, }, }; diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig --- a/drivers/i2c/chips/Kconfig 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/Kconfig 2005-03-03 21:57:36 -08:00 @@ -63,7 +63,7 @@ will be called asb100. config SENSORS_DS1621 - tristate "Dallas Semiconductor DS1621 and DS1625" + tristate "Dallas Semiconductor DS1621 and DS1625" depends on I2C && EXPERIMENTAL select I2C_SENSOR help @@ -84,6 +84,17 @@ This driver can also be built as a module. If so, the module will be called fscher. +config SENSORS_FSCPOS + tristate "FSC Poseidon" + depends on I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Fujitsu Siemens + Computers Poseidon sensor chips. + + This driver can also be built as a module. If so, the module + will be called fscpos. + config SENSORS_GL518SM tristate "Genesys Logic GL518SM" depends on I2C && EXPERIMENTAL @@ -95,6 +106,17 @@ This driver can also be built as a module. If so, the module will be called gl518sm. +config SENSORS_GL520SM + tristate "Genesys Logic GL520SM" + depends on I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for Genesys Logic GL520SM + sensor chips. + + This driver can also be built as a module. If so, the module + will be called gl520sm. + config SENSORS_IT87 tristate "ITE IT87xx and compatibles" depends on I2C && EXPERIMENTAL @@ -251,6 +273,18 @@ This driver can also be built as a module. If so, the module will be called smsc47b397. +config SENSORS_SIS5595 + tristate "Silicon Integrated Systems Corp. SiS5595" + depends on I2C && PCI && EXPERIMENTAL + select I2C_SENSOR + select I2C_ISA + help + If you say yes here you get support for the integrated sensors in + SiS5595 South Bridges. + + This driver can also be built as a module. If so, the module + will be called sis5595. + config SENSORS_SMSC47M1 tristate "SMSC LPC47M10x and compatibles" depends on I2C && EXPERIMENTAL @@ -304,6 +338,7 @@ tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF" depends on I2C && EXPERIMENTAL select I2C_SENSOR + select I2C_ISA help If you say yes here you get support for the Winbond W836X7 series of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF @@ -370,5 +405,14 @@ This driver can also be built as a module. If so, the module will be called isp1301_omap. + +config SENSORS_M41T00 + tristate "ST M41T00 RTC chip" + depends on I2C && PPC32 + help + If you say yes here you get support for the ST M41T00 RTC chip. + + This driver can also be built as a module. If so, the module + will be called m41t00. endmenu diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile --- a/drivers/i2c/chips/Makefile 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/Makefile 2005-03-03 21:57:36 -08:00 @@ -14,7 +14,9 @@ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o obj-$(CONFIG_SENSORS_FSCHER) += fscher.o +obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o +obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_IT87) += it87.o obj-$(CONFIG_SENSORS_LM63) += lm63.o obj-$(CONFIG_SENSORS_LM75) += lm75.o @@ -26,10 +28,12 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o +obj-$(CONFIG_SENSORS_M41T00) += m41t00.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o +obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c --- a/drivers/i2c/chips/adm1021.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/adm1021.c 2005-03-03 21:57:36 -08:00 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -147,8 +148,6 @@ .detach_client = adm1021_detach_client, }; -static int adm1021_id; - #define show(value) \ static ssize_t show_##value(struct device *dev, char *buf) \ { \ @@ -299,8 +298,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, type_name, I2C_NAME_SIZE); data->type = kind; - - new_client->id = adm1021_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -373,8 +370,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting adm1021 update\n"); data->temp_input = adm1021_read_value(client, ADM1021_REG_TEMP); diff -Nru a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c --- a/drivers/i2c/chips/adm1025.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/adm1025.c 2005-03-03 21:57:36 -08:00 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -148,12 +149,6 @@ }; /* - * Internal variables - */ - -static int adm1025_id; - -/* * Sysfs stuff */ @@ -397,7 +392,6 @@ /* We can fill in the remaining client fields */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - new_client->id = adm1025_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -512,9 +506,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ * 2) || - (jiffies < data->last_updated) || - !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { int i; dev_dbg(&client->dev, "Updating data.\n"); diff -Nru a/drivers/i2c/chips/adm1026.c b/drivers/i2c/chips/adm1026.c --- a/drivers/i2c/chips/adm1026.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/adm1026.c 2005-03-03 21:57:36 -08:00 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -313,8 +314,6 @@ .detach_client = adm1026_detach_client, }; -static int adm1026_id; - int adm1026_attach_adapter(struct i2c_adapter *adapter) { if (!(adapter->class & I2C_CLASS_HWMON)) { @@ -363,49 +362,47 @@ int value, i; struct adm1026_data *data = i2c_get_clientdata(client); - dev_dbg(&client->dev,"(%d): Initializing device\n", client->id); + dev_dbg(&client->dev, "Initializing device\n"); /* Read chip config */ data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1); data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2); data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3); /* Inform user of chip config */ - dev_dbg(&client->dev, "(%d): ADM1026_REG_CONFIG1 is: 0x%02x\n", - client->id, data->config1); + dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n", + data->config1); if ((data->config1 & CFG1_MONITOR) == 0) { - dev_dbg(&client->dev, "(%d): Monitoring not currently " - "enabled.\n", client->id); + dev_dbg(&client->dev, "Monitoring not currently " + "enabled.\n"); } if (data->config1 & CFG1_INT_ENABLE) { - dev_dbg(&client->dev, "(%d): SMBALERT interrupts are " - "enabled.\n", client->id); + dev_dbg(&client->dev, "SMBALERT interrupts are " + "enabled.\n"); } if (data->config1 & CFG1_AIN8_9) { - dev_dbg(&client->dev, "(%d): in8 and in9 enabled. " - "temp3 disabled.\n", client->id); + dev_dbg(&client->dev, "in8 and in9 enabled. " + "temp3 disabled.\n"); } else { - dev_dbg(&client->dev, "(%d): temp3 enabled. in8 and " - "in9 disabled.\n", client->id); + dev_dbg(&client->dev, "temp3 enabled. in8 and " + "in9 disabled.\n"); } if (data->config1 & CFG1_THERM_HOT) { - dev_dbg(&client->dev, "(%d): Automatic THERM, PWM, " - "and temp limits enabled.\n", client->id); + dev_dbg(&client->dev, "Automatic THERM, PWM, " + "and temp limits enabled.\n"); } value = data->config3; if (data->config3 & CFG3_GPIO16_ENABLE) { - dev_dbg(&client->dev, "(%d): GPIO16 enabled. THERM" - "pin disabled.\n", client->id); + dev_dbg(&client->dev, "GPIO16 enabled. THERM" + "pin disabled.\n"); } else { - dev_dbg(&client->dev, "(%d): THERM pin enabled. " - "GPIO16 disabled.\n", client->id); + dev_dbg(&client->dev, "THERM pin enabled. " + "GPIO16 disabled.\n"); } if (data->config3 & CFG3_VREF_250) { - dev_dbg(&client->dev, "(%d): Vref is 2.50 Volts.\n", - client->id); + dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); } else { - dev_dbg(&client->dev, "(%d): Vref is 1.82 Volts.\n", - client->id); + dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); } /* Read and pick apart the existing GPIO configuration */ value = 0; @@ -423,12 +420,11 @@ adm1026_print_gpio(client); /* If the user asks us to reprogram the GPIO config, then - * do it now. But only if this is the first ADM1026. + * do it now. */ - if (client->id == 0 - && (gpio_input[0] != -1 || gpio_output[0] != -1 + if (gpio_input[0] != -1 || gpio_output[0] != -1 || gpio_inverted[0] != -1 || gpio_normal[0] != -1 - || gpio_fan[0] != -1)) { + || gpio_fan[0] != -1) { adm1026_fixup_gpio(client); } @@ -448,8 +444,7 @@ value = adm1026_read_value(client, ADM1026_REG_CONFIG1); /* Set MONITOR, clear interrupt acknowledge and s/w reset */ value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET); - dev_dbg(&client->dev, "(%d): Setting CONFIG to: 0x%02x\n", - client->id, value); + dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value); data->config1 = value; adm1026_write_value(client, ADM1026_REG_CONFIG1, value); @@ -467,31 +462,30 @@ struct adm1026_data *data = i2c_get_clientdata(client); int i; - dev_dbg(&client->dev, "(%d): GPIO config is:", client->id); + dev_dbg(&client->dev, "GPIO config is:"); for (i = 0;i <= 7;++i) { if (data->config2 & (1 << i)) { - dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id, + dev_dbg(&client->dev, "\t%sGP%s%d\n", data->gpio_config[i] & 0x02 ? "" : "!", data->gpio_config[i] & 0x01 ? "OUT" : "IN", i); } else { - dev_dbg(&client->dev, "\t(%d): FAN%d\n", - client->id, i); + dev_dbg(&client->dev, "\tFAN%d\n", i); } } for (i = 8;i <= 15;++i) { - dev_dbg(&client->dev, "\t(%d): %sGP%s%d\n", client->id, + dev_dbg(&client->dev, "\t%sGP%s%d\n", data->gpio_config[i] & 0x02 ? "" : "!", data->gpio_config[i] & 0x01 ? "OUT" : "IN", i); } if (data->config3 & CFG3_GPIO16_ENABLE) { - dev_dbg(&client->dev, "\t(%d): %sGP%s16\n", client->id, + dev_dbg(&client->dev, "\t%sGP%s16\n", data->gpio_config[16] & 0x02 ? "" : "!", data->gpio_config[16] & 0x01 ? "OUT" : "IN"); } else { /* GPIO16 is THERM */ - dev_dbg(&client->dev, "\t(%d): THERM\n", client->id); + dev_dbg(&client->dev, "\tTHERM\n"); } } @@ -580,10 +574,9 @@ down(&data->update_lock); if (!data->valid - || (jiffies - data->last_reading > ADM1026_DATA_INTERVAL)) { + || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) { /* Things that change quickly */ - dev_dbg(&client->dev,"(%d): Reading sensor values\n", - client->id); + dev_dbg(&client->dev,"Reading sensor values\n"); for (i = 0;i <= 16;++i) { data->in[i] = adm1026_read_value(client, ADM1026_REG_IN[i]); @@ -628,11 +621,10 @@ data->last_reading = jiffies; }; /* last_reading */ - if (!data->valid || (jiffies - data->last_config > - ADM1026_CONFIG_INTERVAL)) { + if (!data->valid || + time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { /* Things that don't change often */ - dev_dbg(&client->dev, "(%d): Reading config values\n", - client->id); + dev_dbg(&client->dev, "Reading config values\n"); for (i = 0;i <= 16;++i) { data->in_min[i] = adm1026_read_value(client, ADM1026_REG_IN_MIN[i]); @@ -712,8 +704,7 @@ data->last_config = jiffies; }; /* last_config */ - dev_dbg(&client->dev, "(%d): Setting VID from GPIO11-15.\n", - client->id); + dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n"); data->vid = (data->gpio >> 11) & 0x1f; data->valid = 1; up(&data->update_lock); @@ -1608,15 +1599,9 @@ strlcpy(new_client->name, type_name, I2C_NAME_SIZE); /* Fill in the remaining client fields */ - new_client->id = adm1026_id++; data->type = kind; data->valid = 0; init_MUTEX(&data->update_lock); - - dev_dbg(&new_client->dev, "(%d): Assigning ID %d to %s at %d,0x%02x\n", - new_client->id, new_client->id, new_client->name, - i2c_adapter_id(new_client->adapter), - new_client->addr); /* Tell the I2C layer a new client has arrived */ if ((err = i2c_attach_client(new_client))) diff -Nru a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c --- a/drivers/i2c/chips/adm1031.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/adm1031.c 2005-03-03 21:57:36 -08:00 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -110,8 +111,6 @@ .detach_client = adm1031_detach_client, }; -static int adm1031_id; - static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg) { return i2c_smbus_read_byte_data(client, reg); @@ -781,8 +780,6 @@ data->chip_type = kind; strlcpy(new_client->name, name, I2C_NAME_SIZE); - - new_client->id = adm1031_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -888,8 +885,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting adm1031 update\n"); for (chan = 0; diff -Nru a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c --- a/drivers/i2c/chips/asb100.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/asb100.c 2005-03-03 21:57:36 -08:00 @@ -36,17 +36,12 @@ asb100 7 3 1 4 0x31 0x0694 yes no */ -#include #include #include -#include -#include #include #include #include #include -#include -#include #include "lm75.h" /* @@ -970,8 +965,8 @@ down(&data->update_lock); - if (time_after(jiffies - data->last_updated, (unsigned long)(HZ+HZ/2)) - || time_before(jiffies, data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "starting device update...\n"); diff -Nru a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c --- a/drivers/i2c/chips/ds1621.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/ds1621.c 2005-03-03 21:57:36 -08:00 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include "lm75.h" @@ -95,8 +96,6 @@ .detach_client = ds1621_detach_client, }; -static int ds1621_id; - /* All registers are word-sized, except for the configuration register. DS1621 uses a high-byte first convention, which is exactly opposite to the usual practice. */ @@ -236,8 +235,6 @@ /* Fill in remaining client fields and put it into the global list */ strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE); - - new_client->id = ds1621_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -288,8 +285,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting ds1621 update\n"); diff -Nru a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c --- a/drivers/i2c/chips/eeprom.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/eeprom.c 2005-03-03 21:57:36 -08:00 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -86,8 +87,7 @@ down(&data->update_lock); if (!(data->valid & (1 << slice)) || - (jiffies - data->last_updated[slice] > 300 * HZ) || - (jiffies < data->last_updated[slice])) { + time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice); if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { diff -Nru a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c --- a/drivers/i2c/chips/fscher.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/fscher.c 2005-03-03 21:57:36 -08:00 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -151,12 +152,6 @@ }; /* - * Internal variables - */ - -static int fscher_id; - -/* * Sysfs stuff */ @@ -337,7 +332,6 @@ /* Fill in the remaining client fields and put it into the * global list */ strlcpy(new_client->name, "fscher", I2C_NAME_SIZE); - new_client->id = fscher_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -418,8 +412,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > 2 * HZ) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { dev_dbg(&client->dev, "Starting fscher update\n"); diff -Nru a/drivers/i2c/chips/fscpos.c b/drivers/i2c/chips/fscpos.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/i2c/chips/fscpos.c 2005-03-03 21:57:36 -08:00 @@ -0,0 +1,631 @@ +/* + fscpos.c - Kernel module for hardware monitoring with FSC Poseidon chips + Copyright (C) 2004, 2005 Stefan Ott + + 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. +*/ + +/* + fujitsu siemens poseidon chip, + module based on the old fscpos module by Hermann Jung and + the fscher module by Reinhard Nissl + + original module based on lm80.c + Copyright (C) 1998, 1999 Frodo Looijaard + and Philip Edelbrock + + Thanks to Jean Delvare for reviewing my code and suggesting a lot of + improvements. +*/ + +#include +#include +#include +#include +#include + +/* + * Addresses to scan + */ +static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END }; +static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; + +/* + * Insmod parameters + */ +SENSORS_INSMOD_1(fscpos); + +/* + * The FSCPOS registers + */ + +/* chip identification */ +#define FSCPOS_REG_IDENT_0 0x00 +#define FSCPOS_REG_IDENT_1 0x01 +#define FSCPOS_REG_IDENT_2 0x02 +#define FSCPOS_REG_REVISION 0x03 + +/* global control and status */ +#define FSCPOS_REG_EVENT_STATE 0x04 +#define FSCPOS_REG_CONTROL 0x05 + +/* watchdog */ +#define FSCPOS_REG_WDOG_PRESET 0x28 +#define FSCPOS_REG_WDOG_STATE 0x23 +#define FSCPOS_REG_WDOG_CONTROL 0x21 + +/* voltages */ +#define FSCPOS_REG_VOLT_12 0x45 +#define FSCPOS_REG_VOLT_5 0x42 +#define FSCPOS_REG_VOLT_BATT 0x48 + +/* fans - the chip does not support minimum speed for fan2 */ +static u8 FSCPOS_REG_PWM[] = { 0x55, 0x65 }; +static u8 FSCPOS_REG_FAN_ACT[] = { 0x0e, 0x6b, 0xab }; +static u8 FSCPOS_REG_FAN_STATE[] = { 0x0d, 0x62, 0xa2 }; +static u8 FSCPOS_REG_FAN_RIPPLE[] = { 0x0f, 0x6f, 0xaf }; + +/* temperatures */ +static u8 FSCPOS_REG_TEMP_ACT[] = { 0x64, 0x32, 0x35 }; +static u8 FSCPOS_REG_TEMP_STATE[] = { 0x71, 0x81, 0x91 }; + +/* + * Functions declaration + */ +static int fscpos_attach_adapter(struct i2c_adapter *adapter); +static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind); +static int fscpos_detach_client(struct i2c_client *client); + +static int fscpos_read_value(struct i2c_client *client, u8 register); +static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value); +static struct fscpos_data *fscpos_update_device(struct device *dev); +static void fscpos_init_client(struct i2c_client *client); + +static void reset_fan_alarm(struct i2c_client *client, int nr); + +/* + * Driver data (common to all clients) + */ +static struct i2c_driver fscpos_driver = { + .owner = THIS_MODULE, + .name = "fscpos", + .id = I2C_DRIVERID_FSCPOS, + .flags = I2C_DF_NOTIFY, + .attach_adapter = fscpos_attach_adapter, + .detach_client = fscpos_detach_client, +}; + +/* + * Client data (each client gets its own) + */ +struct fscpos_data { + struct i2c_client client; + struct semaphore update_lock; + char valid; /* 0 until following fields are valid */ + unsigned long last_updated; /* In jiffies */ + + /* register values */ + u8 revision; /* revision of chip */ + u8 global_event; /* global event status */ + u8 global_control; /* global control register */ + u8 wdog_control; /* watchdog control */ + u8 wdog_state; /* watchdog status */ + u8 wdog_preset; /* watchdog preset */ + u8 volt[3]; /* 12, 5, battery current */ + u8 temp_act[3]; /* temperature */ + u8 temp_status[3]; /* status of sensor */ + u8 fan_act[3]; /* fans revolutions per second */ + u8 fan_status[3]; /* fan status */ + u8 pwm[2]; /* fan min value for rps */ + u8 fan_ripple[3]; /* divider for rps */ +}; + +/* Temperature */ +#define TEMP_FROM_REG(val) (((val) - 128) * 1000) + +static ssize_t show_temp_input(struct fscpos_data *data, char *buf, int nr) +{ + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[nr - 1])); +} + +static ssize_t show_temp_status(struct fscpos_data *data, char *buf, int nr) +{ + /* bits 2..7 reserved => mask with 0x03 */ + return sprintf(buf, "%u\n", data->temp_status[nr - 1] & 0x03); +} + +static ssize_t show_temp_reset(struct fscpos_data *data, char *buf, int nr) +{ + return sprintf(buf, "1\n"); +} + +static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data + *data, const char *buf, size_t count, int nr, int reg) +{ + unsigned long v = simple_strtoul(buf, NULL, 10); + if (v != 1) { + dev_err(&client->dev, "temp_reset value %ld not supported. " + "Use 1 to reset the alarm!\n", v); + return -EINVAL; + } + + dev_info(&client->dev, "You used the temp_reset feature which has not " + "been proplerly tested. Please report your " + "experience to the module author.\n"); + + /* Supported value: 2 (clears the status) */ + fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr], 2); + return count; +} + +/* Fans */ +#define RPM_FROM_REG(val) ((val) * 60) + +static ssize_t show_fan_status(struct fscpos_data *data, char *buf, int nr) +{ + /* bits 0..1, 3..7 reserved => mask with 0x04 */ + return sprintf(buf, "%u\n", data->fan_status[nr - 1] & 0x04); +} + +static ssize_t show_fan_input(struct fscpos_data *data, char *buf, int nr) +{ + return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[nr - 1])); +} + +static ssize_t show_fan_ripple(struct fscpos_data *data, char *buf, int nr) +{ + /* bits 2..7 reserved => mask with 0x03 */ + return sprintf(buf, "%u\n", data->fan_ripple[nr - 1] & 0x03); +} + +static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data + *data, const char *buf, size_t count, int nr, int reg) +{ + /* supported values: 2, 4, 8 */ + unsigned long v = simple_strtoul(buf, NULL, 10); + + switch (v) { + case 2: v = 1; break; + case 4: v = 2; break; + case 8: v = 3; break; + default: + dev_err(&client->dev, "fan_ripple value %ld not supported. " + "Must be one of 2, 4 or 8!\n", v); + return -EINVAL; + } + + /* bits 2..7 reserved => mask with 0x03 */ + data->fan_ripple[nr - 1] &= ~0x03; + data->fan_ripple[nr - 1] |= v; + + fscpos_write_value(client, reg, data->fan_ripple[nr - 1]); + return count; +} + +static ssize_t show_pwm(struct fscpos_data *data, char *buf, int nr) +{ + return sprintf(buf, "%u\n", data->pwm[nr - 1]); +} + +static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data, + const char *buf, size_t count, int nr, int reg) +{ + unsigned long v = simple_strtoul(buf, NULL, 10); + + /* Range: 0..255 */ + if (v < 0) v = 0; + if (v > 255) v = 255; + + data->pwm[nr - 1] = v; + fscpos_write_value(client, reg, data->pwm[nr - 1]); + return count; +} + +static void reset_fan_alarm(struct i2c_client *client, int nr) +{ + fscpos_write_value(client, FSCPOS_REG_FAN_STATE[nr], 4); +} + +/* Volts */ +#define VOLT_FROM_REG(val, mult) ((val) * (mult) / 255) + +static ssize_t show_volt_12(struct device *dev, char *buf) +{ + struct fscpos_data *data = fscpos_update_device(dev); + return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[0], 14200)); +} + +static ssize_t show_volt_5(struct device *dev, char *buf) +{ + struct fscpos_data *data = fscpos_update_device(dev); + return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[1], 6600)); +} + +static ssize_t show_volt_batt(struct device *dev, char *buf) +{ + struct fscpos_data *data = fscpos_update_device(dev); + return sprintf(buf, "%u\n", VOLT_FROM_REG(data->volt[2], 3300)); +} + +/* Watchdog */ +static ssize_t show_wdog_control(struct fscpos_data *data, char *buf) +{ + /* bits 0..3 reserved, bit 6 write only => mask with 0xb0 */ + return sprintf(buf, "%u\n", data->wdog_control & 0xb0); +} + +static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data + *data, const char *buf, size_t count, int reg) +{ + /* bits 0..3 reserved => mask with 0xf0 */ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0; + data->wdog_control &= ~0xf0; + data->wdog_control |= v; + + fscpos_write_value(client, reg, data->wdog_control); + return count; +} + +static ssize_t show_wdog_state(struct fscpos_data *data, char *buf) +{ + /* bits 0, 2..7 reserved => mask with 0x02 */ + return sprintf(buf, "%u\n", data->wdog_state & 0x02); +} + +static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data + *data, const char *buf, size_t count, int reg) +{ + unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02; + + /* Valid values: 2 (clear) */ + if (v != 2) { + dev_err(&client->dev, "wdog_state value %ld not supported. " + "Must be 2 to clear the state!\n", v); + return -EINVAL; + } + + data->wdog_state &= ~v; + + fscpos_write_value(client, reg, v); + return count; +} + +static ssize_t show_wdog_preset(struct fscpos_data *data, char *buf) +{ + return sprintf(buf, "%u\n", data->wdog_preset); +} + +static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data + *data, const char *buf, size_t count, int reg) +{ + data->wdog_preset = simple_strtoul(buf, NULL, 10) & 0xff; + + fscpos_write_value(client, reg, data->wdog_preset); + return count; +} + +/* Event */ +static ssize_t show_event(struct device *dev, char *buf) +{ + /* bits 5..7 reserved => mask with 0x1f */ + struct fscpos_data *data = fscpos_update_device(dev); + return sprintf(buf, "%u\n", data->global_event & 0x9b); +} + +/* + * Sysfs stuff + */ +#define create_getter(kind, sub) \ + static ssize_t sysfs_show_##kind##sub(struct device *dev, char *buf) \ + { \ + struct fscpos_data *data = fscpos_update_device(dev); \ + return show_##kind##sub(data, buf); \ + } + +#define create_getter_n(kind, offset, sub) \ + static ssize_t sysfs_show_##kind##offset##sub(struct device *dev, char\ + *buf) \ + { \ + struct fscpos_data *data = fscpos_update_device(dev); \ + return show_##kind##sub(data, buf, offset); \ + } + +#define create_setter(kind, sub, reg) \ + static ssize_t sysfs_set_##kind##sub (struct device *dev, const char \ + *buf, size_t count) \ + { \ + struct i2c_client *client = to_i2c_client(dev); \ + struct fscpos_data *data = i2c_get_clientdata(client); \ + return set_##kind##sub(client, data, buf, count, reg); \ + } + +#define create_setter_n(kind, offset, sub, reg) \ + static ssize_t sysfs_set_##kind##offset##sub (struct device *dev, \ + const char *buf, size_t count) \ + { \ + struct i2c_client *client = to_i2c_client(dev); \ + struct fscpos_data *data = i2c_get_clientdata(client); \ + return set_##kind##sub(client, data, buf, count, offset, reg);\ + } + +#define create_sysfs_device_ro(kind, sub, offset) \ + static DEVICE_ATTR(kind##offset##sub, S_IRUGO, \ + sysfs_show_##kind##offset##sub, NULL); + +#define create_sysfs_device_rw(kind, sub, offset) \ + static DEVICE_ATTR(kind##offset##sub, S_IRUGO | S_IWUSR, \ + sysfs_show_##kind##offset##sub, sysfs_set_##kind##offset##sub); + +#define sysfs_ro_n(kind, sub, offset) \ + create_getter_n(kind, offset, sub); \ + create_sysfs_device_ro(kind, sub, offset); + +#define sysfs_rw_n(kind, sub, offset, reg) \ + create_getter_n(kind, offset, sub); \ + create_setter_n(kind, offset, sub, reg); \ + create_sysfs_device_rw(kind, sub, offset); + +#define sysfs_rw(kind, sub, reg) \ + create_getter(kind, sub); \ + create_setter(kind, sub, reg); \ + create_sysfs_device_rw(kind, sub,); + +#define sysfs_fan_with_min(offset, reg_status, reg_ripple, reg_min) \ + sysfs_fan(offset, reg_status, reg_ripple); \ + sysfs_rw_n(pwm,, offset, reg_min); + +#define sysfs_fan(offset, reg_status, reg_ripple) \ + sysfs_ro_n(fan, _input, offset); \ + sysfs_ro_n(fan, _status, offset); \ + sysfs_rw_n(fan, _ripple, offset, reg_ripple); + +#define sysfs_temp(offset, reg_status) \ + sysfs_ro_n(temp, _input, offset); \ + sysfs_ro_n(temp, _status, offset); \ + sysfs_rw_n(temp, _reset, offset, reg_status); + +#define sysfs_watchdog(reg_wdog_preset, reg_wdog_state, reg_wdog_control) \ + sysfs_rw(wdog, _control, reg_wdog_control); \ + sysfs_rw(wdog, _preset, reg_wdog_preset); \ + sysfs_rw(wdog, _state, reg_wdog_state); + +sysfs_fan_with_min(1, FSCPOS_REG_FAN_STATE[0], FSCPOS_REG_FAN_RIPPLE[0], + FSCPOS_REG_PWM[0]); +sysfs_fan_with_min(2, FSCPOS_REG_FAN_STATE[1], FSCPOS_REG_FAN_RIPPLE[1], + FSCPOS_REG_PWM[1]); +sysfs_fan(3, FSCPOS_REG_FAN_STATE[2], FSCPOS_REG_FAN_RIPPLE[2]); + +sysfs_temp(1, FSCPOS_REG_TEMP_STATE[0]); +sysfs_temp(2, FSCPOS_REG_TEMP_STATE[1]); +sysfs_temp(3, FSCPOS_REG_TEMP_STATE[2]); + +sysfs_watchdog(FSCPOS_REG_WDOG_PRESET, FSCPOS_REG_WDOG_STATE, + FSCPOS_REG_WDOG_CONTROL); + +static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); +static DEVICE_ATTR(in0_input, S_IRUGO, show_volt_12, NULL); +static DEVICE_ATTR(in1_input, S_IRUGO, show_volt_5, NULL); +static DEVICE_ATTR(in2_input, S_IRUGO, show_volt_batt, NULL); + +static int fscpos_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; + return i2c_detect(adapter, &addr_data, fscpos_detect); +} + +int fscpos_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *new_client; + struct fscpos_data *data; + int err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) + goto exit; + + /* + * OK. For now, we presume we have a valid client. We now create the + * client structure, even though we cannot fill it completely yet. + * But it allows us to access fscpos_{read,write}_value. + */ + + if (!(data = kmalloc(sizeof(struct fscpos_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct fscpos_data)); + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &fscpos_driver; + new_client->flags = 0; + + /* Do the remaining detection unless force or force_fscpos parameter */ + if (kind < 0) { + if ((fscpos_read_value(new_client, FSCPOS_REG_IDENT_0) + != 0x50) /* 'P' */ + || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_1) + != 0x45) /* 'E' */ + || (fscpos_read_value(new_client, FSCPOS_REG_IDENT_2) + != 0x47))/* 'G' */ + { + dev_dbg(&new_client->dev, "fscpos detection failed\n"); + goto exit_free; + } + } + + /* Fill in the remaining client fields and put it in the global list */ + strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE); + + 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; + + /* Inizialize the fscpos chip */ + fscpos_init_client(new_client); + + /* Announce that the chip was found */ + dev_info(&new_client->dev, "Found fscpos chip, rev %u\n", data->revision); + + /* Register sysfs hooks */ + device_create_file(&new_client->dev, &dev_attr_event); + device_create_file(&new_client->dev, &dev_attr_in0_input); + device_create_file(&new_client->dev, &dev_attr_in1_input); + device_create_file(&new_client->dev, &dev_attr_in2_input); + device_create_file(&new_client->dev, &dev_attr_wdog_control); + device_create_file(&new_client->dev, &dev_attr_wdog_preset); + device_create_file(&new_client->dev, &dev_attr_wdog_state); + device_create_file(&new_client->dev, &dev_attr_temp1_input); + device_create_file(&new_client->dev, &dev_attr_temp1_status); + device_create_file(&new_client->dev, &dev_attr_temp1_reset); + device_create_file(&new_client->dev, &dev_attr_temp2_input); + device_create_file(&new_client->dev, &dev_attr_temp2_status); + device_create_file(&new_client->dev, &dev_attr_temp2_reset); + device_create_file(&new_client->dev, &dev_attr_temp3_input); + device_create_file(&new_client->dev, &dev_attr_temp3_status); + device_create_file(&new_client->dev, &dev_attr_temp3_reset); + device_create_file(&new_client->dev, &dev_attr_fan1_input); + device_create_file(&new_client->dev, &dev_attr_fan1_status); + device_create_file(&new_client->dev, &dev_attr_fan1_ripple); + device_create_file(&new_client->dev, &dev_attr_pwm1); + device_create_file(&new_client->dev, &dev_attr_fan2_input); + device_create_file(&new_client->dev, &dev_attr_fan2_status); + device_create_file(&new_client->dev, &dev_attr_fan2_ripple); + device_create_file(&new_client->dev, &dev_attr_pwm2); + device_create_file(&new_client->dev, &dev_attr_fan3_input); + device_create_file(&new_client->dev, &dev_attr_fan3_status); + device_create_file(&new_client->dev, &dev_attr_fan3_ripple); + + return 0; + +exit_free: + kfree(data); +exit: + return err; +} + +static int fscpos_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(i2c_get_clientdata(client)); + return 0; +} + +static int fscpos_read_value(struct i2c_client *client, u8 reg) +{ + dev_dbg(&client->dev, "Read reg 0x%02x\n", reg); + return i2c_smbus_read_byte_data(client, reg); +} + +static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + dev_dbg(&client->dev, "Write reg 0x%02x, val 0x%02x\n", reg, value); + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* Called when we have found a new FSCPOS chip */ +static void fscpos_init_client(struct i2c_client *client) +{ + struct fscpos_data *data = i2c_get_clientdata(client); + + /* read revision from chip */ + data->revision = fscpos_read_value(client, FSCPOS_REG_REVISION); +} + +static struct fscpos_data *fscpos_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct fscpos_data *data = i2c_get_clientdata(client); + + down(&data->update_lock); + + if ((jiffies - data->last_updated > 2 * HZ) || + (jiffies < data->last_updated) || !data->valid) { + int i; + + dev_dbg(&client->dev, "Starting fscpos update\n"); + + for (i = 0; i < 3; i++) { + data->temp_act[i] = fscpos_read_value(client, + FSCPOS_REG_TEMP_ACT[i]); + data->temp_status[i] = fscpos_read_value(client, + FSCPOS_REG_TEMP_STATE[i]); + data->fan_act[i] = fscpos_read_value(client, + FSCPOS_REG_FAN_ACT[i]); + data->fan_status[i] = fscpos_read_value(client, + FSCPOS_REG_FAN_STATE[i]); + data->fan_ripple[i] = fscpos_read_value(client, + FSCPOS_REG_FAN_RIPPLE[i]); + if (i < 2) { + /* fan2_min is not supported by the chip */ + data->pwm[i] = fscpos_read_value(client, + FSCPOS_REG_PWM[i]); + } + /* reset fan status if speed is back to > 0 */ + if (data->fan_status[i] != 0 && data->fan_act[i] > 0) { + reset_fan_alarm(client, i); + } + } + + data->volt[0] = fscpos_read_value(client, FSCPOS_REG_VOLT_12); + data->volt[1] = fscpos_read_value(client, FSCPOS_REG_VOLT_5); + data->volt[2] = fscpos_read_value(client, FSCPOS_REG_VOLT_BATT); + + data->wdog_preset = fscpos_read_value(client, + FSCPOS_REG_WDOG_PRESET); + data->wdog_state = fscpos_read_value(client, + FSCPOS_REG_WDOG_STATE); + data->wdog_control = fscpos_read_value(client, + FSCPOS_REG_WDOG_CONTROL); + + data->global_event = fscpos_read_value(client, + FSCPOS_REG_EVENT_STATE); + + data->last_updated = jiffies; + data->valid = 1; + } + up(&data->update_lock); + return data; +} + +static int __init sm_fscpos_init(void) +{ + return i2c_add_driver(&fscpos_driver); +} + +static void __exit sm_fscpos_exit(void) +{ + i2c_del_driver(&fscpos_driver); +} + +MODULE_AUTHOR("Stefan Ott based on work from Hermann Jung " + ", Frodo Looijaard " + " and Philip Edelbrock "); +MODULE_DESCRIPTION("fujitsu siemens poseidon chip driver"); +MODULE_LICENSE("GPL"); + +module_init(sm_fscpos_init); +module_exit(sm_fscpos_exit); diff -Nru a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c --- a/drivers/i2c/chips/gl518sm.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/gl518sm.c 2005-03-03 21:57:36 -08:00 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -159,12 +160,6 @@ }; /* - * Internal variables - */ - -static int gl518_id; - -/* * Sysfs stuff */ @@ -396,7 +391,6 @@ /* Fill in the remaining client fields */ strlcpy(new_client->name, "gl518sm", I2C_NAME_SIZE); - new_client->id = gl518_id++; data->type = kind; data->valid = 0; init_MUTEX(&data->update_lock); @@ -512,8 +506,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting gl518 update\n"); data->alarms = gl518_read_value(client, GL518_REG_INT); diff -Nru a/drivers/i2c/chips/gl520sm.c b/drivers/i2c/chips/gl520sm.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/i2c/chips/gl520sm.c 2005-03-03 21:57:36 -08:00 @@ -0,0 +1,754 @@ +/* + gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware + monitoring + Copyright (c) 1998, 1999 Frodo Looijaard , + Kyösti Mälkki + Copyright (c) 2005 Maarten Deprez + + 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 +#include + +/* Type of the extra sensor */ +static unsigned short extra_sensor_type; +module_param(extra_sensor_type, ushort, 0); +MODULE_PARM_DESC(extra_sensor_type, "Type of extra sensor (0=autodetect, 1=temperature, 2=voltage)"); + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END }; +static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; + +/* Insmod parameters */ +SENSORS_INSMOD_1(gl520sm); + +/* Many GL520 constants specified below +One of the inputs can be configured as either temp or voltage. +That's why _TEMP2 and _IN4 access the same register +*/ + +/* The GL520 registers */ +#define GL520_REG_CHIP_ID 0x00 +#define GL520_REG_REVISION 0x01 +#define GL520_REG_CONF 0x03 +#define GL520_REG_MASK 0x11 + +#define GL520_REG_VID_INPUT 0x02 + +#define GL520_REG_IN0_INPUT 0x15 +#define GL520_REG_IN0_LIMIT 0x0c +#define GL520_REG_IN0_MIN GL520_REG_IN0_LIMIT +#define GL520_REG_IN0_MAX GL520_REG_IN0_LIMIT + +#define GL520_REG_IN1_INPUT 0x14 +#define GL520_REG_IN1_LIMIT 0x09 +#define GL520_REG_IN1_MIN GL520_REG_IN1_LIMIT +#define GL520_REG_IN1_MAX GL520_REG_IN1_LIMIT + +#define GL520_REG_IN2_INPUT 0x13 +#define GL520_REG_IN2_LIMIT 0x0a +#define GL520_REG_IN2_MIN GL520_REG_IN2_LIMIT +#define GL520_REG_IN2_MAX GL520_REG_IN2_LIMIT + +#define GL520_REG_IN3_INPUT 0x0d +#define GL520_REG_IN3_LIMIT 0x0b +#define GL520_REG_IN3_MIN GL520_REG_IN3_LIMIT +#define GL520_REG_IN3_MAX GL520_REG_IN3_LIMIT + +#define GL520_REG_IN4_INPUT 0x0e +#define GL520_REG_IN4_MAX 0x17 +#define GL520_REG_IN4_MIN 0x18 + +#define GL520_REG_TEMP1_INPUT 0x04 +#define GL520_REG_TEMP1_MAX 0x05 +#define GL520_REG_TEMP1_MAX_HYST 0x06 + +#define GL520_REG_TEMP2_INPUT 0x0e +#define GL520_REG_TEMP2_MAX 0x17 +#define GL520_REG_TEMP2_MAX_HYST 0x18 + +#define GL520_REG_FAN_INPUT 0x07 +#define GL520_REG_FAN_MIN 0x08 +#define GL520_REG_FAN_DIV 0x0f +#define GL520_REG_FAN_OFF GL520_REG_FAN_DIV + +#define GL520_REG_ALARMS 0x12 +#define GL520_REG_BEEP_MASK 0x10 +#define GL520_REG_BEEP_ENABLE GL520_REG_CONF + +/* + * Function declarations + */ + +static int gl520_attach_adapter(struct i2c_adapter *adapter); +static int gl520_detect(struct i2c_adapter *adapter, int address, int kind); +static void gl520_init_client(struct i2c_client *client); +static int gl520_detach_client(struct i2c_client *client); +static int gl520_read_value(struct i2c_client *client, u8 reg); +static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value); +static struct gl520_data *gl520_update_device(struct device *dev); + +/* Driver data */ +static struct i2c_driver gl520_driver = { + .owner = THIS_MODULE, + .name = "gl520sm", + .id = I2C_DRIVERID_GL520, + .flags = I2C_DF_NOTIFY, + .attach_adapter = gl520_attach_adapter, + .detach_client = gl520_detach_client, +}; + +/* Client data */ +struct gl520_data { + struct i2c_client client; + struct semaphore update_lock; + char valid; /* zero until the following fields are valid */ + unsigned long last_updated; /* in jiffies */ + + u8 vid; + u8 vrm; + u8 in_input[5]; /* [0] = VVD */ + u8 in_min[5]; /* [0] = VDD */ + u8 in_max[5]; /* [0] = VDD */ + u8 fan_input[2]; + u8 fan_min[2]; + u8 fan_div[2]; + u8 fan_off; + u8 temp_input[2]; + u8 temp_max[2]; + u8 temp_max_hyst[2]; + u8 alarms; + u8 beep_enable; + u8 beep_mask; + u8 alarm_mask; + u8 two_temps; +}; + +/* + * Sysfs stuff + */ + +#define sysfs_r(type, n, item, reg) \ +static ssize_t get_##type##item (struct gl520_data *, char *, int); \ +static ssize_t get_##type##n##item (struct device *, char *); \ +static ssize_t get_##type##n##item (struct device *dev, char *buf) \ +{ \ + struct gl520_data *data = gl520_update_device(dev); \ + return get_##type##item(data, buf, (n)); \ +} + +#define sysfs_w(type, n, item, reg) \ +static ssize_t set_##type##item (struct i2c_client *, struct gl520_data *, const char *, size_t, int, int); \ +static ssize_t set_##type##n##item (struct device *, const char *, size_t); \ +static ssize_t set_##type##n##item (struct device *dev, const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct gl520_data *data = i2c_get_clientdata(client); \ + return set_##type##item(client, data, buf, count, (n), reg); \ +} + +#define sysfs_rw_n(type, n, item, reg) \ +sysfs_r(type, n, item, reg) \ +sysfs_w(type, n, item, reg) \ +static DEVICE_ATTR(type##n##item, S_IRUGO | S_IWUSR, get_##type##n##item, set_##type##n##item); + +#define sysfs_ro_n(type, n, item, reg) \ +sysfs_r(type, n, item, reg) \ +static DEVICE_ATTR(type##n##item, S_IRUGO, get_##type##n##item, NULL); + +#define sysfs_rw(type, item, reg) \ +sysfs_r(type, 0, item, reg) \ +sysfs_w(type, 0, item, reg) \ +static DEVICE_ATTR(type##item, S_IRUGO | S_IWUSR, get_##type##0##item, set_##type##0##item); + +#define sysfs_ro(type, item, reg) \ +sysfs_r(type, 0, item, reg) \ +static DEVICE_ATTR(type##item, S_IRUGO, get_##type##0##item, NULL); + + +#define sysfs_vid(n) \ +sysfs_ro_n(cpu, n, _vid, GL520_REG_VID_INPUT) + +#define device_create_file_vid(client, n) \ +device_create_file(&client->dev, &dev_attr_cpu##n##_vid) + +#define sysfs_in(n) \ +sysfs_ro_n(in, n, _input, GL520_REG_IN##n##INPUT) \ +sysfs_rw_n(in, n, _min, GL520_REG_IN##n##_MIN) \ +sysfs_rw_n(in, n, _max, GL520_REG_IN##n##_MAX) \ + +#define device_create_file_in(client, n) \ +({device_create_file(&client->dev, &dev_attr_in##n##_input); \ +device_create_file(&client->dev, &dev_attr_in##n##_min); \ +device_create_file(&client->dev, &dev_attr_in##n##_max);}) + +#define sysfs_fan(n) \ +sysfs_ro_n(fan, n, _input, GL520_REG_FAN_INPUT) \ +sysfs_rw_n(fan, n, _min, GL520_REG_FAN_MIN) \ +sysfs_rw_n(fan, n, _div, GL520_REG_FAN_DIV) + +#define device_create_file_fan(client, n) \ +({device_create_file(&client->dev, &dev_attr_fan##n##_input); \ +device_create_file(&client->dev, &dev_attr_fan##n##_min); \ +device_create_file(&client->dev, &dev_attr_fan##n##_div);}) + +#define sysfs_fan_off(n) \ +sysfs_rw_n(fan, n, _off, GL520_REG_FAN_OFF) \ + +#define device_create_file_fan_off(client, n) \ +device_create_file(&client->dev, &dev_attr_fan##n##_off) + +#define sysfs_temp(n) \ +sysfs_ro_n(temp, n, _input, GL520_REG_TEMP##n##_INPUT) \ +sysfs_rw_n(temp, n, _max, GL520_REG_TEMP##n##_MAX) \ +sysfs_rw_n(temp, n, _max_hyst, GL520_REG_TEMP##n##_MAX_HYST) + +#define device_create_file_temp(client, n) \ +({device_create_file(&client->dev, &dev_attr_temp##n##_input); \ +device_create_file(&client->dev, &dev_attr_temp##n##_max); \ +device_create_file(&client->dev, &dev_attr_temp##n##_max_hyst);}) + +#define sysfs_alarms() \ +sysfs_ro(alarms, , GL520_REG_ALARMS) \ +sysfs_rw(beep_enable, , GL520_REG_BEEP_ENABLE) \ +sysfs_rw(beep_mask, , GL520_REG_BEEP_MASK) + +#define device_create_file_alarms(client) \ +({device_create_file(&client->dev, &dev_attr_alarms); \ +device_create_file(&client->dev, &dev_attr_beep_enable); \ +device_create_file(&client->dev, &dev_attr_beep_mask);}) + + +sysfs_vid(0) + +sysfs_in(0) +sysfs_in(1) +sysfs_in(2) +sysfs_in(3) +sysfs_in(4) + +sysfs_fan(1) +sysfs_fan(2) +sysfs_fan_off(1) + +sysfs_temp(1) +sysfs_temp(2) + +sysfs_alarms() + + +static ssize_t get_cpu_vid(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm)); +} + +#define VDD_FROM_REG(val) (((val)*95+2)/4) +#define VDD_TO_REG(val) (SENSORS_LIMIT((((val)*4+47)/95),0,255)) + +#define IN_FROM_REG(val) ((val)*19) +#define IN_TO_REG(val) (SENSORS_LIMIT((((val)+9)/19),0,255)) + +static ssize_t get_in_input(struct gl520_data *data, char *buf, int n) +{ + u8 r = data->in_input[n]; + + if (n == 0) + return sprintf(buf, "%d\n", VDD_FROM_REG(r)); + else + return sprintf(buf, "%d\n", IN_FROM_REG(r)); +} + +static ssize_t get_in_min(struct gl520_data *data, char *buf, int n) +{ + u8 r = data->in_min[n]; + + if (n == 0) + return sprintf(buf, "%d\n", VDD_FROM_REG(r)); + else + return sprintf(buf, "%d\n", IN_FROM_REG(r)); +} + +static ssize_t get_in_max(struct gl520_data *data, char *buf, int n) +{ + u8 r = data->in_max[n]; + + if (n == 0) + return sprintf(buf, "%d\n", VDD_FROM_REG(r)); + else + return sprintf(buf, "%d\n", IN_FROM_REG(r)); +} + +static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + long v = simple_strtol(buf, NULL, 10); + u8 r; + + if (n == 0) + r = VDD_TO_REG(v); + else + r = IN_TO_REG(v); + + data->in_min[n] = r; + + if (n < 4) + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r); + else + gl520_write_value(client, reg, r); + + return count; +} + +static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + long v = simple_strtol(buf, NULL, 10); + u8 r; + + if (n == 0) + r = VDD_TO_REG(v); + else + r = IN_TO_REG(v); + + data->in_max[n] = r; + + if (n < 4) + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8)); + else + gl520_write_value(client, reg, r); + + return count; +} + +#define DIV_FROM_REG(val) (1 << (val)) +#define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) +#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)); + +static ssize_t get_fan_input(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_input[n - 1], data->fan_div[n - 1])); +} + +static ssize_t get_fan_min(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[n - 1], data->fan_div[n - 1])); +} + +static ssize_t get_fan_div(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[n - 1])); +} + +static ssize_t get_fan_off(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", data->fan_off); +} + +static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + unsigned long v = simple_strtoul(buf, NULL, 10); + u8 r = FAN_TO_REG(v, data->fan_div[n - 1]); + + data->fan_min[n - 1] = r; + + if (n == 1) + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff00) | (r << 8)); + else + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xff) | r); + + data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); + if (data->fan_min[n - 1] == 0) + data->alarm_mask &= (n == 1) ? ~0x20 : ~0x40; + else + data->alarm_mask |= (n == 1) ? 0x20 : 0x40; + data->beep_mask &= data->alarm_mask; + gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); + + return count; +} + +static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + unsigned long v = simple_strtoul(buf, NULL, 10); + u8 r; + + switch (v) { + case 1: r = 0; break; + case 2: r = 1; break; + case 4: r = 2; break; + case 8: r = 3; break; + default: + dev_err(&client->dev, "fan_div value %ld not supported. Choose one of 1, 2, 4 or 8!\n", v); + return -EINVAL; + } + + data->fan_div[n - 1] = r; + + if (n == 1) + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0xc0) | (r << 6)); + else + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4)); + + return count; +} + +static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + u8 r = simple_strtoul(buf, NULL, 10)?1:0; + + data->fan_off = r; + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2)); + + return count; +} + +#define TEMP_FROM_REG(val) (((val) - 130) * 1000) +#define TEMP_TO_REG(val) (SENSORS_LIMIT(((((val)<0?(val)-500:(val)+500) / 1000)+130),0,255)) + +static ssize_t get_temp_input(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_input[n - 1])); +} + +static ssize_t get_temp_max(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[n - 1])); +} + +static ssize_t get_temp_max_hyst(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max_hyst[n - 1])); +} + +static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + long v = simple_strtol(buf, NULL, 10); + u8 r = TEMP_TO_REG(v); + + data->temp_max[n - 1] = r; + gl520_write_value(client, reg, r); + + return count; +} + +static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + long v = simple_strtol(buf, NULL, 10); + u8 r = TEMP_TO_REG(v); + + data->temp_max_hyst[n - 1] = r; + gl520_write_value(client, reg, r); + + return count; +} + +static ssize_t get_alarms(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", data->alarms); +} + +static ssize_t get_beep_enable(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", data->beep_enable); +} + +static ssize_t get_beep_mask(struct gl520_data *data, char *buf, int n) +{ + return sprintf(buf, "%d\n", data->beep_mask); +} + +static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + u8 r = simple_strtoul(buf, NULL, 10)?0:1; + + data->beep_enable = !r; + gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2)); + + return count; +} + +static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data, const char *buf, size_t count, int n, int reg) +{ + u8 r = simple_strtoul(buf, NULL, 10) & data->alarm_mask; + + data->beep_mask = r; + gl520_write_value(client, reg, r); + + return count; +} + + +/* + * Real code + */ + +static int gl520_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; + return i2c_detect(adapter, &addr_data, gl520_detect); +} + +static int gl520_detect(struct i2c_adapter *adapter, int address, int kind) +{ + struct i2c_client *new_client; + struct gl520_data *data; + int err = 0; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA)) + goto exit; + + /* OK. For now, we presume we have a valid client. We now create the + client structure, even though we cannot fill it completely yet. + But it allows us to access gl520_{read,write}_value. */ + + if (!(data = kmalloc(sizeof(struct gl520_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + memset(data, 0, sizeof(struct gl520_data)); + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &gl520_driver; + new_client->flags = 0; + + /* Determine the chip type. */ + if (kind < 0) { + if ((gl520_read_value(new_client, GL520_REG_CHIP_ID) != 0x20) || + ((gl520_read_value(new_client, GL520_REG_REVISION) & 0x7f) != 0x00) || + ((gl520_read_value(new_client, GL520_REG_CONF) & 0x80) != 0x00)) { + dev_dbg(&new_client->dev, "Unknown chip type, skipping\n"); + goto exit_free; + } + } + + /* Fill in the remaining client fields */ + strlcpy(new_client->name, "gl520sm", I2C_NAME_SIZE); + 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 GL520SM chip */ + gl520_init_client(new_client); + + /* Register sysfs hooks */ + device_create_file_vid(new_client, 0); + + device_create_file_in(new_client, 0); + device_create_file_in(new_client, 1); + device_create_file_in(new_client, 2); + device_create_file_in(new_client, 3); + if (!data->two_temps) + device_create_file_in(new_client, 4); + + device_create_file_fan(new_client, 1); + device_create_file_fan(new_client, 2); + device_create_file_fan_off(new_client, 1); + + device_create_file_temp(new_client, 1); + if (data->two_temps) + device_create_file_temp(new_client, 2); + + device_create_file_alarms(new_client); + + return 0; + +exit_free: + kfree(data); +exit: + return err; +} + + +/* Called when we have found a new GL520SM. */ +static void gl520_init_client(struct i2c_client *client) +{ + struct gl520_data *data = i2c_get_clientdata(client); + u8 oldconf, conf; + + conf = oldconf = gl520_read_value(client, GL520_REG_CONF); + + data->alarm_mask = 0xff; + data->vrm = i2c_which_vrm(); + + if (extra_sensor_type == 1) + conf &= ~0x10; + else if (extra_sensor_type == 2) + conf |= 0x10; + data->two_temps = !(conf & 0x10); + + /* If IRQ# is disabled, we can safely force comparator mode */ + if (!(conf & 0x20)) + conf &= 0xf7; + + /* Enable monitoring if needed */ + conf |= 0x40; + + if (conf != oldconf) + gl520_write_value(client, GL520_REG_CONF, conf); + + gl520_update_device(&(client->dev)); + + if (data->fan_min[0] == 0) + data->alarm_mask &= ~0x20; + if (data->fan_min[1] == 0) + data->alarm_mask &= ~0x40; + + data->beep_mask &= data->alarm_mask; + gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask); +} + +static int gl520_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(i2c_get_clientdata(client)); + return 0; +} + + +/* Registers 0x07 to 0x0c are word-sized, others are byte-sized + GL520 uses a high-byte first convention */ +static int gl520_read_value(struct i2c_client *client, u8 reg) +{ + if ((reg >= 0x07) && (reg <= 0x0c)) + return swab16(i2c_smbus_read_word_data(client, reg)); + else + return i2c_smbus_read_byte_data(client, reg); +} + +static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value) +{ + if ((reg >= 0x07) && (reg <= 0x0c)) + return i2c_smbus_write_word_data(client, reg, swab16(value)); + else + return i2c_smbus_write_byte_data(client, reg, value); +} + + +static struct gl520_data *gl520_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct gl520_data *data = i2c_get_clientdata(client); + int val; + + down(&data->update_lock); + + if ((jiffies - data->last_updated > 2 * HZ) || + (jiffies < data->last_updated) || !data->valid) { + + dev_dbg(&client->dev, "Starting gl520sm update\n"); + + data->alarms = gl520_read_value(client, GL520_REG_ALARMS); + data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK); + data->vid = gl520_read_value(client, GL520_REG_VID_INPUT) & 0x1f; + + val = gl520_read_value(client, GL520_REG_IN0_LIMIT); + data->in_min[0] = val & 0xff; + data->in_max[0] = (val >> 8) & 0xff; + val = gl520_read_value(client, GL520_REG_IN1_LIMIT); + data->in_min[1] = val & 0xff; + data->in_max[1] = (val >> 8) & 0xff; + val = gl520_read_value(client, GL520_REG_IN2_LIMIT); + data->in_min[2] = val & 0xff; + data->in_max[2] = (val >> 8) & 0xff; + val = gl520_read_value(client, GL520_REG_IN3_LIMIT); + data->in_min[3] = val & 0xff; + data->in_max[3] = (val >> 8) & 0xff; + + val = gl520_read_value(client, GL520_REG_FAN_INPUT); + data->fan_input[0] = (val >> 8) & 0xff; + data->fan_input[1] = val & 0xff; + + val = gl520_read_value(client, GL520_REG_FAN_MIN); + data->fan_min[0] = (val >> 8) & 0xff; + data->fan_min[1] = val & 0xff; + + data->temp_input[0] = gl520_read_value(client, GL520_REG_TEMP1_INPUT); + data->temp_max[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX); + data->temp_max_hyst[0] = gl520_read_value(client, GL520_REG_TEMP1_MAX_HYST); + + val = gl520_read_value(client, GL520_REG_FAN_DIV); + data->fan_div[0] = (val >> 6) & 0x03; + data->fan_div[1] = (val >> 4) & 0x03; + data->fan_off = (val >> 2) & 0x01; + + data->alarms &= data->alarm_mask; + + val = gl520_read_value(client, GL520_REG_CONF); + data->beep_enable = !((val >> 2) & 1); + + data->in_input[0] = gl520_read_value(client, GL520_REG_IN0_INPUT); + data->in_input[1] = gl520_read_value(client, GL520_REG_IN1_INPUT); + data->in_input[2] = gl520_read_value(client, GL520_REG_IN2_INPUT); + data->in_input[3] = gl520_read_value(client, GL520_REG_IN3_INPUT); + + /* Temp1 and Vin4 are the same input */ + if (data->two_temps) { + data->temp_input[1] = gl520_read_value(client, GL520_REG_TEMP2_INPUT); + data->temp_max[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX); + data->temp_max_hyst[1] = gl520_read_value(client, GL520_REG_TEMP2_MAX_HYST); + } else { + data->in_input[4] = gl520_read_value(client, GL520_REG_IN4_INPUT); + data->in_min[4] = gl520_read_value(client, GL520_REG_IN4_MIN); + data->in_max[4] = gl520_read_value(client, GL520_REG_IN4_MAX); + } + + data->last_updated = jiffies; + data->valid = 1; + } + + up(&data->update_lock); + + return data; +} + + +static int __init sensors_gl520sm_init(void) +{ + return i2c_add_driver(&gl520_driver); +} + +static void __exit sensors_gl520sm_exit(void) +{ + i2c_del_driver(&gl520_driver); +} + + +MODULE_AUTHOR("Frodo Looijaard , " + "Kyösti Mälkki , " + "Maarten Deprez "); +MODULE_DESCRIPTION("GL520SM driver"); +MODULE_LICENSE("GPL"); + +module_init(sensors_gl520sm_init); +module_exit(sensors_gl520sm_exit); diff -Nru a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c --- a/drivers/i2c/chips/isp1301_omap.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/isp1301_omap.c 2005-03-03 21:57:36 -08:00 @@ -1503,7 +1503,6 @@ isp->client.addr = address; i2c_set_clientdata(&isp->client, isp); isp->client.adapter = bus; - isp->client.id = 1301; isp->client.driver = &isp1301_driver; strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE); i2c = &isp->client; diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c --- a/drivers/i2c/chips/it87.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/it87.c 2005-03-03 21:57:36 -08:00 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -104,6 +105,9 @@ /* Update battery voltage after every reading if true */ static int update_vbat; +/* Not all BIOSes properly configure the PWM registers */ +static int fix_pwm_polarity; + /* Chip Type */ static u16 chip_type; @@ -224,6 +228,7 @@ static int it87_write_value(struct i2c_client *client, u8 register, u8 value); static struct it87_data *it87_update_device(struct device *dev); +static int it87_check_pwm(struct i2c_client *client); static void it87_init_client(struct i2c_client *client, struct it87_data *data); @@ -718,7 +723,6 @@ const char *name = ""; int is_isa = i2c_is_isa_adapter(adapter); int enable_pwm_interface; - int tmp; if (!is_isa && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -822,20 +826,12 @@ if ((err = i2c_attach_client(new_client))) goto ERROR2; + /* Check PWM configuration */ + enable_pwm_interface = it87_check_pwm(new_client); + /* Initialize the IT87 chip */ it87_init_client(new_client, data); - /* Some BIOSes fail to correctly configure the IT87 fans. All fans off - * and polarity set to active low is sign that this is the case so we - * disable pwm control to protect the user. */ - enable_pwm_interface = 1; - tmp = it87_read_value(new_client, IT87_REG_FAN_CTL); - if ((tmp & 0x87) == 0) { - enable_pwm_interface = 0; - dev_info(&new_client->dev, - "detected broken BIOS defaults, disabling pwm interface"); - } - /* Register sysfs hooks */ device_create_file(&new_client->dev, &dev_attr_in0_input); device_create_file(&new_client->dev, &dev_attr_in1_input); @@ -966,6 +962,56 @@ return i2c_smbus_write_byte_data(client, reg, value); } +/* Return 1 if and only if the PWM interface is safe to use */ +static int it87_check_pwm(struct i2c_client *client) +{ + /* Some BIOSes fail to correctly configure the IT87 fans. All fans off + * and polarity set to active low is sign that this is the case so we + * disable pwm control to protect the user. */ + int tmp = it87_read_value(client, IT87_REG_FAN_CTL); + if ((tmp & 0x87) == 0) { + if (fix_pwm_polarity) { + /* The user asks us to attempt a chip reconfiguration. + * This means switching to active high polarity and + * inverting all fan speed values. */ + int i; + u8 pwm[3]; + + for (i = 0; i < 3; i++) + pwm[i] = it87_read_value(client, + IT87_REG_PWM(i)); + + /* If any fan is in automatic pwm mode, the polarity + * might be correct, as suspicious as it seems, so we + * better don't change anything (but still disable the + * PWM interface). */ + if (!((pwm[0] | pwm[1] | pwm[2]) & 0x80)) { + dev_info(&client->dev, "Reconfiguring PWM to " + "active high polarity\n"); + it87_write_value(client, IT87_REG_FAN_CTL, + tmp | 0x87); + for (i = 0; i < 3; i++) + it87_write_value(client, + IT87_REG_PWM(i), + 0x7f & ~pwm[i]); + return 1; + } + + dev_info(&client->dev, "PWM configuration is " + "too broken to be fixed\n"); + } + + dev_info(&client->dev, "Detected broken BIOS " + "defaults, disabling PWM interface\n"); + return 0; + } else if (fix_pwm_polarity) { + dev_info(&client->dev, "PWM configuration looks " + "sane, won't touch\n"); + } + + return 1; +} + /* Called when we have found a new IT87. */ static void it87_init_client(struct i2c_client *client, struct it87_data *data) { @@ -1038,8 +1084,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { if (update_vbat) { /* Cleared after each update, so reenable. Value @@ -1126,6 +1172,8 @@ MODULE_DESCRIPTION("IT8705F, IT8712F, Sis950 driver"); module_param(update_vbat, bool, 0); MODULE_PARM_DESC(update_vbat, "Update vbat if set else return powerup value"); +module_param(fix_pwm_polarity, bool, 0); +MODULE_PARM_DESC(fix_pwm_polarity, "Force PWM polarity to active high (DANGEROUS)"); MODULE_LICENSE("GPL"); module_init(sm_it87_init); diff -Nru a/drivers/i2c/chips/lm63.c b/drivers/i2c/chips/lm63.c --- a/drivers/i2c/chips/lm63.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm63.c 2005-03-03 21:57:36 -08:00 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -492,9 +493,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ) || - (jiffies < data->last_updated) || - !data->valid) { + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { if (data->config & 0x04) { /* tachometer enabled */ /* order matters for fan1_input */ data->fan1_input = i2c_smbus_read_byte_data(client, diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c --- a/drivers/i2c/chips/lm75.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm75.c 2005-03-03 21:57:36 -08:00 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include "lm75.h" @@ -73,8 +74,6 @@ .detach_client = lm75_detach_client, }; -static int lm75_id; - #define show(value) \ static ssize_t show_##value(struct device *dev, char *buf) \ { \ @@ -196,8 +195,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - - new_client->id = lm75_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -263,8 +260,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting lm75 update\n"); data->temp_input = lm75_read_value(client, LM75_REG_TEMP); diff -Nru a/drivers/i2c/chips/lm77.c b/drivers/i2c/chips/lm77.c --- a/drivers/i2c/chips/lm77.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm77.c 2005-03-03 21:57:36 -08:00 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -81,8 +82,6 @@ .detach_client = lm77_detach_client, }; -static int lm77_id; - /* straight from the datasheet */ #define LM77_TEMP_MIN (-55000) #define LM77_TEMP_MAX 125000 @@ -295,8 +294,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - - new_client->id = lm77_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -364,8 +361,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting lm77 update\n"); data->temp_input = LM77_TEMP_FROM_REG(lm77_read_value(client, diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c --- a/drivers/i2c/chips/lm78.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm78.c 2005-03-03 21:57:36 -08:00 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -81,9 +82,8 @@ static inline u8 FAN_TO_REG(long rpm, int div) { - if (rpm == 0) + if (rpm <= 0) return 255; - rpm = SENSORS_LIMIT(rpm, 1, 1000000); return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } @@ -94,15 +94,15 @@ /* TEMP: mC (-128C to +127C) REG: 1C/bit, two's complement */ -static inline u8 TEMP_TO_REG(int val) +static inline s8 TEMP_TO_REG(int val) { int nval = SENSORS_LIMIT(val, -128000, 127000) ; - return nval<0 ? (nval-500)/1000+0x100 : (nval+500)/1000; + return nval<0 ? (nval-500)/1000 : (nval+500)/1000; } -static inline int TEMP_FROM_REG(u8 val) +static inline int TEMP_FROM_REG(s8 val) { - return (val>=0x80 ? val-0x100 : val) * 1000; + return val * 1000; } /* VID: mV @@ -112,16 +112,6 @@ return val==0x1f ? 0 : val>=0x10 ? 5100-val*100 : 2050-val*50; } -/* ALARMS: chip-specific bitmask - REG: (same) */ -#define ALARMS_FROM_REG(val) (val) - -/* FAN DIV: 1, 2, 4, or 8 (defaults to 2) - REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */ -static inline u8 DIV_TO_REG(int val) -{ - return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1; -} #define DIV_FROM_REG(val) (1 << (val)) /* There are some complications in a module like this. First off, LM78 chips @@ -157,9 +147,9 @@ u8 in_min[7]; /* Register value */ u8 fan[3]; /* Register value */ u8 fan_min[3]; /* Register value */ - u8 temp; /* Register value */ - u8 temp_over; /* Register value */ - u8 temp_hyst; /* Register value */ + s8 temp; /* Register value */ + s8 temp_over; /* Register value */ + s8 temp_hyst; /* Register value */ u8 fan_div[3]; /* Register encoding, shifted right */ u8 vid; /* Register encoding, combined */ u16 alarms; /* Register encoding, combined */ @@ -357,7 +347,17 @@ DIV_FROM_REG(data->fan_div[nr])); unsigned long val = simple_strtoul(buf, NULL, 10); int reg = lm78_read_value(client, LM78_REG_VID_FANDIV); - data->fan_div[nr] = DIV_TO_REG(val); + switch (val) { + case 1: data->fan_div[nr] = 0; break; + case 2: data->fan_div[nr] = 1; break; + case 4: data->fan_div[nr] = 2; break; + case 8: data->fan_div[nr] = 3; break; + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); + return -EINVAL; + } + switch (nr) { case 0: reg = (reg & 0xcf) | (data->fan_div[nr] << 4); @@ -430,7 +430,7 @@ static ssize_t show_alarms(struct device *dev, char *buf) { struct lm78_data *data = lm78_update_device(dev); - return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms)); + return sprintf(buf, "%u\n", data->alarms); } static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); @@ -633,17 +633,15 @@ { int err; - /* release ISA region first */ - if(i2c_is_isa_client(client)) - release_region(client->addr, LM78_EXTENT); - - /* now it's safe to scrap the rest */ if ((err = i2c_detach_client(client))) { dev_err(&client->dev, "Client deregistration failed, client not detached.\n"); return err; } + if(i2c_is_isa_client(client)) + release_region(client->addr, LM78_EXTENT); + kfree(i2c_get_clientdata(client)); return 0; @@ -653,9 +651,7 @@ We don't want to lock the whole ISA bus, so we lock each client separately. We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, - would slow down the LM78 access and should not be necessary. - There are some ugly typecasts here, but the good new is - they should - nowhere else be necessary! */ + would slow down the LM78 access and should not be necessary. */ static int lm78_read_value(struct i2c_client *client, u8 reg) { int res; @@ -709,8 +705,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(&client->dev, "Starting lm78 update\n"); diff -Nru a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c --- a/drivers/i2c/chips/lm80.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm80.c 2005-03-03 21:57:36 -08:00 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -99,10 +100,7 @@ #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val)<0?\ ((val)-500)/1000:((val)+500)/1000,0,255) -#define ALARMS_FROM_REG(val) (val) - #define DIV_FROM_REG(val) (1 << (val)) -#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) /* * Client data (each client gets its own) @@ -141,12 +139,6 @@ static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); /* - * Internal variables - */ - -static int lm80_id; - -/* * Driver data (common to all clients) */ @@ -269,7 +261,17 @@ DIV_FROM_REG(data->fan_div[nr])); val = simple_strtoul(buf, NULL, 10); - data->fan_div[nr] = DIV_TO_REG(val); + + switch (val) { + case 1: data->fan_div[nr] = 0; break; + case 2: data->fan_div[nr] = 1; break; + case 4: data->fan_div[nr] = 2; break; + case 8: data->fan_div[nr] = 3; break; + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); + return -EINVAL; + } reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1)))) | (data->fan_div[nr] << (2 * (nr + 1))); @@ -327,7 +329,7 @@ static ssize_t show_alarms(struct device *dev, char *buf) { struct lm80_data *data = lm80_update_device(dev); - return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms)); + return sprintf(buf, "%u\n", data->alarms); } static DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min0, set_in_min0); @@ -425,8 +427,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - - new_client->id = lm80_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -530,9 +530,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > 2 * HZ) || - (jiffies < data->last_updated) || !data->valid) { - + if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { dev_dbg(&client->dev, "Starting lm80 update\n"); for (i = 0; i <= 6; i++) { data->in[i] = diff -Nru a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c --- a/drivers/i2c/chips/lm83.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm83.c 2005-03-03 21:57:36 -08:00 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -150,12 +151,6 @@ }; /* - * Internal variables - */ - -static int lm83_id; - -/* * Sysfs stuff */ @@ -312,7 +307,6 @@ /* 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); @@ -369,9 +363,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ * 2) || - (jiffies < data->last_updated) || - !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { int nr; dev_dbg(&client->dev, "Updating lm83 data.\n"); diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c --- a/drivers/i2c/chips/lm85.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm85.c 2005-03-03 21:57:36 -08:00 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -389,9 +390,6 @@ .detach_client = lm85_detach_client, }; -/* Unique ID assigned to each LM85 detected */ -static int lm85_id; - /* 4 Fans */ static ssize_t show_fan(struct device *dev, char *buf, int nr) @@ -1148,16 +1146,10 @@ strlcpy(new_client->name, type_name, I2C_NAME_SIZE); /* Fill in the remaining client fields */ - new_client->id = lm85_id++; data->type = kind; data->valid = 0; init_MUTEX(&data->update_lock); - dev_dbg(&adapter->dev, "Assigning ID %d to %s at %d,0x%02x\n", - new_client->id, new_client->name, - i2c_adapter_id(new_client->adapter), - new_client->addr); - /* Tell the I2C layer a new client has arrived */ if ((err = i2c_attach_client(new_client))) goto ERROR1; @@ -1363,7 +1355,7 @@ down(&data->update_lock); if ( !data->valid || - (jiffies - data->last_reading > LM85_DATA_INTERVAL ) ) { + time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) { /* Things that change quickly */ dev_dbg(&client->dev, "Reading sensor values\n"); @@ -1417,7 +1409,7 @@ }; /* last_reading */ if ( !data->valid || - (jiffies - data->last_config > LM85_CONFIG_INTERVAL) ) { + time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL) ) { /* Things that don't change often */ dev_dbg(&client->dev, "Reading config values\n"); diff -Nru a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c --- a/drivers/i2c/chips/lm87.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm87.c 2005-03-03 21:57:36 -08:00 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -203,12 +204,6 @@ }; /* - * Internal variables - */ - -static int lm87_id; - -/* * Sysfs stuff */ @@ -569,7 +564,6 @@ /* We can fill in the remaining client fields */ strlcpy(new_client->name, "lm87", I2C_NAME_SIZE); - new_client->id = lm87_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -720,9 +714,7 @@ down(&data->update_lock); - if (jiffies - data->last_updated > HZ - || jiffies < data->last_updated - || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { int i, j; dev_dbg(&client->dev, "Updating data.\n"); diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c --- a/drivers/i2c/chips/lm90.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/lm90.c 2005-03-03 21:57:36 -08:00 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -190,12 +191,6 @@ }; /* - * Internal variables - */ - -static int lm90_id; - -/* * Sysfs stuff */ @@ -427,7 +422,6 @@ /* We can fill in the remaining client fields */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - new_client->id = lm90_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -495,9 +489,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ * 2) || - (jiffies < data->last_updated) || - !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { u8 oldh, newh; dev_dbg(&client->dev, "Updating lm90 data.\n"); diff -Nru a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/i2c/chips/m41t00.c 2005-03-03 21:57:36 -08:00 @@ -0,0 +1,247 @@ +/* + * drivers/i2c/chips/m41t00.c + * + * I2C client/driver for the ST M41T00 Real-Time Clock chip. + * + * Author: Mark A. Greer + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +/* + * This i2c client/driver wedges between the drivers/char/genrtc.c RTC + * interface and the SMBus interface of the i2c subsystem. + * It would be more efficient to use i2c msgs/i2c_transfer directly but, as + * recommened in .../Documentation/i2c/writing-clients section + * "Sending and receiving", using SMBus level communication is preferred. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define M41T00_DRV_NAME "m41t00" + +static DECLARE_MUTEX(m41t00_mutex); + +static struct i2c_driver m41t00_driver; +static struct i2c_client *save_client; + +static unsigned short ignore[] = { I2C_CLIENT_END }; +static unsigned short normal_addr[] = { 0x68, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_addr, + .normal_i2c_range = ignore, + .probe = ignore, + .probe_range = ignore, + .ignore = ignore, + .ignore_range = ignore, + .force = ignore, +}; + +ulong +m41t00_get_rtc_time(void) +{ + s32 sec, min, hour, day, mon, year; + s32 sec1, min1, hour1, day1, mon1, year1; + ulong limit = 10; + + sec = min = hour = day = mon = year = 0; + sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; + + down(&m41t00_mutex); + do { + if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) + && ((min = i2c_smbus_read_byte_data(save_client, 1)) + >= 0) + && ((hour = i2c_smbus_read_byte_data(save_client, 2)) + >= 0) + && ((day = i2c_smbus_read_byte_data(save_client, 4)) + >= 0) + && ((mon = i2c_smbus_read_byte_data(save_client, 5)) + >= 0) + && ((year = i2c_smbus_read_byte_data(save_client, 6)) + >= 0) + && ((sec == sec1) && (min == min1) && (hour == hour1) + && (day == day1) && (mon == mon1) + && (year == year1))) + + break; + + sec1 = sec; + min1 = min; + hour1 = hour; + day1 = day; + mon1 = mon; + year1 = year; + } while (--limit > 0); + up(&m41t00_mutex); + + if (limit == 0) { + dev_warn(&save_client->dev, + "m41t00: can't read rtc chip\n"); + sec = min = hour = day = mon = year = 0; + } + + sec &= 0x7f; + min &= 0x7f; + hour &= 0x3f; + day &= 0x3f; + mon &= 0x1f; + year &= 0xff; + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + + year += 1900; + if (year < 1970) + year += 100; + + return mktime(year, mon, day, hour, min, sec); +} + +static void +m41t00_set_tlet(ulong arg) +{ + struct rtc_time tm; + ulong nowtime = *(ulong *)arg; + + to_tm(nowtime, &tm); + tm.tm_year = (tm.tm_year - 1900) % 100; + + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + + down(&m41t00_mutex); + if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) + || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f) + < 0) + || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f) + < 0)) + + dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); + + up(&m41t00_mutex); + return; +} + +ulong new_time; + +DECLARE_TASKLET_DISABLED(m41t00_tasklet, m41t00_set_tlet, (ulong)&new_time); + +int +m41t00_set_rtc_time(ulong nowtime) +{ + new_time = nowtime; + + if (in_interrupt()) + tasklet_schedule(&m41t00_tasklet); + else + m41t00_set_tlet((ulong)&new_time); + + return 0; +} + +/* + ***************************************************************************** + * + * Driver Interface + * + ***************************************************************************** + */ +static int +m41t00_probe(struct i2c_adapter *adap, int addr, int kind) +{ + struct i2c_client *client; + int rc; + + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + + memset(client, 0, sizeof(struct i2c_client)); + strncpy(client->name, M41T00_DRV_NAME, I2C_NAME_SIZE); + client->id = m41t00_driver.id; + client->flags = I2C_DF_NOTIFY; + client->addr = addr; + client->adapter = adap; + client->driver = &m41t00_driver; + + if ((rc = i2c_attach_client(client)) != 0) { + kfree(client); + return rc; + } + + save_client = client; + return 0; +} + +static int +m41t00_attach(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, m41t00_probe); +} + +static int +m41t00_detach(struct i2c_client *client) +{ + int rc; + + if ((rc = i2c_detach_client(client)) == 0) { + kfree(i2c_get_clientdata(client)); + tasklet_kill(&m41t00_tasklet); + } + return rc; +} + +static struct i2c_driver m41t00_driver = { + .owner = THIS_MODULE, + .name = M41T00_DRV_NAME, + .id = I2C_DRIVERID_STM41T00, + .flags = I2C_DF_NOTIFY, + .attach_adapter = m41t00_attach, + .detach_client = m41t00_detach, +}; + +static int __init +m41t00_init(void) +{ + return i2c_add_driver(&m41t00_driver); +} + +static void __exit +m41t00_exit(void) +{ + i2c_del_driver(&m41t00_driver); + return; +} + +module_init(m41t00_init); +module_exit(m41t00_exit); + +MODULE_AUTHOR("Mark A. Greer "); +MODULE_DESCRIPTION("ST Microelectronics M41T00 RTC I2C Client Driver"); +MODULE_LICENSE("GPL"); diff -Nru a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c --- a/drivers/i2c/chips/max1619.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/max1619.c 2005-03-03 21:57:36 -08:00 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -117,12 +118,6 @@ }; /* - * Internal variables - */ - -static int max1619_id; - -/* * Sysfs stuff */ @@ -267,7 +262,6 @@ /* We can fill in the remaining client fields */ strlcpy(new_client->name, name, I2C_NAME_SIZE); - new_client->id = max1619_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -331,10 +325,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ * 2) || - (jiffies < data->last_updated) || - !data->valid) { - + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { dev_dbg(&client->dev, "Updating max1619 data.\n"); data->temp_input1 = i2c_smbus_read_byte_data(client, MAX1619_REG_R_LOCAL_TEMP); diff -Nru a/drivers/i2c/chips/pc87360.c b/drivers/i2c/chips/pc87360.c --- a/drivers/i2c/chips/pc87360.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/pc87360.c 2005-03-03 21:57:36 -08:00 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -1174,8 +1175,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ * 2) - || (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { dev_dbg(&client->dev, "Data update\n"); /* Fans */ diff -Nru a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c --- a/drivers/i2c/chips/pcf8574.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/pcf8574.c 2005-03-03 21:57:36 -08:00 @@ -77,8 +77,6 @@ .detach_client = pcf8574_detach_client, }; -static int pcf8574_id; - /* following are the sysfs callback functions */ static ssize_t show_read(struct device *dev, char *buf) { @@ -159,8 +157,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, client_name, I2C_NAME_SIZE); - - new_client->id = pcf8574_id++; init_MUTEX(&data->update_lock); /* Tell the I2C layer a new client has arrived */ diff -Nru a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c --- a/drivers/i2c/chips/pcf8591.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/pcf8591.c 2005-03-03 21:57:36 -08:00 @@ -98,8 +98,6 @@ .detach_client = pcf8591_detach_client, }; -static int pcf8591_id; - /* following are the sysfs callback functions */ #define show_in_channel(channel) \ static ssize_t show_in##channel##_input(struct device *dev, char *buf) \ @@ -201,8 +199,6 @@ /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE); - - new_client->id = pcf8591_id++; init_MUTEX(&data->update_lock); /* Tell the I2C layer a new client has arrived */ diff -Nru a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c --- a/drivers/i2c/chips/rtc8564.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/rtc8564.c 2005-03-03 21:57:36 -08:00 @@ -89,7 +89,7 @@ _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len); - if (!buf || !client) { + if (!buf) { ret = -EINVAL; goto done; } @@ -111,7 +111,7 @@ struct i2c_msg wr; int i; - if (!client || !data || len > 15) { + if (!data || len > 15) { ret = -EINVAL; goto done; } @@ -163,14 +163,12 @@ strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); i2c_set_clientdata(new_client, d); - new_client->id = rtc8564_driver.id; new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY; new_client->addr = addr; new_client->adapter = adap; new_client->driver = &rtc8564_driver; _DBG(1, "client=%p", new_client); - _DBG(1, "client.id=%d", new_client->id); /* init ctrl1 reg */ data[0] = 0; @@ -222,7 +220,7 @@ _DBG(1, "client=%p, dt=%p", client, dt); - if (!dt || !client) + if (!dt) return -EINVAL; memset(buf, 0, sizeof(buf)); @@ -256,7 +254,7 @@ _DBG(1, "client=%p, dt=%p", client, dt); - if (!dt || !client) + if (!dt) return -EINVAL; _DBGRTCTM(2, *dt); @@ -295,7 +293,7 @@ { struct rtc8564_data *data = i2c_get_clientdata(client); - if (!ctrl || !client) + if (!ctrl) return -1; *ctrl = data->ctrl; @@ -307,7 +305,7 @@ struct rtc8564_data *data = i2c_get_clientdata(client); unsigned char buf[2]; - if (!ctrl || !client) + if (!ctrl) return -1; buf[0] = *ctrl & 0xff; @@ -320,7 +318,7 @@ static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem) { - if (!mem || !client) + if (!mem) return -EINVAL; return rtc8564_read(client, mem->loc, mem->data, mem->nr); @@ -329,7 +327,7 @@ static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem) { - if (!mem || !client) + if (!mem) return -EINVAL; return rtc8564_write(client, mem->loc, mem->data, mem->nr); diff -Nru a/drivers/i2c/chips/sis5595.c b/drivers/i2c/chips/sis5595.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/drivers/i2c/chips/sis5595.c 2005-03-03 21:57:36 -08:00 @@ -0,0 +1,794 @@ +/* + sis5595.c - Part of lm_sensors, Linux kernel modules + for hardware monitoring + + Copyright (C) 1998 - 2001 Frodo Looijaard , + Kyösti Mälkki , and + Mark D. Studebaker + Ported to Linux 2.6 by Aurelien Jarno with + the help of Jean Delvare + + 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. +*/ + +/* + SiS southbridge has a LM78-like chip integrated on the same IC. + This driver is a customized copy of lm78.c + + Supports following revisions: + Version PCI ID PCI Revision + 1 1039/0008 AF or less + 2 1039/0008 B0 or greater + + Note: these chips contain a 0008 device which is incompatible with the + 5595. We recognize these by the presence of the listed + "blacklist" PCI ID and refuse to load. + + NOT SUPPORTED PCI ID BLACKLIST PCI ID + 540 0008 0540 + 550 0008 0550 + 5513 0008 5511 + 5581 0008 5597 + 5582 0008 5597 + 5597 0008 5597 + 5598 0008 5597/5598 + 630 0008 0630 + 645 0008 0645 + 730 0008 0730 + 735 0008 0735 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* If force_addr is set to anything different from 0, we forcibly enable + the device at the given address. */ +static u16 force_addr; +module_param(force_addr, ushort, 0); +MODULE_PARM_DESC(force_addr, + "Initialize the base address of the sensors"); + +/* Addresses to scan. + Note that we can't determine the ISA address until we have initialized + our module */ +static unsigned short normal_i2c[] = { I2C_CLIENT_END }; +static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END }; + +/* Insmod parameters */ +SENSORS_INSMOD_1(sis5595); + +/* Many SIS5595 constants specified below */ + +/* Length of ISA address segment */ +#define SIS5595_EXTENT 8 +/* PCI Config Registers */ +#define SIS5595_REVISION_REG 0x08 +#define SIS5595_BASE_REG 0x68 +#define SIS5595_PIN_REG 0x7A +#define SIS5595_ENABLE_REG 0x7B + +/* Where are the ISA address/data registers relative to the base address */ +#define SIS5595_ADDR_REG_OFFSET 5 +#define SIS5595_DATA_REG_OFFSET 6 + +/* The SIS5595 registers */ +#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2) +#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2) +#define SIS5595_REG_IN(nr) (0x20 + (nr)) + +#define SIS5595_REG_FAN_MIN(nr) (0x3b + (nr)) +#define SIS5595_REG_FAN(nr) (0x28 + (nr)) + +/* On the first version of the chip, the temp registers are separate. + On the second version, + TEMP pin is shared with IN4, configured in PCI register 0x7A. + The registers are the same as well. + OVER and HYST are really MAX and MIN. */ + +#define REV2MIN 0xb0 +#define SIS5595_REG_TEMP (( data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN(4) : 0x27 +#define SIS5595_REG_TEMP_OVER (( data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN_MAX(4) : 0x39 +#define SIS5595_REG_TEMP_HYST (( data->revision) >= REV2MIN) ? \ + SIS5595_REG_IN_MIN(4) : 0x3a + +#define SIS5595_REG_CONFIG 0x40 +#define SIS5595_REG_ALARM1 0x41 +#define SIS5595_REG_ALARM2 0x42 +#define SIS5595_REG_FANDIV 0x47 + +/* Conversions. Limit checking is only done on the TO_REG + variants. */ + +/* IN: mV, (0V to 4.08V) + REG: 16mV/bit */ +static inline u8 IN_TO_REG(unsigned long val) +{ + unsigned long nval = SENSORS_LIMIT(val, 0, 4080); + return (nval + 8) / 16; +} +#define IN_FROM_REG(val) ((val) * 16) + +static inline u8 FAN_TO_REG(long rpm, int div) +{ + if (rpm <= 0) + return 255; + return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); +} + +static inline int FAN_FROM_REG(u8 val, int div) +{ + return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div); +} + +/* TEMP: mC (-54.12C to +157.53C) + REG: 0.83C/bit + 52.12, two's complement */ +static inline int TEMP_FROM_REG(s8 val) +{ + return val * 830 + 52120; +} +static inline s8 TEMP_TO_REG(int val) +{ + int nval = SENSORS_LIMIT(val, -54120, 157530) ; + return nval<0 ? (nval-5212-415)/830 : (nval-5212+415)/830; +} + +/* FAN DIV: 1, 2, 4, or 8 (defaults to 2) + REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */ +static inline u8 DIV_TO_REG(int val) +{ + return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1; +} +#define DIV_FROM_REG(val) (1 << (val)) + +/* For the SIS5595, we need to keep some data in memory. That + data is pointed to by sis5595_list[NR]->data. The structure itself is + dynamically allocated, at the time when the new sis5595 client is + allocated. */ +struct sis5595_data { + struct i2c_client client; + struct semaphore lock; + + struct semaphore update_lock; + char valid; /* !=0 if following fields are valid */ + unsigned long last_updated; /* In jiffies */ + char maxins; /* == 3 if temp enabled, otherwise == 4 */ + u8 revision; /* Reg. value */ + + u8 in[5]; /* Register value */ + u8 in_max[5]; /* Register value */ + u8 in_min[5]; /* Register value */ + u8 fan[2]; /* Register value */ + u8 fan_min[2]; /* Register value */ + s8 temp; /* Register value */ + s8 temp_over; /* Register value */ + s8 temp_hyst; /* Register value */ + u8 fan_div[2]; /* Register encoding, shifted right */ + u16 alarms; /* Register encoding, combined */ +}; + +static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */ + +static int sis5595_attach_adapter(struct i2c_adapter *adapter); +static int sis5595_detect(struct i2c_adapter *adapter, int address, int kind); +static int sis5595_detach_client(struct i2c_client *client); + +static int sis5595_read_value(struct i2c_client *client, u8 register); +static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value); +static struct sis5595_data *sis5595_update_device(struct device *dev); +static void sis5595_init_client(struct i2c_client *client); + +static struct i2c_driver sis5595_driver = { + .owner = THIS_MODULE, + .name = "sis5595", + .id = I2C_DRIVERID_SIS5595, + .flags = I2C_DF_NOTIFY, + .attach_adapter = sis5595_attach_adapter, + .detach_client = sis5595_detach_client, +}; + +/* 4 Voltages */ +static ssize_t show_in(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); +} + +static ssize_t show_in_min(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); +} + +static ssize_t show_in_max(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); +} + +static ssize_t set_in_min(struct device *dev, const char *buf, + size_t count, int nr) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + data->in_min[nr] = IN_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]); + return count; +} + +static ssize_t set_in_max(struct device *dev, const char *buf, + size_t count, int nr) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + data->in_max[nr] = IN_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]); + return count; +} + +#define show_in_offset(offset) \ +static ssize_t \ + show_in##offset (struct device *dev, char *buf) \ +{ \ + return show_in(dev, buf, offset); \ +} \ +static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ + show_in##offset, NULL); \ +static ssize_t \ + show_in##offset##_min (struct device *dev, char *buf) \ +{ \ + return show_in_min(dev, buf, offset); \ +} \ +static ssize_t \ + show_in##offset##_max (struct device *dev, char *buf) \ +{ \ + return show_in_max(dev, buf, offset); \ +} \ +static ssize_t set_in##offset##_min (struct device *dev, \ + const char *buf, size_t count) \ +{ \ + return set_in_min(dev, buf, count, offset); \ +} \ +static ssize_t set_in##offset##_max (struct device *dev, \ + const char *buf, size_t count) \ +{ \ + return set_in_max(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ + show_in##offset##_min, set_in##offset##_min); \ +static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ + show_in##offset##_max, set_in##offset##_max); + +show_in_offset(0); +show_in_offset(1); +show_in_offset(2); +show_in_offset(3); +show_in_offset(4); + +/* Temperature */ +static ssize_t show_temp(struct device *dev, char *buf) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); +} + +static ssize_t show_temp_over(struct device *dev, char *buf) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); +} + +static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + data->temp_over = TEMP_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over); + return count; +} + +static ssize_t show_temp_hyst(struct device *dev, char *buf) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst)); +} + +static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + data->temp_hyst = TEMP_TO_REG(val); + sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst); + return count; +} + +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL); +static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, + show_temp_over, set_temp_over); +static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, + show_temp_hyst, set_temp_hyst); + +/* 2 Fans */ +static ssize_t show_fan(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], + DIV_FROM_REG(data->fan_div[nr])) ); +} + +static ssize_t show_fan_min(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])) ); +} + +static ssize_t set_fan_min(struct device *dev, const char *buf, + size_t count, int nr) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long val = simple_strtoul(buf, NULL, 10); + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); + sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); + return count; +} + +static ssize_t show_fan_div(struct device *dev, char *buf, int nr) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); +} + +/* Note: we save and restore the fan minimum here, because its value is + determined in part by the fan divisor. This follows the principle of + least suprise; the user doesn't expect the fan minimum to change just + because the divisor changed. */ +static ssize_t set_fan_div(struct device *dev, const char *buf, + size_t count, int nr) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + unsigned long min = FAN_FROM_REG(data->fan_min[nr], + DIV_FROM_REG(data->fan_div[nr])); + unsigned long val = simple_strtoul(buf, NULL, 10); + int reg = sis5595_read_value(client, SIS5595_REG_FANDIV); + switch (val) { + case 1: data->fan_div[nr] = 0; break; + case 2: data->fan_div[nr] = 1; break; + case 4: data->fan_div[nr] = 2; break; + case 8: data->fan_div[nr] = 3; break; + default: + dev_err(&client->dev, "fan_div value %ld not " + "supported. Choose one of 1, 2, 4 or 8!\n", val); + return -EINVAL; + } + + switch (nr) { + case 0: + reg = (reg & 0xcf) | (data->fan_div[nr] << 4); + break; + case 1: + reg = (reg & 0x3f) | (data->fan_div[nr] << 6); + break; + } + sis5595_write_value(client, SIS5595_REG_FANDIV, reg); + data->fan_min[nr] = + FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); + sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]); + return count; +} + +#define show_fan_offset(offset) \ +static ssize_t show_fan_##offset (struct device *dev, char *buf) \ +{ \ + return show_fan(dev, buf, offset - 1); \ +} \ +static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \ +{ \ + return show_fan_min(dev, buf, offset - 1); \ +} \ +static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \ +{ \ + return show_fan_div(dev, buf, offset - 1); \ +} \ +static ssize_t set_fan_##offset##_min (struct device *dev, \ + const char *buf, size_t count) \ +{ \ + return set_fan_min(dev, buf, count, offset - 1); \ +} \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_fan_##offset##_min, set_fan_##offset##_min); + +show_fan_offset(1); +show_fan_offset(2); + +static ssize_t set_fan_1_div(struct device *dev, const char *buf, + size_t count) +{ + return set_fan_div(dev, buf, count, 0) ; +} + +static ssize_t set_fan_2_div(struct device *dev, const char *buf, + size_t count) +{ + return set_fan_div(dev, buf, count, 1) ; +} +static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, + show_fan_1_div, set_fan_1_div); +static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, + show_fan_2_div, set_fan_2_div); + +/* Alarms */ +static ssize_t show_alarms(struct device *dev, char *buf) +{ + struct sis5595_data *data = sis5595_update_device(dev); + return sprintf(buf, "%d\n", data->alarms); +} +static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); + +/* This is called when the module is loaded */ +static int sis5595_attach_adapter(struct i2c_adapter *adapter) +{ + if (!(adapter->class & I2C_CLASS_HWMON)) + return 0; + return i2c_detect(adapter, &addr_data, sis5595_detect); +} + +int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) +{ + int err = 0; + int i; + struct i2c_client *new_client; + struct sis5595_data *data; + char val; + u16 a; + + /* Make sure we are probing the ISA bus!! */ + if (!i2c_is_isa_adapter(adapter)) + goto exit; + + if (force_addr) + address = force_addr & ~(SIS5595_EXTENT - 1); + /* Reserve the ISA region */ + if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) { + err = -EBUSY; + goto exit; + } + if (force_addr) { + dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n", address); + if (PCIBIOS_SUCCESSFUL != + pci_write_config_word(s_bridge, SIS5595_BASE_REG, address)) + goto exit_release; + if (PCIBIOS_SUCCESSFUL != + pci_read_config_word(s_bridge, SIS5595_BASE_REG, &a)) + goto exit_release; + if ((a & ~(SIS5595_EXTENT - 1)) != address) + /* doesn't work for some chips? */ + goto exit_release; + } + + if (PCIBIOS_SUCCESSFUL != + pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) { + goto exit_release; + } + if ((val & 0x80) == 0) { + if (PCIBIOS_SUCCESSFUL != + pci_write_config_byte(s_bridge, SIS5595_ENABLE_REG, + val | 0x80)) + goto exit_release; + if (PCIBIOS_SUCCESSFUL != + pci_read_config_byte(s_bridge, SIS5595_ENABLE_REG, &val)) + goto exit_release; + if ((val & 0x80) == 0) + /* doesn't work for some chips! */ + goto exit_release; + } + + if (!(data = kmalloc(sizeof(struct sis5595_data), GFP_KERNEL))) { + err = -ENOMEM; + goto exit_release; + } + memset(data, 0, sizeof(struct sis5595_data)); + + new_client = &data->client; + new_client->addr = address; + init_MUTEX(&data->lock); + i2c_set_clientdata(new_client, data); + new_client->adapter = adapter; + new_client->driver = &sis5595_driver; + new_client->flags = 0; + + /* Check revision and pin registers to determine whether 4 or 5 voltages */ + pci_read_config_byte(s_bridge, SIS5595_REVISION_REG, &(data->revision)); + /* 4 voltages, 1 temp */ + data->maxins = 3; + if (data->revision >= REV2MIN) { + pci_read_config_byte(s_bridge, SIS5595_PIN_REG, &val); + if (!(val & 0x80)) + /* 5 voltages, no temps */ + data->maxins = 4; + } + + /* Fill in the remaining client fields and put it into the global list */ + strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE); + + 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 SIS5595 chip */ + sis5595_init_client(new_client); + + /* A few vars need to be filled upon startup */ + for (i = 0; i < 2; i++) { + data->fan_min[i] = sis5595_read_value(new_client, + SIS5595_REG_FAN_MIN(i)); + } + + /* Register sysfs hooks */ + device_create_file(&new_client->dev, &dev_attr_in0_input); + device_create_file(&new_client->dev, &dev_attr_in0_min); + device_create_file(&new_client->dev, &dev_attr_in0_max); + device_create_file(&new_client->dev, &dev_attr_in1_input); + device_create_file(&new_client->dev, &dev_attr_in1_min); + device_create_file(&new_client->dev, &dev_attr_in1_max); + device_create_file(&new_client->dev, &dev_attr_in2_input); + device_create_file(&new_client->dev, &dev_attr_in2_min); + device_create_file(&new_client->dev, &dev_attr_in2_max); + device_create_file(&new_client->dev, &dev_attr_in3_input); + device_create_file(&new_client->dev, &dev_attr_in3_min); + device_create_file(&new_client->dev, &dev_attr_in3_max); + if (data->maxins == 4) { + device_create_file(&new_client->dev, &dev_attr_in4_input); + device_create_file(&new_client->dev, &dev_attr_in4_min); + device_create_file(&new_client->dev, &dev_attr_in4_max); + } + device_create_file(&new_client->dev, &dev_attr_fan1_input); + device_create_file(&new_client->dev, &dev_attr_fan1_min); + device_create_file(&new_client->dev, &dev_attr_fan1_div); + device_create_file(&new_client->dev, &dev_attr_fan2_input); + device_create_file(&new_client->dev, &dev_attr_fan2_min); + device_create_file(&new_client->dev, &dev_attr_fan2_div); + device_create_file(&new_client->dev, &dev_attr_alarms); + if (data->maxins == 3) { + device_create_file(&new_client->dev, &dev_attr_temp1_input); + device_create_file(&new_client->dev, &dev_attr_temp1_max); + device_create_file(&new_client->dev, &dev_attr_temp1_max_hyst); + } + return 0; + +exit_free: + kfree(data); +exit_release: + release_region(address, SIS5595_EXTENT); +exit: + return err; +} + +static int sis5595_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; + } + + if (i2c_is_isa_client(client)) + release_region(client->addr, SIS5595_EXTENT); + + kfree(i2c_get_clientdata(client)); + + return 0; +} + + +/* ISA access must be locked explicitly. */ +static int sis5595_read_value(struct i2c_client *client, u8 reg) +{ + int res; + + struct sis5595_data *data = i2c_get_clientdata(client); + down(&data->lock); + outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); + res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET); + up(&data->lock); + return res; +} + +static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + struct sis5595_data *data = i2c_get_clientdata(client); + down(&data->lock); + outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET); + outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET); + up(&data->lock); + return 0; +} + +/* Called when we have found a new SIS5595. */ +static void sis5595_init_client(struct i2c_client *client) +{ + u8 config = sis5595_read_value(client, SIS5595_REG_CONFIG); + if (!(config & 0x01)) + sis5595_write_value(client, SIS5595_REG_CONFIG, + (config & 0xf7) | 0x01); +} + +static struct sis5595_data *sis5595_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sis5595_data *data = i2c_get_clientdata(client); + int i; + + down(&data->update_lock); + + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { + + for (i = 0; i <= data->maxins; i++) { + data->in[i] = + sis5595_read_value(client, SIS5595_REG_IN(i)); + data->in_min[i] = + sis5595_read_value(client, + SIS5595_REG_IN_MIN(i)); + data->in_max[i] = + sis5595_read_value(client, + SIS5595_REG_IN_MAX(i)); + } + for (i = 0; i < 2; i++) { + data->fan[i] = + sis5595_read_value(client, SIS5595_REG_FAN(i)); + data->fan_min[i] = + sis5595_read_value(client, + SIS5595_REG_FAN_MIN(i)); + } + if (data->maxins == 3) { + data->temp = + sis5595_read_value(client, SIS5595_REG_TEMP); + data->temp_over = + sis5595_read_value(client, SIS5595_REG_TEMP_OVER); + data->temp_hyst = + sis5595_read_value(client, SIS5595_REG_TEMP_HYST); + } + i = sis5595_read_value(client, SIS5595_REG_FANDIV); + data->fan_div[0] = (i >> 4) & 0x03; + data->fan_div[1] = i >> 6; + data->alarms = + sis5595_read_value(client, SIS5595_REG_ALARM1) | + (sis5595_read_value(client, SIS5595_REG_ALARM2) << 8); + data->last_updated = jiffies; + data->valid = 1; + } + + up(&data->update_lock); + + return data; +} + +static struct pci_device_id sis5595_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, sis5595_pci_ids); + +static int blacklist[] __devinitdata = { + PCI_DEVICE_ID_SI_540, + PCI_DEVICE_ID_SI_550, + PCI_DEVICE_ID_SI_630, + PCI_DEVICE_ID_SI_645, + PCI_DEVICE_ID_SI_730, + PCI_DEVICE_ID_SI_735, + PCI_DEVICE_ID_SI_5511, /* 5513 chip has the 0008 device but + that ID shows up in other chips so we + use the 5511 ID for recognition */ + PCI_DEVICE_ID_SI_5597, + PCI_DEVICE_ID_SI_5598, + 0 }; + +static int __devinit sis5595_pci_probe(struct pci_dev *dev, + const struct pci_device_id *id) +{ + u16 val; + int *i; + int addr = 0; + + for (i = blacklist; *i != 0; i++) { + struct pci_dev *dev; + dev = pci_get_device(PCI_VENDOR_ID_SI, *i, NULL); + if (dev) { + dev_err(&dev->dev, "Looked for SIS5595 but found unsupported device %.4x\n", *i); + pci_dev_put(dev); + return -ENODEV; + } + } + + if (PCIBIOS_SUCCESSFUL != + pci_read_config_word(dev, SIS5595_BASE_REG, &val)) + return -ENODEV; + + addr = val & ~(SIS5595_EXTENT - 1); + if (addr == 0 && force_addr == 0) { + dev_err(&dev->dev, "Base address not set - upgrade BIOS or use force_addr=0xaddr\n"); + return -ENODEV; + } + if (force_addr) + addr = force_addr; /* so detect will get called */ + + if (!addr) { + dev_err(&dev->dev,"No SiS 5595 sensors found.\n"); + return -ENODEV; + } + normal_isa[0] = addr; + + s_bridge = pci_dev_get(dev); + if (i2c_add_driver(&sis5595_driver)) { + pci_dev_put(s_bridge); + s_bridge = NULL; + } + + /* Always return failure here. This is to allow other drivers to bind + * to this pci device. We don't really want to have control over the + * pci device, we only wanted to read as few register values from it. + */ + return -ENODEV; +} + +static struct pci_driver sis5595_pci_driver = { + .name = "sis5595", + .id_table = sis5595_pci_ids, + .probe = sis5595_pci_probe, +}; + +static int __init sm_sis5595_init(void) +{ + return pci_register_driver(&sis5595_pci_driver); +} + +static void __exit sm_sis5595_exit(void) +{ + pci_unregister_driver(&sis5595_pci_driver); + if (s_bridge != NULL) { + i2c_del_driver(&sis5595_driver); + pci_dev_put(s_bridge); + s_bridge = NULL; + } +} + +MODULE_AUTHOR("Aurelien Jarno "); +MODULE_DESCRIPTION("SiS 5595 Sensor device"); +MODULE_LICENSE("GPL"); + +module_init(sm_sis5595_init); +module_exit(sm_sis5595_exit); diff -Nru a/drivers/i2c/chips/smsc47b397.c b/drivers/i2c/chips/smsc47b397.c --- a/drivers/i2c/chips/smsc47b397.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/smsc47b397.c 2005-03-03 21:57:36 -08:00 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -130,9 +131,7 @@ down(&data->update_lock); - if (time_after(jiffies - data->last_updated, (unsigned long)HZ) - || time_before(jiffies, data->last_updated) || !data->valid) { - + if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { dev_dbg(&client->dev, "starting device update...\n"); /* 4 temperature inputs, 4 fan inputs */ diff -Nru a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c --- a/drivers/i2c/chips/smsc47m1.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/smsc47m1.c 2005-03-03 21:57:36 -08:00 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,6 @@ struct smsc47m1_data { struct i2c_client client; struct semaphore lock; - int sysctl_id; struct semaphore update_lock; unsigned long last_updated; /* In jiffies */ @@ -133,8 +133,6 @@ int init); -static int smsc47m1_id; - static struct i2c_driver smsc47m1_driver = { .owner = THIS_MODULE, .name = "smsc47m1", @@ -420,8 +418,6 @@ new_client->flags = 0; strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE); - - new_client->id = smsc47m1_id++; init_MUTEX(&data->update_lock); /* If no function is properly configured, there's no point in @@ -532,8 +528,7 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || init) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { int i; for (i = 0; i < 2; i++) { diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c --- a/drivers/i2c/chips/via686a.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/via686a.c 2005-03-03 21:57:36 -08:00 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -726,9 +727,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { - + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { for (i = 0; i <= 4; i++) { data->in[i] = via686a_read_value(client, VIA686A_REG_IN(i)); diff -Nru a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c --- a/drivers/i2c/chips/w83627hf.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/w83627hf.c 2005-03-03 21:57:36 -08:00 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1321,6 +1322,27 @@ data->pwmenable[2] = 1; if(init) { + /* Enable temp2 */ + tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG); + if (tmp & 0x01) { + dev_warn(&client->dev, "Enabling temp2, readings " + "might not make sense\n"); + w83627hf_write_value(client, W83781D_REG_TEMP2_CONFIG, + tmp & 0xfe); + } + + /* Enable temp3 */ + if (type != w83697hf) { + tmp = w83627hf_read_value(client, + W83781D_REG_TEMP3_CONFIG); + if (tmp & 0x01) { + dev_warn(&client->dev, "Enabling temp3, " + "readings might not make sense\n"); + w83627hf_write_value(client, + W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); + } + } + if (type == w83627hf) { /* enable PWM2 control (can't hurt since PWM reg should have been reset to 0xff) */ @@ -1350,8 +1372,8 @@ down(&data->update_lock); - if ((jiffies - data->last_updated > HZ + HZ / 2) || - (jiffies < data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { for (i = 0; i <= 8; i++) { /* skip missing sensors */ if (((data->type == w83697hf) && (i == 1)) || diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c --- a/drivers/i2c/chips/w83781d.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/w83781d.c 2005-03-03 21:57:36 -08:00 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -1562,11 +1563,28 @@ } #endif /* W83781D_RT */ - if (init) { + if (init && type != as99127f) { + /* Enable temp2 */ + tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG); + if (tmp & 0x01) { + dev_warn(&client->dev, "Enabling temp2, readings " + "might not make sense\n"); + w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG, + tmp & 0xfe); + } + + /* Enable temp3 */ if (type != w83783s && type != w83697hf) { - w83781d_write_value(client, W83781D_REG_TEMP3_CONFIG, - 0x00); + tmp = w83781d_read_value(client, + W83781D_REG_TEMP3_CONFIG); + if (tmp & 0x01) { + dev_warn(&client->dev, "Enabling temp3, " + "readings might not make sense\n"); + w83781d_write_value(client, + W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); + } } + if (type != w83781d) { /* enable comparator mode for temp2 and temp3 so alarm indication will work correctly */ @@ -1592,9 +1610,8 @@ down(&data->update_lock); - if (time_after - (jiffies - data->last_updated, (unsigned long) (HZ + HZ / 2)) - || time_before(jiffies, data->last_updated) || !data->valid) { + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) + || !data->valid) { dev_dbg(dev, "Starting device update\n"); for (i = 0; i <= 8; i++) { diff -Nru a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c --- a/drivers/i2c/chips/w83l785ts.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/chips/w83l785ts.c 2005-03-03 21:57:36 -08:00 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -114,12 +115,6 @@ }; /* - * Internal variables - */ - -static int w83l785ts_id = 0; - -/* * Sysfs stuff */ @@ -229,7 +224,6 @@ /* We can fill in the remaining client fields. */ strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE); - new_client->id = w83l785ts_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -301,9 +295,7 @@ down(&data->update_lock); - if (!data->valid - || (jiffies - data->last_updated > HZ * 2) - || (jiffies < data->last_updated)) { + if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) { dev_dbg(&client->dev, "Updating w83l785ts data.\n"); data->temp = w83l785ts_read_value(client, W83L785TS_REG_TEMP, data->temp); diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/i2c-core.c 2005-03-03 21:57:36 -08:00 @@ -38,12 +38,43 @@ static DECLARE_MUTEX(core_lists); static DEFINE_IDR(i2c_adapter_idr); -int i2c_device_probe(struct device *dev) +/* match always succeeds, as we want the probe() to tell if we really accept this match */ +static int i2c_device_match(struct device *dev, struct device_driver *drv) +{ + return 1; +} + +static int i2c_bus_suspend(struct device * dev, pm_message_t state) +{ + int rc = 0; + + if (dev->driver && dev->driver->suspend) + rc = dev->driver->suspend(dev,state,0); + return rc; +} + +static int i2c_bus_resume(struct device * dev) +{ + int rc = 0; + + if (dev->driver && dev->driver->resume) + rc = dev->driver->resume(dev,0); + return rc; +} + +static struct bus_type i2c_bus_type = { + .name = "i2c", + .match = i2c_device_match, + .suspend = i2c_bus_suspend, + .resume = i2c_bus_resume, +}; + +static int i2c_device_probe(struct device *dev) { return -ENODEV; } -int i2c_device_remove(struct device *dev) +static int i2c_device_remove(struct device *dev) { return 0; } @@ -523,38 +554,6 @@ up(&adap->clist_lock); } - -/* match always succeeds, as we want the probe() to tell if we really accept this match */ -static int i2c_device_match(struct device *dev, struct device_driver *drv) -{ - return 1; -} - -static int i2c_bus_suspend(struct device * dev, u32 state) -{ - int rc = 0; - - if (dev->driver && dev->driver->suspend) - rc = dev->driver->suspend(dev,state,0); - return rc; -} - -static int i2c_bus_resume(struct device * dev) -{ - int rc = 0; - - if (dev->driver && dev->driver->resume) - rc = dev->driver->resume(dev,0); - return rc; -} - -struct bus_type i2c_bus_type = { - .name = "i2c", - .match = i2c_device_match, - .suspend = i2c_bus_suspend, - .resume = i2c_bus_resume, -}; - static int __init i2c_init(void) { int retval; @@ -583,7 +582,7 @@ * ---------------------------------------------------- */ -int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg msgs[],int num) +int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) { int ret; @@ -860,7 +859,7 @@ /* CRC over count bytes in the first array plus the bytes in the rest array if it is non-null. rest[0] is the (length of rest) - 1 and is included. */ -u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest) +static u8 i2c_smbus_partial_pec(u8 crc, int count, u8 *first, u8 *rest) { int i; @@ -872,7 +871,7 @@ return crc; } -u8 i2c_smbus_pec(int count, u8 *first, u8 *rest) +static u8 i2c_smbus_pec(int count, u8 *first, u8 *rest) { return i2c_smbus_partial_pec(0, count, first, rest); } @@ -880,8 +879,8 @@ /* Returns new "size" (transaction type) Note that we convert byte to byte_data and byte_data to word_data rather than invent new xxx_PEC transactions. */ -int i2c_smbus_add_pec(u16 addr, u8 command, int size, - union i2c_smbus_data *data) +static int i2c_smbus_add_pec(u16 addr, u8 command, int size, + union i2c_smbus_data *data) { u8 buf[3]; @@ -910,8 +909,8 @@ return size; } -int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial, - union i2c_smbus_data *data) +static int i2c_smbus_check_pec(u16 addr, u8 command, int size, u8 partial, + union i2c_smbus_data *data) { u8 buf[3], rpec, cpec; diff -Nru a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c --- a/drivers/i2c/i2c-dev.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/i2c-dev.c 2005-03-03 21:57:36 -08:00 @@ -55,7 +55,7 @@ static struct i2c_dev *i2c_dev_array[I2C_MINORS]; static DEFINE_SPINLOCK(i2c_dev_array_lock); -struct i2c_dev *i2c_dev_get_by_minor(unsigned index) +static struct i2c_dev *i2c_dev_get_by_minor(unsigned index) { struct i2c_dev *i2c_dev; @@ -65,7 +65,7 @@ return i2c_dev; } -struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap) +static struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev = NULL; @@ -173,8 +173,8 @@ return ret; } -int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg) +static int i2cdev_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct i2c_client *client = (struct i2c_client *)file->private_data; struct i2c_rdwr_ioctl_data rdwr_arg; @@ -507,7 +507,6 @@ static struct i2c_client i2cdev_client_template = { .name = "I2C /dev entry", - .id = 1, .addr = -1, .driver = &i2cdev_driver, }; diff -Nru a/drivers/i2c/i2c-sensor-detect.c b/drivers/i2c/i2c-sensor-detect.c --- a/drivers/i2c/i2c-sensor-detect.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/i2c/i2c-sensor-detect.c 2005-03-03 21:57:36 -08:00 @@ -19,17 +19,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include -#include -#include -#include -#include -#include #include #include -#include static unsigned short empty[] = {I2C_CLIENT_END}; static unsigned int empty_isa[] = {I2C_CLIENT_ISA_END}; diff -Nru a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c --- a/drivers/macintosh/therm_windtunnel.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/macintosh/therm_windtunnel.c 2005-03-03 21:57:36 -08:00 @@ -47,8 +47,6 @@ #define LOG_TEMP 0 /* continously log temperature */ #define I2C_DRIVERID_G4FAN 0x9001 /* fixme */ -#define THERMOSTAT_CLIENT_ID 1 -#define FAN_CLIENT_ID 2 static int do_probe( struct i2c_adapter *adapter, int addr, int kind); @@ -372,7 +370,6 @@ goto out; printk("ADM1030 fan controller [@%02x]\n", cl->addr ); - cl->id = FAN_CLIENT_ID; strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) ); if( !i2c_attach_client(cl) ) @@ -412,7 +409,6 @@ x.overheat_temp = os_temp; x.overheat_hyst = hyst_temp; - cl->id = THERMOSTAT_CLIENT_ID; strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) ); if( !i2c_attach_client(cl) ) diff -Nru a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c --- a/drivers/media/common/saa7146_i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/common/saa7146_i2c.c 2005-03-03 21:57:36 -08:00 @@ -25,7 +25,7 @@ sent through the saa7146. have a look at the specifications p. 122 ff to understand this. it returns the number of u32s to send, or -1 in case of an error. */ -static int saa7146_i2c_msg_prepare(const struct i2c_msg m[], int num, u32 *op) +static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) { int h1, h2; int i, j, addr; @@ -89,7 +89,7 @@ which bytes were read through the adapter and write them back to the corresponding i2c-message. but instead, we simply write back all bytes. fixme: this could be improved. */ -static int saa7146_i2c_msg_cleanup(const struct i2c_msg m[], int num, u32 *op) +static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op) { int i, j; int op_count = 0; @@ -272,7 +272,7 @@ return 0; } -int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg msgs[], int num, int retries) +int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries) { int i = 0, count = 0; u32* buffer = dev->d_i2c.cpu_addr; @@ -372,7 +372,7 @@ } /* utility functions */ -static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg msg[], int num) +static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) { struct saa7146_dev* dev = i2c_get_adapdata(adapter); diff -Nru a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c --- a/drivers/media/dvb/b2c2/skystar2.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/dvb/b2c2/skystar2.c 2005-03-03 21:57:36 -08:00 @@ -293,7 +293,7 @@ return buf - start; } -static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msgs[], int num) +static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num) { struct adapter *tmp = i2c_get_adapdata(adapter); int i, ret = 0; diff -Nru a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c --- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c 2005-03-03 21:57:36 -08:00 @@ -38,7 +38,7 @@ /* * I2C master xfer function */ -static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num) { struct usb_dibusb *dib = i2c_get_adapdata(adap); int i; diff -Nru a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c 2005-03-03 21:57:36 -08:00 @@ -252,7 +252,7 @@ return rcv_len; } -static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msg[], int num) +static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) { struct ttusb *ttusb = i2c_get_adapdata(adapter); int i = 0; diff -Nru a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c --- a/drivers/media/video/adv7170.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/adv7170.c 2005-03-03 21:57:36 -08:00 @@ -402,7 +402,6 @@ .force = force }; -static int adv7170_i2c_id = 0; static struct i2c_driver i2c_driver_adv7170; static int @@ -432,7 +431,6 @@ client->adapter = adapter; client->driver = &i2c_driver_adv7170; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = adv7170_i2c_id++; if ((client->addr == I2C_ADV7170 >> 1) || (client->addr == (I2C_ADV7170 >> 1) + 1)) { dname = adv7170_name; @@ -444,8 +442,7 @@ kfree(client); return 0; } - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "%s[%d]", dname, client->id); + strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); encoder = kmalloc(sizeof(struct adv7170), GFP_KERNEL); if (encoder == NULL) { diff -Nru a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c --- a/drivers/media/video/adv7175.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/adv7175.c 2005-03-03 21:57:36 -08:00 @@ -452,7 +452,6 @@ .force = force }; -static int adv7175_i2c_id = 0; static struct i2c_driver i2c_driver_adv7175; static int @@ -482,7 +481,6 @@ client->adapter = adapter; client->driver = &i2c_driver_adv7175; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = adv7175_i2c_id++; if ((client->addr == I2C_ADV7175 >> 1) || (client->addr == (I2C_ADV7175 >> 1) + 1)) { dname = adv7175_name; @@ -494,8 +492,7 @@ kfree(client); return 0; } - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "%s[%d]", dname, client->id); + strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client))); encoder = kmalloc(sizeof(struct adv7175), GFP_KERNEL); if (encoder == NULL) { diff -Nru a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c --- a/drivers/media/video/bt819.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/bt819.c 2005-03-03 21:57:36 -08:00 @@ -517,7 +517,6 @@ .force = force }; -static int bt819_i2c_id = 0; static struct i2c_driver i2c_driver_bt819; static int @@ -546,7 +545,6 @@ client->adapter = adapter; client->driver = &i2c_driver_bt819; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = bt819_i2c_id++; decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL); if (decoder == NULL) { @@ -568,16 +566,13 @@ id = bt819_read(client, 0x17); switch (id & 0xf0) { case 0x70: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "bt819a[%d]", client->id); + strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client))); break; case 0x60: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "bt817a[%d]", client->id); + strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client))); break; case 0x20: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "bt815a[%d]", client->id); + strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client))); break; default: dprintk(1, diff -Nru a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c --- a/drivers/media/video/bt856.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/bt856.c 2005-03-03 21:57:36 -08:00 @@ -306,7 +306,6 @@ .force = force }; -static int bt856_i2c_id = 0; static struct i2c_driver i2c_driver_bt856; static int @@ -335,9 +334,7 @@ client->adapter = adapter; client->driver = &i2c_driver_bt856; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = bt856_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "bt856[%d]", client->id); + strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL); if (encoder == NULL) { diff -Nru a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c --- a/drivers/media/video/bttv-i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/bttv-i2c.c 2005-03-03 21:57:36 -08:00 @@ -245,7 +245,7 @@ return retval; } -static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) +static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct bttv *btv = i2c_get_adapdata(i2c_adap); int retval = 0; @@ -330,7 +330,6 @@ static struct i2c_client bttv_i2c_client_template = { I2C_DEVNAME("bttv internal"), - .id = -1, }; diff -Nru a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c --- a/drivers/media/video/cx88/cx88-i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/cx88/cx88-i2c.c 2005-03-03 21:57:36 -08:00 @@ -141,7 +141,6 @@ static struct i2c_client cx8800_i2c_client_template = { I2C_DEVNAME("cx88xx internal"), - .id = -1, }; static char *i2c_devs[128] = { diff -Nru a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c --- a/drivers/media/video/ovcamchip/ovcamchip_core.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c 2005-03-03 21:57:36 -08:00 @@ -422,7 +422,6 @@ static struct i2c_client client_template = { I2C_DEVNAME("(unset)"), - .id = -1, .driver = &driver, }; diff -Nru a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c --- a/drivers/media/video/saa5246a.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa5246a.c 2005-03-03 21:57:36 -08:00 @@ -185,7 +185,6 @@ }; static struct i2c_client client_template = { - .id = -1, .driver = &i2c_driver_videotext, .name = "(unset)", }; diff -Nru a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c --- a/drivers/media/video/saa5249.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa5249.c 2005-03-03 21:57:36 -08:00 @@ -258,7 +258,6 @@ }; static struct i2c_client client_template = { - .id = -1, .driver = &i2c_driver_videotext, .name = "(unset)", }; diff -Nru a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c --- a/drivers/media/video/saa7110.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa7110.c 2005-03-03 21:57:36 -08:00 @@ -476,7 +476,6 @@ .force = force }; -static int saa7110_i2c_id = 0; static struct i2c_driver i2c_driver_saa7110; static int @@ -507,9 +506,7 @@ client->adapter = adapter; client->driver = &i2c_driver_saa7110; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = saa7110_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "saa7110[%d]", client->id); + strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client))); decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); if (decoder == 0) { diff -Nru a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c --- a/drivers/media/video/saa7111.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa7111.c 2005-03-03 21:57:36 -08:00 @@ -500,7 +500,6 @@ .force = force }; -static int saa7111_i2c_id = 0; static struct i2c_driver i2c_driver_saa7111; static int @@ -530,9 +529,7 @@ client->adapter = adapter; client->driver = &i2c_driver_saa7111; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = saa7111_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "saa7111[%d]", client->id); + strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client))); decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL); if (decoder == NULL) { diff -Nru a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c --- a/drivers/media/video/saa7114.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa7114.c 2005-03-03 21:57:36 -08:00 @@ -838,7 +838,6 @@ .force = force }; -static int saa7114_i2c_id = 0; static struct i2c_driver i2c_driver_saa7114; static int @@ -871,9 +870,7 @@ client->adapter = adapter; client->driver = &i2c_driver_saa7114; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = saa7114_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "saa7114[%d]", client->id); + strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client))); decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL); if (decoder == NULL) { diff -Nru a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c --- a/drivers/media/video/saa7134/saa7134-i2c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa7134/saa7134-i2c.c 2005-03-03 21:57:36 -08:00 @@ -236,7 +236,7 @@ } static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], int num) + struct i2c_msg *msgs, int num) { struct saa7134_dev *dev = i2c_adap->algo_data; enum i2c_status status; @@ -362,7 +362,6 @@ static struct i2c_client saa7134_client_template = { I2C_DEVNAME("saa7134 internal"), - .id = -1, }; /* ----------------------------------------------------------- */ diff -Nru a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c --- a/drivers/media/video/saa7185.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/saa7185.c 2005-03-03 21:57:36 -08:00 @@ -398,7 +398,6 @@ .force = force }; -static int saa7185_i2c_id = 0; static struct i2c_driver i2c_driver_saa7185; static int @@ -427,9 +426,7 @@ client->adapter = adapter; client->driver = &i2c_driver_saa7185; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = saa7185_i2c_id++; - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "saa7185[%d]", client->id); + strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client))); encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL); if (encoder == NULL) { diff -Nru a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c --- a/drivers/media/video/tda7432.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tda7432.c 2005-03-03 21:57:36 -08:00 @@ -528,7 +528,6 @@ static struct i2c_client client_template = { I2C_DEVNAME("tda7432"), - .id = -1, .driver = &driver, }; diff -Nru a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c --- a/drivers/media/video/tda9840.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tda9840.c 2005-03-03 21:57:36 -08:00 @@ -51,9 +51,6 @@ static struct i2c_driver driver; static struct i2c_client client_template; -/* unique ID allocation */ -static int tda9840_id = 0; - static int command(struct i2c_client *client, unsigned int cmd, void *arg) { int result; @@ -179,7 +176,6 @@ /* fill client structure */ memcpy(client, &client_template, sizeof(struct i2c_client)); - client->id = tda9840_id++; client->addr = address; client->adapter = adapter; diff -Nru a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c --- a/drivers/media/video/tda9875.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tda9875.c 2005-03-03 21:57:36 -08:00 @@ -399,7 +399,6 @@ static struct i2c_client client_template = { I2C_DEVNAME("tda9875"), - .id = -1, .driver = &driver, }; diff -Nru a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c --- a/drivers/media/video/tea6415c.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tea6415c.c 2005-03-03 21:57:36 -08:00 @@ -51,9 +51,6 @@ static struct i2c_driver driver; static struct i2c_client client_template; -/* unique ID allocation */ -static int tea6415c_id = 0; - /* this function is called by i2c_probe */ static int detect(struct i2c_adapter *adapter, int address, int kind) { @@ -73,7 +70,6 @@ /* fill client structure */ memcpy(client, &client_template, sizeof(struct i2c_client)); - client->id = tea6415c_id++; client->addr = address; client->adapter = adapter; diff -Nru a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c --- a/drivers/media/video/tea6420.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tea6420.c 2005-03-03 21:57:36 -08:00 @@ -48,9 +48,6 @@ static struct i2c_driver driver; static struct i2c_client client_template; -/* unique ID allocation */ -static int tea6420_id = 0; - /* make a connection between the input 'i' and the output 'o' with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) @@ -111,7 +108,6 @@ /* fill client structure */ memcpy(client, &client_template, sizeof(struct i2c_client)); - client->id = tea6420_id++; client->addr = address; client->adapter = adapter; diff -Nru a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c --- a/drivers/media/video/tuner-3036.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/tuner-3036.c 2005-03-03 21:57:36 -08:00 @@ -192,7 +192,6 @@ static struct i2c_client client_template = { - .id = -1, .driver = &i2c_driver_tuner, .name = "SAB3036", }; diff -Nru a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c --- a/drivers/media/video/vpx3220.c 2005-03-03 21:57:36 -08:00 +++ b/drivers/media/video/vpx3220.c 2005-03-03 21:57:36 -08:00 @@ -587,7 +587,6 @@ .force = force }; -static int vpx3220_i2c_id = 0; static struct i2c_driver vpx3220_i2c_driver; static int @@ -634,7 +633,6 @@ client->adapter = adapter; client->driver = &vpx3220_i2c_driver; client->flags = I2C_CLIENT_ALLOW_USE; - client->id = vpx3220_i2c_id++; /* Check for manufacture ID and part number */ if (kind < 0) { @@ -655,16 +653,16 @@ vpx3220_read(client, 0x01); switch (pn) { case 0x4680: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "vpx3220a[%d]", client->id); + strlcpy(I2C_NAME(client), "vpx3220a", + sizeof(I2C_NAME(client))); break; case 0x4260: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "vpx3216b[%d]", client->id); + strlcpy(I2C_NAME(client), "vpx3216b", + sizeof(I2C_NAME(client))); break; case 0x4280: - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "vpx3214c[%d]", client->id); + strlcpy(I2C_NAME(client), "vpx3214c", + sizeof(I2C_NAME(client))); break; default: dprintk(1, @@ -675,9 +673,8 @@ return 0; } } else { - snprintf(I2C_NAME(client), sizeof(I2C_NAME(client)) - 1, - "forced vpx32xx[%d]", - client->id); + strlcpy(I2C_NAME(client), "forced vpx32xx", + sizeof(I2C_NAME(client))); } decoder = kmalloc(sizeof(struct vpx3220), GFP_KERNEL); diff -Nru a/include/linux/i2c-id.h b/include/linux/i2c-id.h --- a/include/linux/i2c-id.h 2005-03-03 21:57:36 -08:00 +++ b/include/linux/i2c-id.h 2005-03-03 21:57:36 -08:00 @@ -20,8 +20,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ------------------------------------------------------------------------- */ -/* $Id: i2c-id.h,v 1.68 2003/02/25 02:55:18 mds Exp $ */ - #ifndef LINUX_I2C_ID_H #define LINUX_I2C_ID_H @@ -196,11 +194,15 @@ #define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */ #define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */ #define I2C_ALGO_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */ -#define I2C_ALGO_PCA 0x150000 /* PCA 9564 style adapters */ - #define I2C_ALGO_SIBYTE 0x150000 /* Broadcom SiByte SOCs */ -#define I2C_ALGO_SGI 0x160000 /* SGI algorithm */ -#define I2C_ALGO_AU1550 0x170000 /* Au1550 PSC algorithm */ +#define I2C_ALGO_SGI 0x160000 /* SGI algorithm */ + +#define I2C_ALGO_USB 0x170000 /* USB algorithm */ +#define I2C_ALGO_VIRT 0x180000 /* Virtual bus adapter */ + +#define I2C_ALGO_MV64XXX 0x190000 /* Marvell mv64xxx i2c ctlr */ +#define I2C_ALGO_PCA 0x1a0000 /* PCA 9564 style adapters */ +#define I2C_ALGO_AU1550 0x1b0000 /* Au1550 PSC algorithm */ #define I2C_ALGO_EXP 0x800000 /* experimental */ @@ -240,6 +242,7 @@ #define I2C_HW_B_IXP4XX 0x17 /* GPIO on IXP4XX systems */ #define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */ #define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */ +#define I2C_HW_B_PCILYNX 0x1a /* TI PCILynx I2C adapter */ #define I2C_HW_B_CX2388x 0x1b /* connexant 2388x based tv cards */ /* --- PCF 8584 based algorithms */ @@ -309,5 +312,8 @@ /* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00 #endif /* LINUX_I2C_ID_H */ diff -Nru a/include/linux/i2c.h b/include/linux/i2c.h --- a/include/linux/i2c.h 2005-03-03 21:57:36 -08:00 +++ b/include/linux/i2c.h 2005-03-03 21:57:36 -08:00 @@ -55,7 +55,7 @@ /* Transfer num messages. */ -extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],int num); +extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); /* * Some adapter types (i.e. PCF 8584 based ones) may support slave behaviuor. @@ -134,8 +134,6 @@ }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) -extern struct bus_type i2c_bus_type; - #define I2C_NAME_SIZE 50 /* @@ -144,7 +142,6 @@ * function is mainly used for lookup & other admin. functions. */ struct i2c_client { - int id; unsigned int flags; /* div., see below */ unsigned int addr; /* chip address - NOTE: 7bit */ /* addresses are stored in the */ @@ -190,11 +187,11 @@ char name[32]; /* textual description */ unsigned int id; - /* If an adapter algorithm can't to I2C-level access, set master_xfer + /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated using common I2C messages */ - int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg msgs[], + int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, @@ -302,8 +299,8 @@ }; /* Internal numbers to terminate lists */ -#define I2C_CLIENT_END 0xfffe -#define I2C_CLIENT_ISA_END 0xfffefffe +#define I2C_CLIENT_END 0xfffeU +#define I2C_CLIENT_ISA_END 0xfffefffeU /* The numbers to use to set I2C bus address */ #define ANY_I2C_BUS 0xffff @@ -423,22 +420,22 @@ #define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ -#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ - I2C_FUNC_SMBUS_WRITE_BYTE -#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \ - I2C_FUNC_SMBUS_WRITE_BYTE_DATA -#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA -#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA -#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK -#define I2C_FUNC_SMBUS_I2C_BLOCK_2 I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 -#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC -#define I2C_FUNC_SMBUS_WORD_DATA_PEC I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) +#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2) +#define I2C_FUNC_SMBUS_BLOCK_DATA_PEC (I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC) +#define I2C_FUNC_SMBUS_WORD_DATA_PEC (I2C_FUNC_SMBUS_READ_WORD_DATA_PEC | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC) #define I2C_FUNC_SMBUS_READ_BYTE_PEC I2C_FUNC_SMBUS_READ_BYTE_DATA #define I2C_FUNC_SMBUS_WRITE_BYTE_PEC I2C_FUNC_SMBUS_WRITE_BYTE_DATA @@ -447,14 +444,14 @@ #define I2C_FUNC_SMBUS_BYTE_PEC I2C_FUNC_SMBUS_BYTE_DATA #define I2C_FUNC_SMBUS_BYTE_DATA_PEC I2C_FUNC_SMBUS_WORD_DATA -#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ - I2C_FUNC_SMBUS_BYTE | \ - I2C_FUNC_SMBUS_BYTE_DATA | \ - I2C_FUNC_SMBUS_WORD_DATA | \ - I2C_FUNC_SMBUS_PROC_CALL | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ - I2C_FUNC_SMBUS_I2C_BLOCK +#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ + I2C_FUNC_SMBUS_I2C_BLOCK) /* * Data for SMBus Messages diff -Nru a/include/linux/mv643xx.h b/include/linux/mv643xx.h --- a/include/linux/mv643xx.h 2005-03-03 21:57:36 -08:00 +++ b/include/linux/mv643xx.h 2005-03-03 21:57:36 -08:00 @@ -977,12 +977,9 @@ /* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020 /****************************************/ /* GPP Interface Registers */ @@ -1083,6 +1080,14 @@ u8 brg_can_tune; u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { + u32 freq_m; + u32 freq_n; + u32 timeout; /* In milliseconds */ + u32 retries; }; #endif /* __ASM_MV64340_H */ diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h --- a/include/linux/pci_ids.h 2005-03-03 21:57:36 -08:00 +++ b/include/linux/pci_ids.h 2005-03-03 21:57:36 -08:00 @@ -1098,6 +1098,7 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 #define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e +#define PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS 0x0052 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 diff -Nru a/include/media/saa7146.h b/include/media/saa7146.h --- a/include/media/saa7146.h 2005-03-03 21:57:36 -08:00 +++ b/include/media/saa7146.h 2005-03-03 21:57:36 -08:00 @@ -157,7 +157,7 @@ /* from saa7146_i2c.c */ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate); -int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg msgs[], int num, int retries); +int saa7146_i2c_transfer(struct saa7146_dev *saa, const struct i2c_msg *msgs, int num, int retries); /* from saa7146_core.c */ extern struct list_head saa7146_devices; diff -Nru a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c --- a/sound/oss/dmasound/dac3550a.c 2005-03-03 21:57:36 -08:00 +++ b/sound/oss/dmasound/dac3550a.c 2005-03-03 21:57:36 -08:00 @@ -40,9 +40,6 @@ static int daca_detect_client(struct i2c_adapter *adapter, int address); static int daca_detach_client(struct i2c_client *client); -/* Unique ID allocation */ -static int daca_id; - struct i2c_driver daca_driver = { .owner = THIS_MODULE, .name = "DAC3550A driver V " DACA_VERSION, @@ -176,7 +173,6 @@ new_client->driver = &daca_driver; new_client->flags = 0; strcpy(new_client->name, client_name); - new_client->id = daca_id++; /* racy... */ if (daca_init_client(new_client)) goto bail; diff -Nru a/sound/ppc/keywest.c b/sound/ppc/keywest.c --- a/sound/ppc/keywest.c 2005-03-03 21:57:36 -08:00 +++ b/sound/ppc/keywest.c 2005-03-03 21:57:36 -08:00 @@ -76,8 +76,6 @@ new_client->flags = 0; strcpy(i2c_device_name(new_client), keywest_ctx->name); - - new_client->id = keywest_ctx->id++; /* Automatically unique */ keywest_ctx->client = new_client; /* Tell the i2c layer a new client has arrived */