summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrodo Looijaard <frodol@dds.nl>1999-01-07 20:07:15 +0000
committerFrodo Looijaard <frodol@dds.nl>1999-01-07 20:07:15 +0000
commit340b7c5e7bf401259729b949a4a6f5dc060c164f (patch)
tree243b7ece875c8ff211548376b9135cc8ef229f4e
parentdabc5bfbb686f36117947c74256b6122bc1d3613 (diff)
downloadlm-sensors-git-340b7c5e7bf401259729b949a4a6f5dc060c164f.tar.gz
This commit was manufactured by cvs2svn to create tag 'V2-1-1'.V2-1-1
git-svn-id: http://lm-sensors.org/svn/lm-sensors/tags/V2-1-1@148 7894878c-1315-0410-8ee3-d5d059ff63e0
-rw-r--r--kernel/Module.mk49
-rw-r--r--kernel/busses/i2c-isa.c198
-rw-r--r--kernel/busses/i2c-piix4.c443
-rw-r--r--kernel/chips/eeprom.c387
-rw-r--r--kernel/chips/gl518sm.c674
-rw-r--r--kernel/chips/lm75.c363
-rw-r--r--kernel/chips/lm78.c926
-rw-r--r--kernel/chips/lm80.c686
-rw-r--r--kernel/chips/w83781d.c1120
-rw-r--r--kernel/compat.h85
-rw-r--r--kernel/i2c-proc.c485
-rw-r--r--kernel/include/compat.h85
-rw-r--r--kernel/include/i2c-isa.h158
-rw-r--r--kernel/include/i2c.h30
-rw-r--r--kernel/include/isa.h158
-rw-r--r--kernel/include/sensors.h227
-rw-r--r--kernel/include/smbus.h299
-rw-r--r--kernel/sensors.c617
-rw-r--r--kernel/smbus.c277
19 files changed, 0 insertions, 7267 deletions
diff --git a/kernel/Module.mk b/kernel/Module.mk
deleted file mode 100644
index afb57a60..00000000
--- a/kernel/Module.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Module.mk - Makefile for a Linux module for reading sensor data.
-# Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-#
-# 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.
-
-# Note that MODULE_DIR (the directory in which this file resides) is a
-# 'simply expanded variable'. That means that its value is substituted
-# verbatim in the rules, until it is redefined.
-MODULE_DIR := src
-
-# Regrettably, even 'simply expanded variables' will not put their currently
-# defined value verbatim into the command-list of rules...
-SRCTARGETS := $(MODULE_DIR)/smbus.o $(MODULE_DIR)/piix4.o $(MODULE_DIR)/isa.o \
- $(MODULE_DIR)/lm78.o $(MODULE_DIR)/sensors.o \
- $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/lm75.o \
- $(MODULE_DIR)/i2c-proc.o $(MODULE_DIR)/gl518sm.o \
- $(MODULE_DIR)/eeprom.o $(MODULE_DIR)/w83781d.o \
- $(MODULE_DIR)/lm80.o
-
-SRCHEADERFILES := $(MODULE_DIR)/sensors.h $(MODULE_DIR)/isa.h \
- $(MODULE_DIR)/smbus.h
-
-# Include all dependency files
-INCLUDEFILES += $(SRCTARGETS:.o=.d)
-
-all-src: $(SRCTARGETS)
-all :: all-src
-
-install-src:
- $(MKDIR) $(MODDIR) $(SYSINCLUDEDIR)
- $(INSTALL) -o root -g root -m 644 $(SRCTARGETS) $(MODDIR)
- $(INSTALL) -o root -g root -m 644 $(SRCHEADERFILES) $(SYSINCLUDEDIR)
-install :: install-src
-
-clean-src:
- $(RM) $(SRCTARGETS) $(SRCTARGETS:.o=.d)
-clean :: clean-src
diff --git a/kernel/busses/i2c-isa.c b/kernel/busses/i2c-isa.c
deleted file mode 100644
index 8ec904ae..00000000
--- a/kernel/busses/i2c-isa.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- isa.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-/* This implements an i2c algorithm/adapter for ISA bus. Not that this is
- on first sight very useful; almost no functionality is preserved.
- Except that it makes writing drivers for chips which can be on both
- the SMBus and the ISA bus very much easier. See lm78.c for an example
- of this. */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#include "i2c.h"
-#ifdef SPINLOCK
-#include <asm/spinlock.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#include "version.h"
-#include "isa.h"
-
-static int isa_master_xfer (struct isa_adapter *adap,
- struct i2c_msg msgs[], int num);
-static int isa_slave_send (struct isa_adapter *adap, char *data, int len);
-static int isa_slave_recv (struct isa_adapter *adap, char *data, int len);
-static int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
- unsigned long arg);
-static int isa_client_register (struct isa_client *client);
-static int isa_client_unregister (struct isa_client *client);
-
-static int isa_init(void);
-static int isa_cleanup(void);
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-/* This is the actual algorithm we define */
-static struct isa_algorithm isa_algorithm = {
- /* name */ "ISA bus adapter",
- /* id */ ALGO_ISA,
- /* master_xfer */ &isa_master_xfer,
- /* slave_send */ &isa_slave_send,
- /* slave_rcv */ &isa_slave_recv,
- /* algo_control */ &isa_algo_control,
- /* client_register */ &isa_client_register,
- /* client_unregister*/&isa_client_unregister
-};
-
-/* There can only be one... */
-static struct isa_adapter isa_adapter;
-
-/* Used in isa_init/cleanup */
-static int isa_initialized;
-
-/* Algorithm master_xfer call-back implementation. Can't do that... */
-int isa_master_xfer (struct isa_adapter *adap, struct i2c_msg msgs[],
- int num)
-{
-#ifdef DEBUG
- printk("isa.o: isa_master_xfer called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Algorithm slave_send call-back implementation. Can't do that... */
-int isa_slave_send (struct isa_adapter *adap, char *data, int len)
-{
-#ifdef DEBUG
- printk("isa.o: isa_slave_send called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Algorithm slave_recv call-back implementation. Can't do that... */
-int isa_slave_recv (struct isa_adapter *adap, char *data, int len)
-{
-#ifdef DEBUG
- printk("isa.o: isa_slave_recv called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Here we can put additional calls to modify the workings of the algorithm.
- But right now, there is no need for that. */
-int isa_algo_control (struct isa_adapter *adap, unsigned int cmd,
- unsigned long arg)
-{
- return 0;
-}
-
-/* Ehm... This is called when a client is registered to an adapter. We could
- do all kinds of neat stuff here like, ehm - returning success? */
-int isa_client_register (struct isa_client *client)
-{
- return 0;
-}
-
-int isa_client_unregister (struct isa_client *client)
-{
- return 0;
-}
-
-int isa_init(void)
-{
- int res;
- printk("isa.o version %s (%s)\n",LM_VERSION,LM_DATE);
-#ifdef DEBUG
- if (isa_initialized) {
- printk("isa.o: Oops, isa_init called a second time!\n");
- return -EBUSY;
- }
-#endif
- isa_initialized = 0;
- if ((res = isa_add_algorithm(&isa_algorithm))) {
- printk("isa.o: Algorithm registration failed, module not inserted.\n");
- isa_cleanup();
- return res;
- }
- isa_initialized++;
- strcpy(isa_adapter.name,"ISA main adapter");
- isa_adapter.id = ALGO_ISA | ISA_MAIN;
- isa_adapter.algo = &isa_algorithm;
- if ((res = isa_add_adapter(&isa_adapter))) {
- printk("isa.o: Adapter registration failed, "
- "module isa.o is not inserted\n.");
- isa_cleanup();
- return res;
- }
- isa_initialized++;
- printk("isa.o: ISA bus access for i2c modules initialized.\n");
- return 0;
-}
-
-int isa_cleanup(void)
-{
- int res;
- if (isa_initialized >= 2)
- {
- if ((res = isa_del_adapter(&isa_adapter))) {
- printk("isa.o: Adapter deregistration failed, module not removed.\n");
- return res;
- } else
- isa_initialized--;
- }
- if (isa_initialized >= 1)
- {
- if ((res = isa_del_algorithm(&isa_algorithm))) {
- printk("isa.o: Algorithm deregistration failed, module not removed.\n");
- return res;
- } else
- isa_initialized--;
- }
- return 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("ISA bus access through i2c");
-
-int init_module(void)
-{
- return isa_init();
-}
-
-int cleanup_module(void)
-{
- return isa_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/busses/i2c-piix4.c b/kernel/busses/i2c-piix4.c
deleted file mode 100644
index 349cc516..00000000
--- a/kernel/busses/i2c-piix4.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- piix4.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
-
- 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.
-*/
-
-/* Note: we assume there can only be one PIIX4, with one SMBus interface */
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include "smbus.h"
-#include "version.h"
-#include "compat.h"
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54))
-#include <linux/bios32.h>
-#endif
-
-
-/* PIIX4 SMBus address offsets */
-#define SMBHSTSTS (0 + piix4_smba)
-#define SMBHSLVSTS (1 + piix4_smba)
-#define SMBHSTCNT (2 + piix4_smba)
-#define SMBHSTCMD (3 + piix4_smba)
-#define SMBHSTADD (4 + piix4_smba)
-#define SMBHSTDAT0 (5 + piix4_smba)
-#define SMBHSTDAT1 (6 + piix4_smba)
-#define SMBBLKDAT (7 + piix4_smba)
-#define SMBSLVCNT (8 + piix4_smba)
-#define SMBSHDWCMD (9 + piix4_smba)
-#define SMBSLVEVT (0xA + piix4_smba)
-#define SMBSLVDAT (0xC + piix4_smba)
-
-/* PCI Address Constants */
-#define SMBBA 0x090
-#define SMBHSTCFG 0x0D2
-#define SMBSLVC 0x0D3
-#define SMBSHDW1 0x0D4
-#define SMBSHDW2 0x0D5
-#define SMBREV 0x0D6
-
-/* Other settings */
-#define MAX_TIMEOUT 500
-#define ENABLE_INT9 0
-
-/* PIIX4 constants */
-#define PIIX4_QUICK 0x00
-#define PIIX4_BYTE 0x04
-#define PIIX4_BYTE_DATA 0x08
-#define PIIX4_WORD_DATA 0x0C
-#define PIIX4_BLOCK_DATA 0x14
-
-
-static int piix4_init(void);
-static int piix4_cleanup(void);
-static int piix4_setup(void);
-static s32 piix4_access(u8 addr, char read_write,
- u8 command, int size, union smbus_data * data);
-static void piix4_do_pause( unsigned int amount );
-static int piix4_transaction(void);
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-static struct smbus_adapter piix4_adapter;
-static int piix4_initialized;
-static unsigned short piix4_smba = 0;
-
-
-/* Detect whether a PIIX4 can be found, and initialize it, where necessary.
- Note the differences between kernels with the old PCI BIOS interface and
- newer kernels with the real PCI interface. In compat.h some things are
- defined to make the transition easier. */
-int piix4_setup(void)
-{
- int error_return=0;
- unsigned char temp;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54))
- struct pci_dev *PIIX4_dev;
-#else
- unsigned char PIIX4_bus, PIIX4_devfn;
- int i,res;
-#endif
-
- /* First check whether we can access PCI at all */
- if (pci_present() == 0) {
- printk("piix4.o: Error: No PCI-bus found!\n");
- error_return=-ENODEV;
- goto END;
- }
-
- /* Look for the PIIX4, function 3 */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54))
- /* Note: we keep on searching until we have found 'function 3' */
- PIIX4_dev = NULL;
- do
- PIIX4_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, PIIX4_dev);
- while(PIIX4_dev && (PCI_FUNC(PIIX4_dev->devfn) != 3));
- if(PIIX4_dev == NULL) {
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54) */
- for (i = 0;
- ! (res = pcibios_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3,
- i,&PIIX4_bus, &PIIX4_devfn)) &&
- PCI_FUNC(PIIX4_devfn) != 3;
- i++);
-
- if (res) {
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54) */
- printk("piix4.o: Error: Can't detect PIIX4, function 3!\n");
- error_return=-ENODEV;
- goto END;
- }
-
-/* Determine the address of the SMBus areas */
- pci_read_config_word_united(PIIX4_dev, PIIX4_bus ,PIIX4_devfn,
- SMBBA,&piix4_smba);
- piix4_smba &= 0xfff0;
-
- if (check_region(piix4_smba, 8)) {
- printk("piix4.o: PIIX4_smb region 0x%x already in use!\n", piix4_smba);
- error_return=-ENODEV;
- goto END;
- }
-
- pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn,
- SMBHSTCFG, &temp);
-
-
-#ifdef FORCE_PIIX4_ENABLE
-/* This should never need to be done, but has been noted that
- many Dell machines have the SMBus interface on the PIIX4
- disabled!? NOTE: This assumes I/O space and other allocations WERE
- done by the Bios! Don't complain if your hardware does weird
- things after enabling this. :') Check for Bios updates before
- resorting to this. */
- if ((temp & 1) == 0) {
- pci_write_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn,
- SMBHSTCFG, temp | 1);
- printk("piix4.0: WARNING: PIIX4 SMBus interface has been FORCEFULLY "
- "ENABLED!!\n");
- /* Update configuration value */
- pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn,
- SMBHSTCFG, &temp);
- /* Note: We test the bit again in the next 'if' just to be sure... */
- }
-#endif /* FORCE_PIIX4_ENABLE */
-
- if ((temp & 1) == 0) {
- printk("SMBUS: Error: Host SMBus controller not enabled!\n");
- error_return=-ENODEV;
- goto END;
- }
-
- /* Everything is happy, let's grab the memory and set things up. */
- request_region(piix4_smba, 8, "piix4");
-
-#ifdef DEBUG
- if ((temp & 0x0E) == 8)
- printk("piix4.o: PIIX4 using Interrupt 9 for SMBus.\n");
- else if ((temp & 0x0E) == 0)
- printk("piix4.o: PIIX4 using Interrupt SMI# for SMBus.\n");
- else
- printk("piix4.o: PIIX4: Illegal Interrupt configuration (or code out "
- "of date)!\n");
-
- pci_read_config_byte_united(PIIX4_dev, PIIX4_bus, PIIX4_devfn, SMBREV,
- &temp);
- printk("piix4.o: SMBREV = 0x%X\n",temp);
- printk("piix4.o: PIIX4_smba = 0x%X\n",piix4_smba);
-#endif /* DEBUG */
-
-END:
- return error_return;
-}
-
-
-/* Internally used pause function */
-void piix4_do_pause( unsigned int amount )
-{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(amount);
-}
-
-/* Another internally used function */
-int piix4_transaction(void)
-{
- int temp;
- int result=0;
- int timeout=0;
-
-#ifdef DEBUG
- printk("piix4.o: Transaction: CNT=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, "
- "DAT1=%02x\n",
- inb_p(SMBHSTCNT),inb_p(SMBHSTCMD),inb_p(SMBHSTADD),inb_p(SMBHSTDAT0),
- inb_p(SMBHSTDAT1));
-#endif
-
- /* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-#ifdef DEBUG
- printk("piix4.o: SMBus busy (%02x). Resetting... \n",temp);
-#endif
- outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-#ifdef DEBUG
- printk("piix4.o: Failed! (%02x)\n",temp);
-#endif
- return -1;
- } else {
-#ifdef DEBUG
- printk("piix4.o: Successfull!\n");
-#endif
- }
- }
-
- /* start the transaction by setting bit 6 */
- outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
-
- /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
- do {
- piix4_do_pause(1);
- temp=inb_p(SMBHSTSTS);
- } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
-
- /* If the SMBus is still busy, we give up */
- if (timeout >= MAX_TIMEOUT) {
-#ifdef DEBUG
- printk("piix4.o: SMBus Timeout!\n");
- result = -1;
-#endif
- }
-
- if (temp & 0x10) {
- result = -1;
-#ifdef DEBUG
- printk("piix4.o: Error: Failed bus transaction\n");
-#endif
- }
-
- if (temp & 0x08) {
- result = -1;
- printk("piix4.o: Bus collision! SMBus may be locked until next hard
- reset. (sorry!)\n");
- /* Clock stops and slave is stuck in mid-transmission */
- }
-
- if (temp & 0x04) {
- result = -1;
-#ifdef DEBUG
- printk("piix4.o: Error: no response!\n");
-#endif
- }
-
- if (inb_p(SMBHSTSTS) != 0x00)
- outb_p( inb(SMBHSTSTS), SMBHSTSTS);
-
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
-#ifdef DEBUG
- printk("piix4.o: Failed reset at end of transaction (%02x)\n",temp);
-#endif
- }
- return result;
-}
-
-/* Return -1 on error. See smbus.h for more information */
-s32 piix4_access(u8 addr, char read_write,
- u8 command, int size, union smbus_data * data)
-{
- int i,len;
-
- switch(size) {
- case SMBUS_PROC_CALL:
- printk("piix4.o: SMBUS_PROC_CALL not supported!\n");
- return -1;
- case SMBUS_QUICK:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
- size = PIIX4_QUICK;
- break;
- case SMBUS_BYTE:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
- if (read_write == SMBUS_WRITE)
- outb_p(command, SMBHSTCMD);
- size = PIIX4_BYTE;
- break;
- case SMBUS_BYTE_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == SMBUS_WRITE)
- outb_p(data->byte,SMBHSTDAT0);
- size = PIIX4_BYTE_DATA;
- break;
- case SMBUS_WORD_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == SMBUS_WRITE) {
- outb_p(data->word & 0xff,SMBHSTDAT0);
- outb_p((data->word & 0xff00) >> 8,SMBHSTDAT1);
- }
- size = PIIX4_WORD_DATA;
- break;
- case SMBUS_BLOCK_DATA:
- outb_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMBHSTADD);
- outb_p(command, SMBHSTCMD);
- if (read_write == SMBUS_WRITE) {
- len = data->block[0];
- if (len < 0)
- len = 0;
- if (len > 32)
- len = 32;
- outb_p(len,SMBHSTDAT0);
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= len; i ++)
- outb_p(data->block[i],SMBBLKDAT);
- }
- size = PIIX4_BLOCK_DATA;
- break;
- }
-
- outb_p((size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT);
-
- if (piix4_transaction()) /* Error in transaction */
- return -1;
-
- if ((read_write == SMBUS_WRITE) || (size == PIIX4_QUICK))
- return 0;
-
-
- switch(size) {
- case PIIX4_BYTE: /* Where is the result put? I assume here it is in
- SMBHSTDAT0 but it might just as well be in the
- SMBHSTCMD. No clue in the docs */
-
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case PIIX4_BYTE_DATA:
- data->byte = inb_p(SMBHSTDAT0);
- break;
- case PIIX4_WORD_DATA:
- data->word = inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8);
- break;
- case PIIX4_BLOCK_DATA:
- data->block[0] = inb_p(SMBHSTDAT0);
- i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */
- for (i = 1; i <= data->block[0]; i++)
- data->block[i] = inb_p(SMBBLKDAT);
- break;
- }
- return 0;
-}
-
-
-int piix4_init(void)
-{
- int res;
- printk("piix4.o version %s (%s)\n",LM_VERSION,LM_DATE);
-#ifdef DEBUG
-/* PE- It might be good to make this a permanent part of the code! */
- if (piix4_initialized) {
- printk("piix4.o: Oops, piix4_init called a second time!\n");
- return -EBUSY;
- }
-#endif
- piix4_initialized = 0;
- if ((res = piix4_setup())) {
- printk("piix4.o: PIIX4 not detected, module not inserted.\n");
- piix4_cleanup();
- return res;
- }
- piix4_initialized ++;
- sprintf(piix4_adapter.name,"SMBus PIIX4 adapter at %04x",piix4_smba);
- piix4_adapter.id = ALGO_SMBUS | SMBUS_PIIX4;
- piix4_adapter.algo = &smbus_algorithm;
- piix4_adapter.smbus_access = &piix4_access;
- if ((res = smbus_add_adapter(&piix4_adapter))) {
- printk("piix4.o: Adapter registration failed, module not inserted.\n");
- piix4_cleanup();
- return res;
- }
- piix4_initialized++;
- printk("piix4.o: PIIX4 bus detected and initialized\n");
- return 0;
-}
-
-int piix4_cleanup(void)
-{
- int res;
- if (piix4_initialized >= 2)
- {
- if ((res = smbus_del_adapter(&piix4_adapter))) {
- printk("piix4.o: smbus_del_adapter failed, module not removed\n");
- return res;
- } else
- piix4_initialized--;
- }
- if (piix4_initialized >= 1) {
- release_region(piix4_smba, 8);
- piix4_initialized--;
- }
- return 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("PIIX4 SMBus driver");
-
-int init_module(void)
-{
- return piix4_init();
-}
-
-int cleanup_module(void)
-{
- return piix4_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/eeprom.c b/kernel/chips/eeprom.c
deleted file mode 100644
index 20f1f876..00000000
--- a/kernel/chips/eeprom.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- eeprom.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include "smbus.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "version.h"
-
-/* Many constants specified below */
-
-/* EEPROM memory types: */
-#define ONE_K 1
-#define TWO_K 2
-#define FOUR_K 3
-#define EIGHT_K 4
-#define SIXTEEN_K 5
-
-/* Conversions */
-/* Size of EEPROM in bytes */
-#define EEPROM_SIZE 128
-
-/* Each client has this additional data */
-struct eeprom_data {
- int sysctl_id;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u8 data[EEPROM_SIZE]; /* Register values */
- int memtype;
-};
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-static int eeprom_init(void);
-static int eeprom_cleanup(void);
-
-static int eeprom_attach_adapter(struct i2c_adapter *adapter);
-static int eeprom_detach_client(struct i2c_client *client);
-static int eeprom_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-
-static void eeprom_inc_use (struct i2c_client *client);
-static void eeprom_dec_use (struct i2c_client *client);
-
-static u16 swap_bytes(u16 val);
-
-static int eeprom_read_value(struct i2c_client *client, u8 reg);
-static int eeprom_write_value(struct i2c_client *client, u8 reg, u16 value);
-
-static void eeprom_contents(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void eeprom_update_client(struct i2c_client *client);
-
-
-/* This is the driver that will be inserted */
-static struct i2c_driver eeprom_driver = {
- /* name */ "EEPROM READER",
- /* id */ I2C_DRIVERID_EEPROM,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &eeprom_attach_adapter,
- /* detach_client */ &eeprom_detach_client,
- /* command */ &eeprom_command,
- /* inc_use */ &eeprom_inc_use,
- /* dec_use */ &eeprom_dec_use
-};
-
-/* These files are created for each detected EEPROM. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table eeprom_dir_table_template[] = {
- { EEPROM_SYSCTL1, "data0-15", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL2, "data16-31", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL3, "data32-47", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL4, "data48-63", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL5, "data64-79", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL6, "data80-95", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL7, "data96-111", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { EEPROM_SYSCTL8, "data112-127", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &eeprom_contents },
- { 0 }
-};
-
-/* Used by init/cleanup */
-static int eeprom_initialized = 0;
-
-/* I choose here for semi-static LM78 allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_EEPROM_NR 8
-static struct i2c_client *eeprom_list[MAX_EEPROM_NR];
-
-
-int eeprom_attach_adapter(struct i2c_adapter *adapter)
-{
- int address,err,i;
- struct i2c_client *new_client;
- struct eeprom_data *data;
-
- err = 0;
-
- /* OK, this is no detection. I know. It will do for now, though. */
-
- /* Set err only if a global error would make registering other clients
- impossible too (like out-of-memory). */
-
- /* Serial EEPROMs for SMBus use addresses from 0x50 to 0x57 */
- for (address = 0x50; (! err) && (address <= 0x57); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if (smbus_read_byte(adapter,address) < 0) {
-#ifdef DEBUG
- printk("eeprom.o: No eeprom found at: 0x%X\n",address);
-#endif
- continue;
- }
-
- /* Real detection code goes here */
-
- /* Allocate space for a new client structure */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct eeprom_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Find a place in our global list */
- for (i = 0; i < MAX_EEPROM_NR; i++)
- if (! eeprom_list[i])
- break;
- if (i == MAX_EEPROM_NR) {
- err = -ENOMEM;
- printk("eeprom.o: No empty slots left, recompile and heighten "
- "MAX_EEPROM_NR!\n");
- goto ERROR1;
- }
- eeprom_list[i] = new_client;
-
- /* Fill the new client structure with data */
- data = (struct eeprom_data *) (new_client + 1);
- new_client->data = data;
- new_client->id = i;
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &eeprom_driver;
- strcpy(new_client->name,"EEPROM chip");
- data->valid = 0;
- data->update_lock = MUTEX;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR2;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,"eeprom",
- eeprom_dir_table_template)) < 0)
- goto ERROR3;
- data->sysctl_id = err;
- err = 0;
-
- continue;
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-
-ERROR3:
- i2c_detach_client(new_client);
-ERROR2:
- eeprom_list[i] = NULL;
-ERROR1:
- kfree(new_client);
- }
- return err;
-}
-
-int eeprom_detach_client(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_EEPROM_NR; i++)
- if (client == eeprom_list[i])
- break;
- if ((i == MAX_EEPROM_NR)) {
- printk("eeprom.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct eeprom_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("eeprom.o: Client deregistration failed, client not detached.\n");
- return err;
- }
-
- eeprom_list[i] = NULL;
- kfree(client);
- return 0;
-}
-
-
-/* No commands defined yet */
-int eeprom_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-void eeprom_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-void eeprom_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-u16 swap_bytes(u16 val)
-{
- return (val >> 8) | (val << 8);
-}
-
-/* No swapping needed here! */
-int eeprom_write_value(struct i2c_client *client, u8 reg, u16 value)
-{/*
- if (reg == EEPROM_REG_CONF)
- return smbus_write_byte_data(client->adapter,client->addr,reg,value);
- else
- return smbus_write_word_data(client->adapter,client->addr,reg,value); */
-
- /* No writes yet (PAE) */
- return 0;
-}
-
-void eeprom_update_client(struct i2c_client *client)
-{
- struct eeprom_data *data = client->data;
- int i;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting eeprom update\n");
-#endif
-
- if (smbus_write_byte(client->adapter,client->addr,0)) {
-#ifdef DEBUG
- printk("eeprom read start has failed!\n");
-#endif
- }
- for (i=0;i<EEPROM_SIZE;i++) {
- data->data[i] = (u8)smbus_read_byte(client->adapter,client->addr);
- }
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-void eeprom_contents(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- int i;
- int base=0;
- struct eeprom_data *data = client->data;
-
- if (ctl_name == EEPROM_SYSCTL2){ base=16; }
- if (ctl_name == EEPROM_SYSCTL3){ base=32; }
- if (ctl_name == EEPROM_SYSCTL4){ base=48; }
- if (ctl_name == EEPROM_SYSCTL5){ base=64; }
- if (ctl_name == EEPROM_SYSCTL6){ base=80; }
- if (ctl_name == EEPROM_SYSCTL7){ base=96; }
- if (ctl_name == EEPROM_SYSCTL8){ base=112; }
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- eeprom_update_client(client);
- for (i=0; i<16; i++) {
- results[i]=data->data[i + base];
- }
-#ifdef DEBUG
- printk("eeprom.o: 0x%X EEPROM Contents (base %d): ",client->addr,base);
- for (i=0; i<16; i++) {
- printk(" 0x%X",data->data[i + base]);
- }
- printk(" .\n");
-#endif
- *nrels_mag = 16;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
-
-/* No writes to the EEPROM (yet, anyway) (PAE) */
- printk("eeprom.o: No writes to EEPROMs supported!\n");
- }
-}
-
-int eeprom_init(void)
-{
- int res;
-
- printk("eeprom.o version %s (%s)\n",LM_VERSION,LM_DATE);
- eeprom_initialized = 0;
- if ((res = i2c_add_driver(&eeprom_driver))) {
- printk("eeprom.o: Driver registration failed, module not inserted.\n");
- eeprom_cleanup();
- return res;
- }
- eeprom_initialized ++;
- return 0;
-}
-
-int eeprom_cleanup(void)
-{
- int res;
-
- if (eeprom_initialized >= 1) {
- if ((res = i2c_del_driver(&eeprom_driver))) {
- printk("eeprom.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- } else
- eeprom_initialized --;
-
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("EEPROM driver");
-
-int init_module(void)
-{
- return eeprom_init();
-}
-
-int cleanup_module(void)
-{
- return eeprom_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/gl518sm.c b/kernel/chips/gl518sm.c
deleted file mode 100644
index 353b3228..00000000
--- a/kernel/chips/gl518sm.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- gl518sm.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include "smbus.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "version.h"
-
-
-/* Many GL518 constants specified below */
-
-/* The GL518 registers */
-#define GL518_REG_CHIP_ID 0x00
-#define GL518_REG_REVISION 0x01
-#define GL518_REG_VENDOR_ID 0x02
-#define GL518_REG_CONF 0x03
-#define GL518_REG_TEMP 0x04
-#define GL518_REG_TEMP_OVER 0x05
-#define GL518_REG_TEMP_HYST 0x06
-#define GL518_REG_FAN_COUNT 0x07
-#define GL518_REG_FAN_LIMIT 0x08
-#define GL518_REG_VIN1_LIMIT 0x09
-#define GL518_REG_VIN2_LIMIT 0x0a
-#define GL518_REG_VIN3_LIMIT 0x0b
-#define GL518_REG_VDD_LIMIT 0x0c
-#define GL518_REG_VIN3 0x0d
-#define GL518_REG_MISC 0x0f
-#define GL518_REG_ALARM 0x10
-#define GL518_REG_MASK 0x11
-#define GL518_REG_INT 0x12
-#define GL518_REG_VIN2 0x13
-#define GL518_REG_VIN1 0x14
-#define GL518_REG_VDD 0x15
-
-
-/* Conversions. Rounding is only done on the TO_REG variants. */
-#define TEMP_TO_REG(val) (((((val)<0?(val)-5:(val)+5) / 10) + 119) & 0xff)
-#define TEMP_FROM_REG(val) (((val) - 119) * 10)
-
-#define FAN_TO_REG(val,div) (((val)==0?255:\
- (960000+((val)*(div)))/(2*(val)*(div))) & 0xff)
-#define FAN_FROM_REG(val,div) ((val)==0?0:(val)==255?0:960000/(2*(val)*(div)))
-
-#define IN_TO_REG(val) ((((val)*10+8)/19) & 0xff)
-#define IN_FROM_REG(val) (((val)*19)/10)
-
-#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
-#define DIV_FROM_REG(val) (1 << (val))
-
-#define ALARMS_FROM_REG(val) val
-
-#define BEEP_ENABLE_TO_REG(val) ((val)?0:1)
-#define BEEP_ENABLE_FROM_REG(val) ((val)?0:1)
-
-#define BEEPS_TO_REG(val) ((val) & 0x7f)
-#define BEEPS_FROM_REG(val) (val)
-
-/* Initial values */
-#define GL518_INIT_TEMP_OVER 600
-#define GL518_INIT_TEMP_HYST 500
-#define GL518_INIT_FAN_MIN_1 3000
-#define GL518_INIT_FAN_MIN_2 3000
-
-/* What are sane values for these?!? */
-#define GL518_INIT_VIN_1 300
-#define GL518_INIT_VIN_2 300
-#define GL518_INIT_VIN_3 300
-#define GL518_INIT_VDD 300
-
-#define GL518_INIT_PERCENTAGE 10
-
-#define GL518_INIT_VIN_MIN_1 \
- (GL518_INIT_VIN_1 - GL518_INIT_VIN_1 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VIN_MAX_1 \
- (GL518_INIT_VIN_1 + GL518_INIT_VIN_1 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VIN_MIN_2 \
- (GL518_INIT_VIN_2 - GL518_INIT_VIN_2 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VIN_MAX_2 \
- (GL518_INIT_VIN_2 + GL518_INIT_VIN_2 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VIN_MIN_3 \
- (GL518_INIT_VIN_3 - GL518_INIT_VIN_3 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VIN_MAX_3 \
- (GL518_INIT_VIN_3 + GL518_INIT_VIN_3 * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VDD_MIN \
- (GL518_INIT_VDD - GL518_INIT_VDD * GL518_INIT_PERCENTAGE / 100)
-#define GL518_INIT_VDD_MAX \
- (GL518_INIT_VDD + GL518_INIT_VDD * GL518_INIT_PERCENTAGE / 100)
-
-
-/* Each client has this additional data */
-struct gl518_data {
- int sysctl_id;
-
- u8 revision;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u8 voltage[4]; /* Register values; [0] = VDD */
- u8 voltage_min[4]; /* Register values; [0] = VDD */
- u8 voltage_max[4]; /* Register values; [0] = VDD */
- u8 fan[2];
- u8 fan_min[2];
- u8 temp; /* Register values */
- u8 temp_over; /* Register values */
- u8 temp_hyst; /* Register values */
- u8 alarms,beeps; /* Register value */
- u8 fan_div[2]; /* Register encoding, shifted right */
- u8 beep_enable; /* Boolean */
-};
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-static int gl518_init(void);
-static int gl518_cleanup(void);
-static int gl518_attach_adapter(struct i2c_adapter *adapter);
-static int gl518_detach_client(struct i2c_client *client);
-static int gl518_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void gl518_inc_use (struct i2c_client *client);
-static void gl518_dec_use (struct i2c_client *client);
-static u16 swap_bytes(u16 val);
-static int gl518_read_value(struct i2c_client *client, u8 reg);
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
-static void gl518_update_client(struct i2c_client *client);
-
-static void gl518_vin(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void gl518_fan(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void gl518_temp(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void gl518_fan_div(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void gl518_alarms(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void gl518_beep(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver gl518_driver = {
- /* name */ "GL518SM sensor chip driver",
- /* id */ I2C_DRIVERID_GL518,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &gl518_attach_adapter,
- /* detach_client */ &gl518_detach_client,
- /* command */ &gl518_command,
- /* inc_use */ &gl518_inc_use,
- /* dec_use */ &gl518_dec_use
-};
-
-/* These files are created for each detected GL518. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table gl518_dir_table_template[] = {
- { GL518_SYSCTL_VIN1, "vin1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_vin },
- { GL518_SYSCTL_VIN2, "vin2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_vin },
- { GL518_SYSCTL_VIN3, "vin3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_vin },
- { GL518_SYSCTL_VDD, "vdd", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_vin },
- { GL518_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_fan },
- { GL518_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_fan },
- { GL518_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_temp },
- { GL518_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_fan_div },
- { GL518_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_alarms },
- { GL518_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &gl518_beep },
- { 0 }
-};
-
-/* Used by init/cleanup */
-static int gl518_initialized = 0;
-
-/* I choose here for semi-static LM78 allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_GL518_NR 4
-static struct i2c_client *gl518_list[MAX_GL518_NR];
-
-
-int gl518_attach_adapter(struct i2c_adapter *adapter)
-{
- int address,err,i;
- struct i2c_client *new_client;
- struct gl518_data *data;
- u8 revision;
- char name[11];
-
- err = 0;
-
- /* OK, this is no detection. I know. It will do for now, though. */
-
- /* Set err only if a global error would make registering other clients
- impossible too (like out-of-memory). */
- for (address = 0x2c; (! err) && (address <= 0x2d); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if ((i = smbus_read_byte_data(adapter,address,GL518_REG_CHIP_ID)) < 0)
- continue;
-
- if (i != 0x80)
- continue;
-
- revision = smbus_read_byte_data(adapter,address,GL518_REG_REVISION);
- if ((revision != 0x00) && (revision != 0x80))
- continue;
-
- /* Real detection code goes here */
-
- /* Allocate space for a new client structure */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct gl518_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Find a place in our global list */
- for (i = 0; i < MAX_GL518_NR; i++)
- if (! gl518_list[i])
- break;
- if (i == MAX_GL518_NR) {
- err = -ENOMEM;
- printk("gl518sm.o: No empty slots left, recompile and heighten "
- "MAX_GL518_NR!\n");
- goto ERROR1;
- }
- gl518_list[i] = new_client;
-
- /* Fill the new client structure with data */
- data = (struct gl518_data *) (new_client + 1);
- new_client->data = data;
- new_client->id = i;
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &gl518_driver;
- sprintf(new_client->name,"GL518SM chip rev. %02x",revision);
- data->valid = 0;
- data->update_lock = MUTEX;
- data->revision = revision;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR2;
-
- sprintf(name,"gl518sm-r%02x",revision);
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,name,
- gl518_dir_table_template)) < 0)
- goto ERROR3;
- data->sysctl_id = err;
- err = 0;
-
- /* Initialize the GL518SM chip */
- /* Power-on defaults (bit 7=1) */
- gl518_write_value(new_client,GL518_REG_CONF,0x80);
- /* No noisy output (bit 2=1), Comparator mode (bit 3=0), two fans (bit4=0),
- standby mode (bit6=0) */
- gl518_write_value(new_client,GL518_REG_CONF,0x04);
- /* Never interrupts */
- gl518_write_value(new_client,GL518_REG_MASK,0x00);
- gl518_write_value(new_client,GL518_REG_TEMP_HYST,
- TEMP_TO_REG(GL518_INIT_TEMP_HYST));
- gl518_write_value(new_client,GL518_REG_TEMP_OVER,
- TEMP_TO_REG(GL518_INIT_TEMP_OVER));
- gl518_write_value(new_client,GL518_REG_MISC,(DIV_TO_REG(2) << 6) |
- (DIV_TO_REG(2) << 4) | 0x08);
- gl518_write_value(new_client,GL518_REG_FAN_LIMIT,
- (FAN_TO_REG(GL518_INIT_FAN_MIN_1,2) << 8) |
- FAN_TO_REG(GL518_INIT_FAN_MIN_2,2));
- gl518_write_value(new_client,GL518_REG_VIN1_LIMIT,
- (IN_TO_REG(GL518_INIT_VIN_MAX_1) << 8) |
- IN_TO_REG(GL518_INIT_VIN_MIN_1));
- gl518_write_value(new_client,GL518_REG_VIN2_LIMIT,
- (IN_TO_REG(GL518_INIT_VIN_MAX_2) << 8) |
- IN_TO_REG(GL518_INIT_VIN_MIN_2));
- gl518_write_value(new_client,GL518_REG_VIN3_LIMIT,
- (IN_TO_REG(GL518_INIT_VIN_MAX_3) << 8) |
- IN_TO_REG(GL518_INIT_VIN_MIN_3));
- gl518_write_value(new_client,GL518_REG_VDD_LIMIT,
- (IN_TO_REG(GL518_INIT_VDD_MAX) << 8) |
- IN_TO_REG(GL518_INIT_VDD_MIN));
- /* Clear status register (bit 5=1), start (bit6=1) */
- gl518_write_value(new_client,GL518_REG_CONF,0x24);
- gl518_write_value(new_client,GL518_REG_CONF,0x44);
-
- continue;
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-
-ERROR3:
- i2c_detach_client(new_client);
-ERROR2:
- gl518_list[i] = NULL;
-ERROR1:
- kfree(new_client);
- }
- return err;
-}
-
-int gl518_detach_client(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_GL518_NR; i++)
- if (client == gl518_list[i])
- break;
- if ((i == MAX_GL518_NR)) {
- printk("gl518sm.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct gl518_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("gl518sm.o: Client deregistration failed, client not detached.\n");
- return err;
- }
-
- gl518_list[i] = NULL;
- kfree(client);
- return 0;
-}
-
-
-/* No commands defined yet */
-int gl518_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-/* Nothing here yet */
-void gl518_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-/* Nothing here yet */
-void gl518_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-u16 swap_bytes(u16 val)
-{
- return (val >> 8) | (val << 8);
-}
-
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized
- GL518 uses a high-byte first convention, which is exactly opposite to
- the usual practice. */
-int gl518_read_value(struct i2c_client *client, u8 reg)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg));
- else
- return smbus_read_byte_data(client->adapter,client->addr,reg);
-}
-
-/* Registers 0x07 to 0x0c are word-sized, others are byte-sized
- GL518 uses a high-byte first convention, which is exactly opposite to
- the usual practice. */
-int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
- if ((reg >= 0x07) && (reg <= 0x0c))
- return smbus_write_word_data(client->adapter,client->addr,reg,
- swap_bytes(value));
- else
- return smbus_write_byte_data(client->adapter,client->addr,reg,value);
-}
-
-void gl518_update_client(struct i2c_client *client)
-{
- struct gl518_data *data = client->data;
- int val;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting gl518 update\n");
-#endif
-
- if (data->revision != 0x00) {
- data->voltage[0] = gl518_read_value(client,GL518_REG_VDD);
- data->voltage[1] = gl518_read_value(client,GL518_REG_VIN1);
- data->voltage[2] = gl518_read_value(client,GL518_REG_VIN2);
- }
- data->voltage[3] = gl518_read_value(client,GL518_REG_VIN3);
-
- val = gl518_read_value(client,GL518_REG_VDD_LIMIT);
- data->voltage_min[0] = val & 0xff;
- data->voltage_max[0] = (val >> 8) & 0xff;
- val = gl518_read_value(client,GL518_REG_VIN1_LIMIT);
- data->voltage_min[1] = val & 0xff;
- data->voltage_max[1] = (val >> 8) & 0xff;
- val = gl518_read_value(client,GL518_REG_VIN2_LIMIT);
- data->voltage_min[2] = val & 0xff;
- data->voltage_max[2] = (val >> 8) & 0xff;
- val = gl518_read_value(client,GL518_REG_VIN3_LIMIT);
- data->voltage_min[3] = val & 0xff;
- data->voltage_max[3] = (val >> 8) & 0xff;
-
- val = gl518_read_value(client,GL518_REG_FAN_COUNT);
- data->fan[0] = (val >> 8) & 0xff;
- data->fan[1] = val & 0xff;
-
- val = gl518_read_value(client,GL518_REG_FAN_LIMIT);
- data->fan_min[0] = (val >> 8) & 0xff;
- data->fan_min[1] = val & 0xff;
-
- data->temp = gl518_read_value(client,GL518_REG_TEMP);
- data->temp_over = gl518_read_value(client,GL518_REG_TEMP_OVER);
- data->temp_hyst = gl518_read_value(client,GL518_REG_TEMP_HYST);
-
- data->alarms = gl518_read_value(client,GL518_REG_INT);
- data->beeps = gl518_read_value(client,GL518_REG_ALARM);
-
- val = gl518_read_value(client,GL518_REG_MISC);
- data->fan_div[0] = (val >> 4) & 0x03;
- data->fan_div[1] = (val >> 6) & 0x03;
- data->beep_enable = (gl518_read_value(client,GL518_REG_CONF) >> 2) & 1;
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-void gl518_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = TEMP_FROM_REG(data->temp_over);
- results[1] = TEMP_FROM_REG(data->temp_hyst);
- results[2] = TEMP_FROM_REG(data->temp);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_over = TEMP_TO_REG(results[0]);
- gl518_write_value(client,GL518_REG_TEMP_OVER,data->temp_over);
- }
- if (*nrels_mag >= 2) {
- data->temp_over = TEMP_TO_REG(results[1]);
- gl518_write_value(client,GL518_REG_TEMP_HYST,data->temp_over);
- }
- }
-}
-
-void gl518_vin(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- int nr = ctl_name - GL518_SYSCTL_VDD;
- int regnr,old=0;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = IN_FROM_REG(data->voltage_min[nr]);
- results[1] = IN_FROM_REG(data->voltage_max[nr]);
- if ((data->revision == 0x00) && (nr != 3))
- results[2] = 0;
- else
- results[2] = IN_FROM_REG(data->voltage[nr]);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- regnr=nr==0?GL518_REG_VDD_LIMIT:nr==1?GL518_REG_VIN1_LIMIT:nr==2?
- GL518_REG_VIN2_LIMIT:GL518_REG_VIN3_LIMIT;
- if (*nrels_mag == 1)
- old = gl518_read_value(client,regnr) & 0xff00;
- if (*nrels_mag >= 2) {
- data->voltage_max[nr] = IN_TO_REG(results[1]);
- old = data->voltage_max[nr] << 8;
- }
- if (*nrels_mag >= 1) {
- data->voltage_min[nr] = IN_TO_REG(results[0]);
- old |= data->voltage_min[nr];
- gl518_write_value(client,regnr,old);
- }
- }
-}
-
-
-void gl518_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- int nr = ctl_name - GL518_SYSCTL_FAN1;
- int old;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = FAN_FROM_REG(data->fan_min[nr],
- DIV_FROM_REG(data->fan_div[nr]));
- results[1] = FAN_FROM_REG(data->fan[nr],DIV_FROM_REG(data->fan_div[nr]));
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->fan_min[nr] = FAN_TO_REG(results[0],
- DIV_FROM_REG(data->fan_div[nr]));
- old = gl518_read_value(client,GL518_REG_FAN_LIMIT);
- if (nr == 0)
- old = (old & 0x00ff) | (data->fan_min[nr] << 8);
- else
- old = (old & 0xff00) | data->fan_min[nr];
- gl518_write_value(client,GL518_REG_FAN_LIMIT,old);
- }
- }
-}
-
-
-void gl518_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = ALARMS_FROM_REG(data->alarms);
- *nrels_mag = 1;
- }
-}
-
-void gl518_beep(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable);
- results[1] = BEEPS_FROM_REG(data->beeps);
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->beep_enable = BEEP_ENABLE_TO_REG(results[0]);
- gl518_write_value(client,GL518_REG_CONF,
- (gl518_read_value(client,GL518_REG_CONF) & 0xfb) |
- (data->beep_enable << 2));
- }
- if (*nrels_mag >= 2) {
- data->beeps = BEEPS_TO_REG(results[1]);
- gl518_write_value(client,GL518_REG_ALARM,data->beeps);
- }
- }
-}
-
-void gl518_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct gl518_data *data = client->data;
- int old;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- gl518_update_client(client);
- results[0] = DIV_FROM_REG(data->fan_div[0]);
- results[1] = DIV_FROM_REG(data->fan_div[1]);
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- old = gl518_read_value(client,GL518_REG_MISC);
- if (*nrels_mag >= 2) {
- data->fan_div[1] = DIV_TO_REG(results[1]);
- old = (old & 0x3f) | (data->fan_div[1] << 6);
- }
- if (*nrels_mag >= 1) {
- data->fan_div[0] = DIV_TO_REG(results[0]);
- old = (old & 0xcf) | (data->fan_div[0] << 4);
- gl518_write_value(client,GL518_REG_MISC,old);
- }
- }
-}
-
-
-int gl518_init(void)
-{
- int res;
-
- printk("gl518sm.o version %s (%s)\n",LM_VERSION,LM_DATE);
- gl518_initialized = 0;
- if ((res = i2c_add_driver(&gl518_driver))) {
- printk("gl518sm.o: Driver registration failed, module not inserted.\n");
- gl518_cleanup();
- return res;
- }
- gl518_initialized ++;
- return 0;
-}
-
-int gl518_cleanup(void)
-{
- int res;
-
- if (gl518_initialized >= 1) {
- if ((res = i2c_del_driver(&gl518_driver))) {
- printk("gl518.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- gl518_initialized --;
- }
-
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("GL518SM driver");
-
-int init_module(void)
-{
- return gl518_init();
-}
-
-int cleanup_module(void)
-{
- return gl518_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/lm75.c b/kernel/chips/lm75.c
deleted file mode 100644
index 4ab9f4de..00000000
--- a/kernel/chips/lm75.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- lm75.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include "smbus.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "version.h"
-
-/* Many LM75 constants specified below */
-
-/* The LM75 registers */
-#define LM75_REG_TEMP 0x00
-#define LM75_REG_CONF 0x01
-#define LM75_REG_TEMP_HYST 0x02
-#define LM75_REG_TEMP_OS 0x03
-
-/* Conversions */
-#define TEMP_FROM_REG(val) (((val) >> 7) * 5)
-#define TEMP_TO_REG(val) (((((val) + 2) / 5) << 7) & 0xff80)
-
-/* Initial values */
-#define LM75_INIT_TEMP_OS 600
-#define LM75_INIT_TEMP_HYST 500
-
-/* Each client has this additional data */
-struct lm75_data {
- int sysctl_id;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u16 temp,temp_os,temp_hyst; /* Register values */
-};
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-static int lm75_init(void);
-static int lm75_cleanup(void);
-static int lm75_attach_adapter(struct i2c_adapter *adapter);
-static int lm75_detach_client(struct i2c_client *client);
-static int lm75_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void lm75_inc_use (struct i2c_client *client);
-static void lm75_dec_use (struct i2c_client *client);
-static u16 swap_bytes(u16 val);
-static int lm75_read_value(struct i2c_client *client, u8 reg);
-static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value);
-static void lm75_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm75_update_client(struct i2c_client *client);
-
-
-/* This is the driver that will be inserted */
-static struct i2c_driver lm75_driver = {
- /* name */ "LM75 sensor chip driver",
- /* id */ I2C_DRIVERID_LM75,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &lm75_attach_adapter,
- /* detach_client */ &lm75_detach_client,
- /* command */ &lm75_command,
- /* inc_use */ &lm75_inc_use,
- /* dec_use */ &lm75_dec_use
-};
-
-/* These files are created for each detected LM75. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table lm75_dir_table_template[] = {
- { LM75_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm75_temp },
- { 0 }
-};
-
-/* Used by init/cleanup */
-static int lm75_initialized = 0;
-
-/* I choose here for semi-static LM78 allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_LM75_NR 8
-static struct i2c_client *lm75_list[MAX_LM75_NR];
-
-
-int lm75_attach_adapter(struct i2c_adapter *adapter)
-{
- int address,err,i;
- struct i2c_client *new_client;
- struct lm75_data *data;
-
- err = 0;
-
- /* OK, this is no detection. I know. It will do for now, though. */
-
- /* Set err only if a global error would make registering other clients
- impossible too (like out-of-memory). */
- for (address = 0x48; (! err) && (address <= 0x4f); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if (smbus_read_byte_data(adapter,address,LM75_REG_CONF) < 0)
- continue;
-
- /* Real detection code goes here */
-
- /* Allocate space for a new client structure */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct lm75_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Find a place in our global list */
- for (i = 0; i < MAX_LM75_NR; i++)
- if (! lm75_list[i])
- break;
- if (i == MAX_LM75_NR) {
- err = -ENOMEM;
- printk("lm75.o: No empty slots left, recompile and heighten "
- "MAX_LM75_NR!\n");
- goto ERROR1;
- }
- lm75_list[i] = new_client;
-
- /* Fill the new client structure with data */
- data = (struct lm75_data *) (new_client + 1);
- new_client->data = data;
- new_client->id = i;
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &lm75_driver;
- strcpy(new_client->name,"LM75 chip");
- data->valid = 0;
- data->update_lock = MUTEX;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR2;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,"lm75",
- lm75_dir_table_template)) < 0)
- goto ERROR3;
- data->sysctl_id = err;
- err = 0;
-
- /* Initialize the LM75 chip */
- lm75_write_value(new_client,LM75_REG_TEMP_OS,
- TEMP_TO_REG(LM75_INIT_TEMP_OS));
- lm75_write_value(new_client,LM75_REG_TEMP_HYST,
- TEMP_TO_REG(LM75_INIT_TEMP_HYST));
- lm75_write_value(new_client,LM75_REG_CONF,0);
-
- continue;
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-
-ERROR3:
- i2c_detach_client(new_client);
-ERROR2:
- lm75_list[i] = NULL;
-ERROR1:
- kfree(new_client);
- }
- return err;
-}
-
-int lm75_detach_client(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_LM75_NR; i++)
- if (client == lm75_list[i])
- break;
- if ((i == MAX_LM75_NR)) {
- printk("lm75.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct lm75_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("lm75.o: Client deregistration failed, client not detached.\n");
- return err;
- }
-
- lm75_list[i] = NULL;
- kfree(client);
- return 0;
-}
-
-
-/* No commands defined yet */
-int lm75_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-/* Nothing here yet */
-void lm75_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-/* Nothing here yet */
-void lm75_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-u16 swap_bytes(u16 val)
-{
- return (val >> 8) | (val << 8);
-}
-
-/* All registers are word-sized, except for the configuration register.
- LM75 uses a high-byte first convention, which is exactly opposite to
- the usual practice. */
-int lm75_read_value(struct i2c_client *client, u8 reg)
-{
- if (reg == LM75_REG_CONF)
- return smbus_read_byte_data(client->adapter,client->addr,reg);
- else
- return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg));
-}
-
-/* All registers are word-sized, except for the configuration register.
- LM75 uses a high-byte first convention, which is exactly opposite to
- the usual practice. */
-int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
- if (reg == LM75_REG_CONF)
- return smbus_write_byte_data(client->adapter,client->addr,reg,value);
- else
- return smbus_write_word_data(client->adapter,client->addr,reg,
- swap_bytes(value));
-}
-
-void lm75_update_client(struct i2c_client *client)
-{
- struct lm75_data *data = client->data;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting lm75 update\n");
-#endif
-
- data->temp = lm75_read_value(client,LM75_REG_TEMP);
- data->temp_os = lm75_read_value(client,LM75_REG_TEMP_OS);
- data->temp_hyst = lm75_read_value(client,LM75_REG_TEMP_HYST);
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-void lm75_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm75_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm75_update_client(client);
- results[0] = TEMP_FROM_REG(data->temp_os);
- results[1] = TEMP_FROM_REG(data->temp_hyst);
- results[2] = TEMP_FROM_REG(data->temp);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_os = TEMP_TO_REG(results[0]);
- lm75_write_value(client,LM75_REG_TEMP_OS,data->temp_os);
- }
- if (*nrels_mag >= 2) {
- data->temp_os = TEMP_TO_REG(results[1]);
- lm75_write_value(client,LM75_REG_TEMP_HYST,data->temp_os);
- }
- }
-}
-
-int lm75_init(void)
-{
- int res;
-
- printk("lm75.o version %s (%s)\n",LM_VERSION,LM_DATE);
- lm75_initialized = 0;
- if ((res = i2c_add_driver(&lm75_driver))) {
- printk("lm75.o: Driver registration failed, module not inserted.\n");
- lm75_cleanup();
- return res;
- }
- lm75_initialized ++;
- return 0;
-}
-
-int lm75_cleanup(void)
-{
- int res;
-
- if (lm75_initialized >= 1) {
- if ((res = i2c_del_driver(&lm75_driver))) {
- printk("lm75.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- lm75_initialized --;
- }
-
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("LM75 driver");
-
-int init_module(void)
-{
- return lm75_init();
-}
-
-int cleanup_module(void)
-{
- return lm75_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/lm78.c b/kernel/chips/lm78.c
deleted file mode 100644
index f8a56de4..00000000
--- a/kernel/chips/lm78.c
+++ /dev/null
@@ -1,926 +0,0 @@
-/*
- lm78.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <linux/types.h>
-#include "smbus.h"
-#include "version.h"
-#include "isa.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "compat.h"
-
-/* Many LM78 constants specified below */
-
-/* Length of ISA address segment */
-#define LM78_EXTENT 8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define LM78_ADDR_REG_OFFSET 5
-#define LM78_DATA_REG_OFFSET 6
-
-/* The LM78 registers */
-#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
-#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
-#define LM78_REG_IN(nr) (0x20 + (nr))
-
-#define LM78_REG_FAN_MIN(nr) (0x3a + (nr))
-#define LM78_REG_FAN(nr) (0x27 + (nr))
-
-#define LM78_REG_TEMP 0x27
-#define LM78_REG_TEMP_OVER 0x39
-#define LM78_REG_TEMP_HYST 0x3a
-
-#define LM78_REG_ALARM1 0x41
-#define LM78_REG_ALARM2 0x42
-
-#define LM78_REG_VID_FANDIV 0x47
-
-#define LM78_REG_CONFIG 0x40
-#define LM78_REG_CHIPID 0x49
-
-
-/* Conversions. Rounding is only done on the TO_REG variants. */
-#define IN_TO_REG(val) (((val) * 10 + 8)/16)
-#define IN_FROM_REG(val) (((val) * 16) / 10)
-
-#define FAN_TO_REG(val,div) ((val)==0?255:((1350000+(val)*(div)/2)/\
- ((val)*(div))) & 0xff)
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*(div)))
-
-#define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff)
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
-
-#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
- (val)>=0x06?0:205-(val)*5)
-#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)
-
-/* Initial limits. To keep them sane, we use the 'standard' translation as
- specified in the LM78 sheet. Use the config file to set better limits. */
-#define LM78_INIT_IN_0 (vid==350?280:vid)
-#define LM78_INIT_IN_1 (vid==350?280:vid)
-#define LM78_INIT_IN_2 330
-#define LM78_INIT_IN_3 (((500) * 100)/168)
-#define LM78_INIT_IN_4 (((1200) * 10)/38)
-#define LM78_INIT_IN_5 (((-1200) * -604)/2100)
-#define LM78_INIT_IN_6 (((-500) * -604)/909)
-
-#define LM78_INIT_IN_PERCENTAGE 10
-
-#define LM78_INIT_IN_MIN_0 \
- (LM78_INIT_IN_0 - LM78_INIT_IN_0 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_0 \
- (LM78_INIT_IN_0 + LM78_INIT_IN_0 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_1 \
- (LM78_INIT_IN_1 - LM78_INIT_IN_1 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_1 \
- (LM78_INIT_IN_1 + LM78_INIT_IN_1 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_2 \
- (LM78_INIT_IN_2 - LM78_INIT_IN_2 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_2 \
- (LM78_INIT_IN_2 + LM78_INIT_IN_2 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_3 \
- (LM78_INIT_IN_3 - LM78_INIT_IN_3 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_3 \
- (LM78_INIT_IN_3 + LM78_INIT_IN_3 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_4 \
- (LM78_INIT_IN_4 - LM78_INIT_IN_4 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_4 \
- (LM78_INIT_IN_4 + LM78_INIT_IN_4 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_5 \
- (LM78_INIT_IN_5 - LM78_INIT_IN_5 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_5 \
- (LM78_INIT_IN_5 + LM78_INIT_IN_5 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MIN_6 \
- (LM78_INIT_IN_6 - LM78_INIT_IN_6 * LM78_INIT_IN_PERCENTAGE / 100)
-#define LM78_INIT_IN_MAX_6 \
- (LM78_INIT_IN_6 + LM78_INIT_IN_6 * LM78_INIT_IN_PERCENTAGE / 100)
-
-#define LM78_INIT_FAN_MIN_1 3000
-#define LM78_INIT_FAN_MIN_2 3000
-#define LM78_INIT_FAN_MIN_3 3000
-
-#define LM78_INIT_TEMP_OVER 600
-#define LM78_INIT_TEMP_HYST 500
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-/* There are some complications in a module like this. First off, LM78 chips
- may be both present on the SMBus and the ISA bus, and we have to handle
- those cases separately at some places. Second, there might be several
- LM78 chips available (well, actually, that is probably never done; but
- it is a clean illustration of how to handle a case like that). Finally,
- a specific chip may be attached to *both* ISA and SMBus, and we would
- not like to detect it double. Fortunately, in the case of the LM78 at
- least, a register tells us what SMBus address we are on, so that helps
- a bit - except if there could be more than one SMBus. Groan. No solution
- for this yet. */
-
-/* This module may seem overly long and complicated. In fact, it is not so
- bad. Quite a lot of bookkeeping is done. A real driver can often cut
- some corners. */
-
-/* Types of chips supported */
-enum lm78_type { lm78, lm78j, lm79 };
-
-/* For each registered LM78, we need to keep some data in memory. That
- data is pointed to by lm78_list[NR]->data. The structure itself is
- dynamically allocated, at the same time when a new lm78 client is
- allocated. */
-struct lm78_data {
- struct semaphore lock;
- int sysctl_id;
- enum lm78_type type;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u8 in[7]; /* Register value */
- u8 in_max[7]; /* Register value */
- 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 */
- u8 fan_div[3]; /* Register encoding, shifted right */
- u8 vid; /* Register encoding, combined */
- u16 alarms; /* Register encoding, combined */
-};
-
-
-static int lm78_init(void);
-static int lm78_cleanup(void);
-
-static int lm78_attach_adapter(struct i2c_adapter *adapter);
-static int lm78_detect_isa(struct isa_adapter *adapter);
-static int lm78_detect_smbus(struct i2c_adapter *adapter);
-static int lm78_detach_client(struct i2c_client *client);
-static int lm78_detach_isa(struct isa_client *client);
-static int lm78_detach_smbus(struct i2c_client *client);
-static int lm78_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client);
-static void lm78_remove_client(struct i2c_client *client);
-static int lm78_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void lm78_inc_use (struct i2c_client *client);
-static void lm78_dec_use (struct i2c_client *client);
-
-static int lm78_read_value(struct i2c_client *client, u8 register);
-static int lm78_write_value(struct i2c_client *client, u8 register, u8 value);
-static void lm78_update_client(struct i2c_client *client);
-static void lm78_init_client(struct i2c_client *client);
-
-
-static void lm78_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm78_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm78_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm78_vid(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm78_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm78_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-
-/* I choose here for semi-static LM78 allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_LM78_NR 4
-static struct i2c_client *lm78_list[MAX_LM78_NR];
-
-/* The driver. I choose to use type i2c_driver, as at is identical to both
- smbus_driver and isa_driver, and clients could be of either kind */
-static struct i2c_driver lm78_driver = {
- /* name */ "LM78(-J) and LM79 sensor driver",
- /* id */ I2C_DRIVERID_LM78,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &lm78_attach_adapter,
- /* detach_client */ &lm78_detach_client,
- /* command */ &lm78_command,
- /* inc_use */ &lm78_inc_use,
- /* dec_use */ &lm78_dec_use
-};
-
-/* Used by lm78_init/cleanup */
-static int lm78_initialized = 0;
-
-/* The /proc/sys entries */
-/* These files are created for each detected LM78. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table lm78_dir_table_template[] = {
- { LM78_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_in },
- { LM78_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_fan },
- { LM78_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_fan },
- { LM78_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_fan },
- { LM78_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_temp },
- { LM78_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_vid },
- { LM78_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_fan_div },
- { LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm78_alarms },
- { 0 }
-};
-
-
-/* This function is called when:
- * lm78_driver is inserted (when this module is loaded), for each
- available adapter
- * when a new adapter is inserted (and lm78_driver is still present) */
-int lm78_attach_adapter(struct i2c_adapter *adapter)
-{
- if (i2c_is_isa_adapter(adapter))
- return lm78_detect_isa((struct isa_adapter *) adapter);
- else
- return lm78_detect_smbus(adapter);
-}
-
-/* This function is called whenever a client should be removed:
- * lm78_driver is removed (when this module is unloaded)
- * when an adapter is removed which has a lm78 client (and lm78_driver
- is still present). */
-int lm78_detach_client(struct i2c_client *client)
-{
- if (i2c_is_isa_client(client))
- return lm78_detach_isa((struct isa_client *) client);
- else
- return lm78_detach_smbus(client);
-}
-
-/* Detect whether there is a LM78 on the ISA bus, register and initialize
- it. */
-int lm78_detect_isa(struct isa_adapter *adapter)
-{
- int address,err;
- struct isa_client *new_client;
- enum lm78_type type;
- const char *type_name;
- const char *client_name;
-
- /* OK, this is no detection. I know. It will do for now, though. */
-
- err = 0;
- for (address = 0x290; (! err) && (address <= 0x290); address += 0x08) {
- if (check_region(address, LM78_EXTENT))
- continue;
-
- /* Awful, but true: unused port addresses should return 0xff */
- if ((inb_p(address + 1) != 0xff) || (inb_p(address + 2) != 0xff) ||
- (inb_p(address + 3) != 0xff) || (inb_p(address + 7) != 0xff))
- continue;
-
- if (inb_p(address + LM78_ADDR_REG_OFFSET) == 0xff) {
- outb_p(0x00,address + LM78_ADDR_REG_OFFSET);
- if (inb_p(address + LM78_ADDR_REG_OFFSET) == 0xff)
- continue;
- }
-
- /* Real detection code goes here */
-
- /* Determine exact type */
- outb_p(LM78_REG_CHIPID,address + LM78_ADDR_REG_OFFSET);
- err = inb_p(address + LM78_DATA_REG_OFFSET) & 0xfe;
- if (err == 0x00) {
- type = lm78;
- type_name = "lm78";
- client_name = "LM78 chip";
- } else if (err == 0x40) {
- type = lm78j;
- type_name = "lm78-j";
- client_name = "LM78-J chip";
- } else if (err == 0xc0) {
- type = lm79;
- type_name = "lm79";
- client_name = "LM79 chip";
- } else if (err == 0x02) {
- printk("lm78.o: Warning: Winbond W83781D detected (treated as a LM79)\n");
- type = lm79;
- type_name = "lm79";
- client_name = "LM79 chip";
- } else {
-#ifdef DEBUG
- printk("lm78.o: warning: probed non-lm78 chip?!? (%x)\n",err);
-#endif
- continue;
- }
-
- request_region(address, LM78_EXTENT, type_name);
-
- /* Allocate space for a new client structure */
- if (! (new_client = kmalloc(sizeof(struct isa_client) +
- sizeof(struct lm78_data),
- GFP_KERNEL)))
- {
- err=-ENOMEM;
- goto ERROR1;
- }
-
- /* Fill the new client structure with data */
- new_client->data = (struct lm78_data *) (new_client + 1);
- new_client->addr = 0;
- strcpy(new_client->name,client_name);
- ((struct lm78_data *) (new_client->data))->type = type;
- new_client->isa_addr = address;
- if ((err = lm78_new_client((struct i2c_adapter *) adapter,
- (struct i2c_client *) new_client)))
- goto ERROR2;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = isa_attach_client(new_client)))
- goto ERROR3;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry((struct i2c_client *) new_client,
- type_name,
- lm78_dir_table_template)) < 0)
- goto ERROR4;
- ((struct lm78_data *) (new_client->data)) -> sysctl_id = err;
- err = 0;
-
- /* Initialize the LM78 chip */
- lm78_init_client((struct i2c_client *) new_client);
- continue;
-
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-
-ERROR4:
- isa_detach_client(new_client);
-ERROR3:
- lm78_remove_client((struct i2c_client *) new_client);
-ERROR2:
- kfree(new_client);
-ERROR1:
- release_region(address, LM78_EXTENT);
- }
- return err;
-
-}
-
-/* Deregister and remove a LM78 client */
-int lm78_detach_isa(struct isa_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_LM78_NR; i++)
- if ((client == (struct isa_client *) (lm78_list[i])))
- break;
- if (i == MAX_LM78_NR) {
- printk("lm78.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
-
- if ((err = isa_detach_client(client))) {
- printk("lm78.o: Client deregistration failed, client not detached.\n");
- return err;
- }
- lm78_remove_client((struct i2c_client *) client);
- release_region(client->isa_addr,LM78_EXTENT);
- kfree(client);
- return 0;
-}
-
-int lm78_detect_smbus(struct i2c_adapter *adapter)
-{
- int address,err;
- struct i2c_client *new_client;
- enum lm78_type type;
- const char *type_name,*client_name;
-
- /* OK, this is no detection. I know. It will do for now, though. */
- err = 0;
- for (address = 0x20; (! err) && (address <= 0x2f); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if (smbus_read_byte_data(adapter,address,LM78_REG_CONFIG) < 0)
- continue;
-
- /* Real detection code goes here */
-
- /* Determine exact type */
- err = smbus_read_byte_data(adapter,address,LM78_REG_CHIPID) & 0xfe;
- if (err == 0x00) {
- type = lm78;
- type_name = "lm78";
- client_name = "LM78 chip";
- } else if (err == 0x40) {
- type = lm78j;
- type_name = "lm78-j";
- client_name = "LM78-J chip";
- } else if (err == 0xc0) {
- type = lm79;
- type_name = "lm79";
- client_name = "LM79 chip";
- } else if (err == 0x02) {
- printk("lm78.o: Warning: Winbond W83781D detected (treated as a LM79)\n");
- type = lm79;
- type_name = "lm79";
- client_name = "LM79 chip";
- } else {
-#ifdef DEBUG
- printk("lm78.o: warning: probed non-lm78 chip?!? (%x)\n",err);
-#endif
- continue;
- }
-
-
- /* Allocate space for a new client structure. To counter memory
- ragmentation somewhat, we only do one kmalloc. */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct lm78_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Fill the new client structure with data */
- new_client->data = (struct lm78_data *) (new_client + 1);
- new_client->addr = address;
- strcpy(new_client->name,client_name);
- ((struct lm78_data *) (new_client->data))->type = type;
- if ((err = lm78_new_client(adapter,new_client)))
- goto ERROR2;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR3;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,type_name,
- lm78_dir_table_template)) < 0)
- goto ERROR4;
- ((struct lm78_data *) (new_client->data))->sysctl_id = err;
- err = 0;
-
- /* Initialize the LM78 chip */
- lm78_init_client(new_client);
- continue;
-
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-ERROR4:
- i2c_detach_client(new_client);
-ERROR3:
- lm78_remove_client((struct i2c_client *) new_client);
-ERROR2:
- kfree(new_client);
- }
- return err;
-}
-
-int lm78_detach_smbus(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_LM78_NR; i++)
- if (client == lm78_list[i])
- break;
- if ((i == MAX_LM78_NR)) {
- printk("lm78.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("lm78.o: Client deregistration failed, client not detached.\n");
- return err;
- }
- lm78_remove_client(client);
- kfree(client);
- return 0;
-}
-
-
-/* Find a free slot, and initialize most of the fields */
-int lm78_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client)
-{
- int i;
- struct lm78_data *data;
-
- /* First, seek out an empty slot */
- for(i = 0; i < MAX_LM78_NR; i++)
- if (! lm78_list[i])
- break;
- if (i == MAX_LM78_NR) {
- printk("lm78.o: No empty slots left, recompile and heighten "
- "MAX_LM78_NR!\n");
- return -ENOMEM;
- }
-
- lm78_list[i] = new_client;
- new_client->id = i;
- new_client->adapter = adapter;
- new_client->driver = &lm78_driver;
- data = new_client->data;
- data->valid = 0;
- data->lock = MUTEX;
- data->update_lock = MUTEX;
- return 0;
-}
-
-/* Inverse of lm78_new_client */
-void lm78_remove_client(struct i2c_client *client)
-{
- int i;
- for (i = 0; i < MAX_LM78_NR; i++)
- if (client == lm78_list[i])
- lm78_list[i] = NULL;
-}
-
-/* No commands defined yet */
-int lm78_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-/* Nothing here yet */
-void lm78_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-/* Nothing here yet */
-void lm78_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-
-/* The SMBus locks itself, but ISA access must be locked explicitely!
- 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! */
-int lm78_read_value(struct i2c_client *client, u8 reg)
-{
- int res;
- if (i2c_is_isa_client(client)) {
- down((struct semaphore *) (client->data));
- outb_p(reg,(((struct isa_client *) client)->isa_addr) +
- LM78_ADDR_REG_OFFSET);
- res = inb_p((((struct isa_client *) client)->isa_addr) +
- LM78_DATA_REG_OFFSET);
- up((struct semaphore *) (client->data));
- return res;
- } else
- return smbus_read_byte_data(client->adapter,client->addr, reg);
-}
-
-/* The SMBus locks itself, but ISA access muse be locked explicitely!
- 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! */
-int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
- if (i2c_is_isa_client(client)) {
- down((struct semaphore *) (client->data));
- outb_p(reg,((struct isa_client *) client)->isa_addr + LM78_ADDR_REG_OFFSET);
- outb_p(value,((struct isa_client *) client)->isa_addr + LM78_DATA_REG_OFFSET);
- up((struct semaphore *) (client->data));
- return 0;
- } else
- return smbus_write_byte_data(client->adapter, client->addr, reg,value);
-}
-
-/* Called when we have found a new LM78. It should set limits, etc. */
-void lm78_init_client(struct i2c_client *client)
-{
- int vid;
-
- /* Reset all except Watchdog values and last conversion values
- This sets fan-divs to 2, among others */
- lm78_write_value(client,LM78_REG_CONFIG,0x80);
-
- vid = lm78_read_value(client,LM78_REG_VID_FANDIV) & 0x0f;
- if (((struct lm78_data *) (client->data))->type == lm79)
- vid |= (lm78_read_value(client,LM78_REG_CHIPID) & 0x01) >> 4;
- else
- vid |= 0x10;
- vid = VID_FROM_REG(vid);
-
- lm78_write_value(client,LM78_REG_IN_MIN(0),IN_TO_REG(LM78_INIT_IN_MIN_0));
- lm78_write_value(client,LM78_REG_IN_MAX(0),IN_TO_REG(LM78_INIT_IN_MAX_0));
- lm78_write_value(client,LM78_REG_IN_MIN(1),IN_TO_REG(LM78_INIT_IN_MIN_1));
- lm78_write_value(client,LM78_REG_IN_MAX(1),IN_TO_REG(LM78_INIT_IN_MAX_1));
- lm78_write_value(client,LM78_REG_IN_MIN(2),IN_TO_REG(LM78_INIT_IN_MIN_2));
- lm78_write_value(client,LM78_REG_IN_MAX(2),IN_TO_REG(LM78_INIT_IN_MAX_2));
- lm78_write_value(client,LM78_REG_IN_MIN(3),IN_TO_REG(LM78_INIT_IN_MIN_3));
- lm78_write_value(client,LM78_REG_IN_MAX(3),IN_TO_REG(LM78_INIT_IN_MAX_3));
- lm78_write_value(client,LM78_REG_IN_MIN(4),IN_TO_REG(LM78_INIT_IN_MIN_4));
- lm78_write_value(client,LM78_REG_IN_MAX(4),IN_TO_REG(LM78_INIT_IN_MAX_4));
- lm78_write_value(client,LM78_REG_IN_MIN(5),IN_TO_REG(LM78_INIT_IN_MIN_5));
- lm78_write_value(client,LM78_REG_IN_MAX(5),IN_TO_REG(LM78_INIT_IN_MAX_5));
- lm78_write_value(client,LM78_REG_IN_MIN(6),IN_TO_REG(LM78_INIT_IN_MIN_6));
- lm78_write_value(client,LM78_REG_IN_MAX(6),IN_TO_REG(LM78_INIT_IN_MAX_6));
- lm78_write_value(client,LM78_REG_FAN_MIN(1),
- FAN_TO_REG(LM78_INIT_FAN_MIN_1,2));
- lm78_write_value(client,LM78_REG_FAN_MIN(2),
- FAN_TO_REG(LM78_INIT_FAN_MIN_2,2));
- lm78_write_value(client,LM78_REG_FAN_MIN(3),
- FAN_TO_REG(LM78_INIT_FAN_MIN_3,2));
- lm78_write_value(client,LM78_REG_TEMP_OVER,TEMP_TO_REG(LM78_INIT_TEMP_OVER));
- lm78_write_value(client,LM78_REG_TEMP_HYST,TEMP_TO_REG(LM78_INIT_TEMP_HYST));
-
- /* Start monitoring */
- lm78_write_value(client,LM78_REG_CONFIG,
- (lm78_read_value(client,LM78_REG_CONFIG) & 0xf7) | 0x01);
-
-}
-
-void lm78_update_client(struct i2c_client *client)
-{
- struct lm78_data *data = client->data;
- int i;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting lm78 update\n");
-#endif
- for (i = 0; i <= 6; i++) {
- data->in[i] = lm78_read_value(client,LM78_REG_IN(i));
- data->in_min[i] = lm78_read_value(client,LM78_REG_IN_MIN(i));
- data->in_max[i] = lm78_read_value(client,LM78_REG_IN_MAX(i));
- }
- for (i = 1; i <= 3; i++) {
- data->fan[i-1] = lm78_read_value(client,LM78_REG_FAN(i));
- data->fan_min[i-1] = lm78_read_value(client,LM78_REG_FAN_MIN(i));
- }
- data->temp = lm78_read_value(client,LM78_REG_TEMP);
- data->temp_over = lm78_read_value(client,LM78_REG_TEMP_OVER);
- data->temp_hyst = lm78_read_value(client,LM78_REG_TEMP_HYST);
- i = lm78_read_value(client,LM78_REG_VID_FANDIV);
- data->vid = i & 0x0f;
- if (data->type == lm79)
- data->vid |= (lm78_read_value(client,LM78_REG_CHIPID) & 0x01) >> 4;
- else
- data->vid |= 0x10;
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = i >> 6;
- data->alarms = lm78_read_value(client,LM78_REG_ALARM1) +
- (lm78_read_value(client,LM78_REG_ALARM2) << 8);
- data->last_updated = jiffies;
- data->valid = 1;
-
- data->fan_div[2] = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-/* The next few functions are the call-back functions of the /proc/sys and
- sysctl files. Which function is used is defined in the ctl_table in
- the extra1 field.
- Each function must return the magnitude (power of 10 to divide the date
- with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
- put a maximum of *nrels elements in results reflecting the data of this
- file, and set *nrels to the number it actually put in it, if operation==
- SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
- results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
- Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
- large enough (by checking the incoming value of *nrels). This is not very
- good practice, but as long as you put less than about 5 values in results,
- you can assume it is large enough. */
-void lm78_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- int nr = ctl_name - LM78_SYSCTL_IN0;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = IN_FROM_REG(data->in_min[nr]);
- results[1] = IN_FROM_REG(data->in_max[nr]);
- results[2] = IN_FROM_REG(data->in[nr]);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->in_min[nr] = IN_TO_REG(results[0]);
- lm78_write_value(client,LM78_REG_IN_MIN(nr),data->in_min[nr]);
- }
- if (*nrels_mag >= 2) {
- data->in_max[nr] = IN_TO_REG(results[1]);
- lm78_write_value(client,LM78_REG_IN_MAX(nr),data->in_max[nr]);
- }
- }
-}
-
-void lm78_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- int nr = ctl_name - LM78_SYSCTL_FAN1 + 1;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = FAN_FROM_REG(data->fan_min[nr-1],
- DIV_FROM_REG(data->fan_div[nr-1]));
- results[1] = FAN_FROM_REG(data->fan[nr-1],
- DIV_FROM_REG(data->fan_div[nr-1]));
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->fan_min[nr-1] = FAN_TO_REG(results[0],
- DIV_FROM_REG(data->fan_div[nr-1]));
- lm78_write_value(client,LM78_REG_FAN_MIN(nr),data->fan_min[nr-1]);
- }
- }
-}
-
-
-void lm78_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = TEMP_FROM_REG(data->temp_over);
- results[1] = TEMP_FROM_REG(data->temp_hyst);
- results[2] = TEMP_FROM_REG(data->temp);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_over = TEMP_TO_REG(results[0]);
- lm78_write_value(client,LM78_REG_TEMP_OVER,data->temp_over);
- }
- if (*nrels_mag >= 2) {
- data->temp_hyst = TEMP_TO_REG(results[1]);
- lm78_write_value(client,LM78_REG_TEMP_HYST,data->temp_hyst);
- }
- }
-}
-
-void lm78_vid(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = VID_FROM_REG(data->vid);
- *nrels_mag = 1;
- }
-}
-
-void lm78_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = ALARMS_FROM_REG(data->alarms);
- *nrels_mag = 1;
- }
-}
-
-void lm78_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm78_data *data = client->data;
- int old;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm78_update_client(client);
- results[0] = DIV_FROM_REG(data->fan_div[0]);
- results[1] = DIV_FROM_REG(data->fan_div[1]);
- results[2] = 2;
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- old = lm78_read_value(client,LM78_REG_VID_FANDIV);
- if (*nrels_mag >= 2) {
- data->fan_div[1] = DIV_TO_REG(results[1]);
- old = (old & 0x3f) | (data->fan_div[1] << 6);
- }
- if (*nrels_mag >= 1) {
- data->fan_div[0] = DIV_TO_REG(results[0]);
- old = (old & 0xcf) | (data->fan_div[0] << 4);
- lm78_write_value(client,LM78_REG_VID_FANDIV,old);
- }
- }
-}
-
-int lm78_init(void)
-{
- int res;
-
- printk("lm78.o version %s (%s)\n",LM_VERSION,LM_DATE);
- lm78_initialized = 0;
-
- if ((res =i2c_add_driver(&lm78_driver))) {
- printk("lm78.o: Driver registration failed, module not inserted.\n");
- lm78_cleanup();
- return res;
- }
- lm78_initialized ++;
- return 0;
-}
-
-int lm78_cleanup(void)
-{
- int res;
-
- if (lm78_initialized >= 1) {
- if ((res = i2c_del_driver(&lm78_driver))) {
- printk("lm78.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- lm78_initialized --;
- }
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver");
-
-int init_module(void)
-{
- return lm78_init();
-}
-
-int cleanup_module(void)
-{
- return lm78_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/lm80.c b/kernel/chips/lm80.c
deleted file mode 100644
index 72ba020e..00000000
--- a/kernel/chips/lm80.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- lm80.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
- and Philip Edelbrock <phil@netroedge.com>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <linux/types.h>
-#include "smbus.h"
-#include "version.h"
-#include "isa.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "compat.h"
-
-/* Many LM80 constants specified below */
-
-/* The LM80 registers */
-#define LM80_REG_IN_MAX(nr) (0x2a + (nr) * 2)
-#define LM80_REG_IN_MIN(nr) (0x2b + (nr) * 2)
-#define LM80_REG_IN(nr) (0x20 + (nr))
-
-#define LM80_REG_FAN1_MIN 0x3c
-#define LM80_REG_FAN2_MIN 0x3d
-#define LM80_REG_FAN1 0x28
-#define LM80_REG_FAN2 0x29
-
-#define LM80_REG_TEMP 0x27
-#define LM80_REG_TEMP_HOT_MAX 0x38
-#define LM80_REG_TEMP_HOT_HYST 0x39
-#define LM80_REG_TEMP_OS_MAX 0x3a
-#define LM80_REG_TEMP_OS_HYST 0x3b
-
-#define LM80_REG_CONFIG 0x00
-#define LM80_REG_ALARM1 0x01
-#define LM80_REG_ALARM2 0x02
-#define LM80_REG_MASK1 0x03
-#define LM80_REG_MASK2 0x04
-#define LM80_REG_FANDIV 0x05
-#define LM80_REG_RES 0x06
-
-
-/* Conversions. Rounding is only done on the TO_REG variants. */
-#define IN_TO_REG(val,nr) ((val) & 0xff)
-#define IN_FROM_REG(val,nr) (val)
-
-#define FAN_TO_REG(val,div) ((val)==0?255:\
- ((1350000+(val)*(div)/2)/((val)*(div))) & 0xff)
-#define FAN_FROM_REG(val,div) ((val)==0?-1:\
- (val)==255?0:1350000/((div)*(val)))
-
-#define TEMP_FROM_REG(val) lm80_temp_from_reg(val)
-
-#define TEMP_LIMIT_TO_REG(val) (((val)<0?(((val)-50)/100)&0xff:\
- ((val)+50)/100) & 0xff)
-#define TEMP_LIMIT_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*100)
-
-#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)
-
-/* Initial limits */
-#define LM80_INIT_IN_0 190
-#define LM80_INIT_IN_1 190
-#define LM80_INIT_IN_2 190
-#define LM80_INIT_IN_3 190
-#define LM80_INIT_IN_4 190
-#define LM80_INIT_IN_5 190
-#define LM80_INIT_IN_6 190
-
-#define LM80_INIT_IN_PERCENTAGE 10
-
-#define LM80_INIT_IN_MIN_0 \
- (LM80_INIT_IN_0 - LM80_INIT_IN_0 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_0 \
- (LM80_INIT_IN_0 + LM80_INIT_IN_0 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_1 \
- (LM80_INIT_IN_1 - LM80_INIT_IN_1 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_1 \
- (LM80_INIT_IN_1 + LM80_INIT_IN_1 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_2 \
- (LM80_INIT_IN_2 - LM80_INIT_IN_2 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_2 \
- (LM80_INIT_IN_2 + LM80_INIT_IN_2 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_3 \
- (LM80_INIT_IN_3 - LM80_INIT_IN_3 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_3 \
- (LM80_INIT_IN_3 + LM80_INIT_IN_3 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_4 \
- (LM80_INIT_IN_4 - LM80_INIT_IN_4 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_4 \
- (LM80_INIT_IN_4 + LM80_INIT_IN_4 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_5 \
- (LM80_INIT_IN_5 - LM80_INIT_IN_5 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_5 \
- (LM80_INIT_IN_5 + LM80_INIT_IN_5 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MIN_6 \
- (LM80_INIT_IN_6 - LM80_INIT_IN_6 * LM80_INIT_IN_PERCENTAGE / 100)
-#define LM80_INIT_IN_MAX_6 \
- (LM80_INIT_IN_6 + LM80_INIT_IN_6 * LM80_INIT_IN_PERCENTAGE / 100)
-
-#define LM80_INIT_FAN_MIN_1 3000
-#define LM80_INIT_FAN_MIN_2 3000
-
-#define LM80_INIT_TEMP_OS_MAX 600
-#define LM80_INIT_TEMP_OS_HYST 500
-#define LM80_INIT_TEMP_HOT_MAX 700
-#define LM80_INIT_TEMP_HOT_HYST 600
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-/* For each registered LM80, we need to keep some data in memory. That
- data is pointed to by lm80_list[NR]->data. The structure itself is
- dynamically allocated, at the same time when a new lm80 client is
- allocated. */
-struct lm80_data {
- int sysctl_id;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u8 in[7]; /* Register value */
- u8 in_max[7]; /* Register value */
- u8 in_min[7]; /* Register value */
- u8 fan[2]; /* Register value */
- u8 fan_min[2]; /* Register value */
- u8 fan_div[2]; /* Register encoding, shifted right */
- u16 temp; /* Register values, shifted right */
- u8 temp_hot_max; /* Register value */
- u8 temp_hot_hyst; /* Register value */
- u8 temp_os_max; /* Register value */
- u8 temp_os_hyst; /* Register value */
- u16 alarms; /* Register encoding, combined */
-};
-
-
-static int lm80_init(void);
-static int lm80_cleanup(void);
-
-static int lm80_attach_adapter(struct i2c_adapter *adapter);
-static int lm80_detach_client(struct i2c_client *client);
-static int lm80_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client);
-static void lm80_remove_client(struct i2c_client *client);
-static int lm80_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void lm80_inc_use (struct i2c_client *client);
-static void lm80_dec_use (struct i2c_client *client);
-
-static long lm80_temp_from_reg(u16 regs);
-
-static int lm80_read_value(struct i2c_client *client, u8 register);
-static int lm80_write_value(struct i2c_client *client, u8 register, u8 value);
-static void lm80_update_client(struct i2c_client *client);
-static void lm80_init_client(struct i2c_client *client);
-
-
-static void lm80_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm80_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm80_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm80_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void lm80_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-
-/* I choose here for semi-static LM80 allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_LM80_NR 4
-static struct i2c_client *lm80_list[MAX_LM80_NR];
-
-/* The driver. I choose to use type i2c_driver, as at is identical to both
- smbus_driver and isa_driver, and clients could be of either kind */
-static struct i2c_driver lm80_driver = {
- /* name */ "LM80 sensor driver",
- /* id */ I2C_DRIVERID_LM80,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &lm80_attach_adapter,
- /* detach_client */ &lm80_detach_client,
- /* command */ &lm80_command,
- /* inc_use */ &lm80_inc_use,
- /* dec_use */ &lm80_dec_use
-};
-
-/* Used by lm80_init/cleanup */
-static int lm80_initialized = 0;
-
-/* The /proc/sys entries */
-/* These files are created for each detected LM80. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table lm80_dir_table_template[] = {
- { LM80_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_in },
- { LM80_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_fan },
- { LM80_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_fan },
- { LM80_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_temp },
- { LM80_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_fan_div },
- { LM80_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &lm80_alarms },
- { 0 }
-};
-
-
-int lm80_attach_adapter(struct i2c_adapter *adapter)
-{
- int address,err;
- struct i2c_client *new_client;
- const char *type_name,*client_name;
-
- /* OK, this is no detection. I know. It will do for now, though. */
- err = 0;
- for (address = 0x20; (! err) && (address <= 0x2f); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if (smbus_read_byte_data(adapter,address,LM80_REG_CONFIG) < 0)
- continue;
-
- /* Real detection code goes here */
-
- printk("lm80.o: LM80 detected\n");
- type_name = "lm80";
- client_name = "LM80 chip";
-
-
- /* Allocate space for a new client structure. To counter memory
- fragmentation somewhat, we only do one kmalloc. */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct lm80_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Fill the new client structure with data */
- new_client->data = (struct lm80_data *) (new_client + 1);
- new_client->addr = address;
- strcpy(new_client->name,client_name);
- if ((err = lm80_new_client(adapter,new_client)))
- goto ERROR2;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR3;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,type_name,
- lm80_dir_table_template)) < 0)
- goto ERROR4;
- ((struct lm80_data *) (new_client->data))->sysctl_id = err;
- err = 0;
-
- /* Initialize the LM80 chip */
- lm80_init_client(new_client);
- continue;
-
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-ERROR4:
- i2c_detach_client(new_client);
-ERROR3:
- lm80_remove_client((struct i2c_client *) new_client);
-ERROR2:
- kfree(new_client);
- }
- return err;
-}
-
-int lm80_detach_client(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_LM80_NR; i++)
- if (client == lm80_list[i])
- break;
- if ((i == MAX_LM80_NR)) {
- printk("lm80.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct lm80_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("lm80.o: Client deregistration failed, client not detached.\n");
- return err;
- }
- lm80_remove_client(client);
- kfree(client);
- return 0;
-}
-
-
-/* Find a free slot, and initialize most of the fields */
-int lm80_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client)
-{
- int i;
- struct lm80_data *data;
-
- /* First, seek out an empty slot */
- for(i = 0; i < MAX_LM80_NR; i++)
- if (! lm80_list[i])
- break;
- if (i == MAX_LM80_NR) {
- printk("lm80.o: No empty slots left, recompile and heighten "
- "MAX_LM80_NR!\n");
- return -ENOMEM;
- }
-
- lm80_list[i] = new_client;
- new_client->id = i;
- new_client->adapter = adapter;
- new_client->driver = &lm80_driver;
- data = new_client->data;
- data->valid = 0;
- data->update_lock = MUTEX;
- return 0;
-}
-
-/* Inverse of lm80_new_client */
-void lm80_remove_client(struct i2c_client *client)
-{
- int i;
- for (i = 0; i < MAX_LM80_NR; i++)
- if (client == lm80_list[i])
- lm80_list[i] = NULL;
-}
-
-/* No commands defined yet */
-int lm80_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-void lm80_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-void lm80_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-
-long lm80_temp_from_reg(u16 temp)
-{
- long res;
- res = ((temp & 0xff00) >> 8) * 10000 + ((temp & 0x10) >> 4) * 5000 +
- ((temp & 0x20) >> 5) * 2500 + ((temp & 0x40) >> 6) * 1250 +
- ((temp & 0x80) >> 7) * 625;
- temp /= 100;
- if (temp >= 0x80 * 100)
- temp = - (0x100 * 100 - temp);
- return temp;
-}
-
-int lm80_read_value(struct i2c_client *client, u8 reg)
-{
- return smbus_read_byte_data(client->adapter,client->addr, reg);
-}
-
-int lm80_write_value(struct i2c_client *client, u8 reg, u8 value)
-{
- return smbus_write_byte_data(client->adapter, client->addr, reg,value);
-}
-
-/* Called when we have found a new LM80. It should set limits, etc. */
-void lm80_init_client(struct i2c_client *client)
-{
- /* Reset all except Watchdog values and last conversion values
- This sets fan-divs to 2, among others. This makes most other
- initializations unnecessary */
- lm80_write_value(client,LM80_REG_CONFIG,0x80);
- /* Set 11-bit temperature resolution */
- lm80_write_value(client,LM80_REG_RES,0x08);
-
- lm80_write_value(client,LM80_REG_IN_MIN(0),IN_TO_REG(LM80_INIT_IN_MIN_0,0));
- lm80_write_value(client,LM80_REG_IN_MAX(0),IN_TO_REG(LM80_INIT_IN_MAX_0,0));
- lm80_write_value(client,LM80_REG_IN_MIN(1),IN_TO_REG(LM80_INIT_IN_MIN_1,1));
- lm80_write_value(client,LM80_REG_IN_MAX(1),IN_TO_REG(LM80_INIT_IN_MAX_1,1));
- lm80_write_value(client,LM80_REG_IN_MIN(2),IN_TO_REG(LM80_INIT_IN_MIN_2,2));
- lm80_write_value(client,LM80_REG_IN_MAX(2),IN_TO_REG(LM80_INIT_IN_MAX_2,2));
- lm80_write_value(client,LM80_REG_IN_MIN(3),IN_TO_REG(LM80_INIT_IN_MIN_3,3));
- lm80_write_value(client,LM80_REG_IN_MAX(3),IN_TO_REG(LM80_INIT_IN_MAX_3,3));
- lm80_write_value(client,LM80_REG_IN_MIN(4),IN_TO_REG(LM80_INIT_IN_MIN_4,4));
- lm80_write_value(client,LM80_REG_IN_MAX(4),IN_TO_REG(LM80_INIT_IN_MAX_4,4));
- lm80_write_value(client,LM80_REG_IN_MIN(5),IN_TO_REG(LM80_INIT_IN_MIN_5,5));
- lm80_write_value(client,LM80_REG_IN_MAX(5),IN_TO_REG(LM80_INIT_IN_MAX_5,5));
- lm80_write_value(client,LM80_REG_IN_MIN(6),IN_TO_REG(LM80_INIT_IN_MIN_6,6));
- lm80_write_value(client,LM80_REG_IN_MAX(6),IN_TO_REG(LM80_INIT_IN_MAX_6,6));
- lm80_write_value(client,LM80_REG_FAN1_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_1,2));
- lm80_write_value(client,LM80_REG_FAN2_MIN,FAN_TO_REG(LM80_INIT_FAN_MIN_2,2));
- lm80_write_value(client,LM80_REG_TEMP_HOT_MAX,
- TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX));
- lm80_write_value(client,LM80_REG_TEMP_HOT_HYST,
- TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST));
- lm80_write_value(client,LM80_REG_TEMP_OS_MAX,
- TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_MAX));
- lm80_write_value(client,LM80_REG_TEMP_OS_HYST,
- TEMP_LIMIT_TO_REG(LM80_INIT_TEMP_OS_HYST));
-
- /* Start monitoring */
- lm80_write_value(client,LM80_REG_CONFIG,0x01);
-}
-
-void lm80_update_client(struct i2c_client *client)
-{
- struct lm80_data *data = client->data;
- int i;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > 2*HZ ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting lm80 update\n");
-#endif
- for (i = 0; i <= 6; i++) {
- data->in[i] = lm80_read_value(client,LM80_REG_IN(i));
- data->in_min[i] = lm80_read_value(client,LM80_REG_IN_MIN(i));
- data->in_max[i] = lm80_read_value(client,LM80_REG_IN_MAX(i));
- }
- data->fan[0] = lm80_read_value(client,LM80_REG_FAN1);
- data->fan_min[0] = lm80_read_value(client,LM80_REG_FAN1_MIN);
- data->fan[1] = lm80_read_value(client,LM80_REG_FAN2);
- data->fan_min[1] = lm80_read_value(client,LM80_REG_FAN2_MIN);
-
- data->temp = (lm80_read_value(client,LM80_REG_TEMP) << 8) |
- (lm80_read_value(client,LM80_REG_RES) & 0xf0);
- data->temp_os_max = lm80_read_value(client,LM80_REG_TEMP_OS_MAX);
- data->temp_os_hyst = lm80_read_value(client,LM80_REG_TEMP_OS_HYST);
- data->temp_hot_max = lm80_read_value(client,LM80_REG_TEMP_HOT_MAX);
- data->temp_hot_hyst = lm80_read_value(client,LM80_REG_TEMP_HOT_HYST);
-
- i = lm80_read_value(client,LM80_REG_FANDIV);
- data->fan_div[0] = (i >> 2) & 0x03;
- data->fan_div[1] = (i >> 4) & 0x03;
- data->alarms = lm80_read_value(client,LM80_REG_ALARM1) +
- (lm80_read_value(client,LM80_REG_ALARM2) << 8);
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-/* The next few functions are the call-back functions of the /proc/sys and
- sysctl files. Which function is used is defined in the ctl_table in
- the extra1 field.
- Each function must return the magnitude (power of 10 to divide the date
- with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
- put a maximum of *nrels elements in results reflecting the data of this
- file, and set *nrels to the number it actually put in it, if operation==
- SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
- results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
- Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
- large enough (by checking the incoming value of *nrels). This is not very
- good practice, but as long as you put less than about 5 values in results,
- you can assume it is large enough. */
-void lm80_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm80_data *data = client->data;
- int nr = ctl_name - LM80_SYSCTL_IN0;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm80_update_client(client);
- results[0] = IN_FROM_REG(data->in_min[nr],nr);
- results[1] = IN_FROM_REG(data->in_max[nr],nr);
- results[2] = IN_FROM_REG(data->in[nr],nr);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->in_min[nr] = IN_TO_REG(results[0],nr);
- lm80_write_value(client,LM80_REG_IN_MIN(nr),data->in_min[nr]);
- }
- if (*nrels_mag >= 2) {
- data->in_max[nr] = IN_TO_REG(results[1],nr);
- lm80_write_value(client,LM80_REG_IN_MAX(nr),data->in_max[nr]);
- }
- }
-}
-
-void lm80_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm80_data *data = client->data;
- int nr = ctl_name - LM80_SYSCTL_FAN1 + 1;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm80_update_client(client);
- results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]);
- results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]);
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]);
- lm80_write_value(client,nr==1?LM80_REG_FAN1_MIN:LM80_REG_FAN2_MIN,
- data->fan_min[nr-1]);
- }
- }
-}
-
-
-void lm80_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm80_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm80_update_client(client);
- results[0] = TEMP_LIMIT_FROM_REG(data->temp_hot_max);
- results[1] = TEMP_LIMIT_FROM_REG(data->temp_hot_hyst);
- results[2] = TEMP_LIMIT_FROM_REG(data->temp_os_max);
- results[3] = TEMP_LIMIT_FROM_REG(data->temp_os_hyst);
- results[4] = TEMP_FROM_REG(data->temp);
- *nrels_mag = 5;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_hot_max = TEMP_LIMIT_TO_REG(results[0]);
- lm80_write_value(client,LM80_REG_TEMP_HOT_MAX,data->temp_hot_max);
- }
- if (*nrels_mag >= 2) {
- data->temp_hot_hyst = TEMP_LIMIT_TO_REG(results[1]);
- lm80_write_value(client,LM80_REG_TEMP_HOT_HYST,data->temp_hot_hyst);
- }
- if (*nrels_mag >= 3) {
- data->temp_os_max = TEMP_LIMIT_TO_REG(results[2]);
- lm80_write_value(client,LM80_REG_TEMP_OS_MAX,data->temp_os_max);
- }
- if (*nrels_mag >= 4) {
- data->temp_os_hyst = TEMP_LIMIT_TO_REG(results[3]);
- lm80_write_value(client,LM80_REG_TEMP_OS_HYST,data->temp_os_hyst);
- }
- }
-}
-
-void lm80_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm80_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm80_update_client(client);
- results[0] = ALARMS_FROM_REG(data->alarms);
- *nrels_mag = 1;
- }
-}
-
-void lm80_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct lm80_data *data = client->data;
- int old;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- lm80_update_client(client);
- results[0] = DIV_FROM_REG(data->fan_div[0]);
- results[1] = DIV_FROM_REG(data->fan_div[1]);
- results[2] = 2;
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- old = lm80_read_value(client,LM80_REG_FANDIV);
- if (*nrels_mag >= 2) {
- data->fan_div[1] = DIV_TO_REG(results[1]);
- old = (old & 0xcf) | (data->fan_div[1] << 4);
- }
- if (*nrels_mag >= 1) {
- data->fan_div[0] = DIV_TO_REG(results[0]);
- old = (old & 0xf3) | (data->fan_div[0] << 2);
- lm80_write_value(client,LM80_REG_FANDIV,old);
- }
- }
-}
-
-int lm80_init(void)
-{
- int res;
-
- printk("lm80.o version %s (%s)\n",LM_VERSION,LM_DATE);
- lm80_initialized = 0;
-
- if ((res =i2c_add_driver(&lm80_driver))) {
- printk("lm80.o: Driver registration failed, module not inserted.\n");
- lm80_cleanup();
- return res;
- }
- lm80_initialized ++;
- return 0;
-}
-
-int lm80_cleanup(void)
-{
- int res;
-
- if (lm80_initialized >= 1) {
- if ((res = i2c_del_driver(&lm80_driver))) {
- printk("lm80.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- lm80_initialized --;
- }
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("LM80 driver");
-
-int init_module(void)
-{
- return lm80_init();
-}
-
-int cleanup_module(void)
-{
- return lm80_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/chips/w83781d.c b/kernel/chips/w83781d.c
deleted file mode 100644
index f2c8fd27..00000000
--- a/kernel/chips/w83781d.c
+++ /dev/null
@@ -1,1120 +0,0 @@
-/*
- w83781d.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
- and Philip Edelbrock <phil@netroedge.com>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include <linux/proc_fs.h>
-#include <linux/ioport.h>
-#include <linux/sysctl.h>
-#include <asm/errno.h>
-#include <asm/io.h>
-#include <linux/types.h>
-#include "smbus.h"
-#include "version.h"
-#include "isa.h"
-#include "sensors.h"
-#include "i2c.h"
-#include "compat.h"
-
-/* Many W83781D constants specified below */
-
-/* Length of ISA address segment */
-#define W83781D_EXTENT 8
-
-/* Where are the ISA address/data registers relative to the base address */
-#define W83781D_ADDR_REG_OFFSET 5
-#define W83781D_DATA_REG_OFFSET 6
-
-/* The W83781D registers */
-#define W83781D_REG_IN_MAX(nr) (0x2b + (nr) * 2)
-#define W83781D_REG_IN_MIN(nr) (0x2c + (nr) * 2)
-#define W83781D_REG_IN(nr) (0x20 + (nr))
-
-#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr))
-#define W83781D_REG_FAN(nr) (0x27 + (nr))
-
-#define W83781D_REG_TEMP2 0x0150
-#define W83781D_REG_TEMP3 0x0250
-#define W83781D_REG_TEMP2_HYST 0x153
-#define W83781D_REG_TEMP3_HYST 0x253
-#define W83781D_REG_TEMP2_CONFIG 0x152
-#define W83781D_REG_TEMP3_CONFIG 0x252
-#define W83781D_REG_TEMP2_OVER 0x155
-#define W83781D_REG_TEMP3_OVER 0x255
-
-#define W83781D_REG_TEMP 0x27
-#define W83781D_REG_TEMP_OVER 0x39
-#define W83781D_REG_TEMP_HYST 0x3A
-#define W83781D_REG_TEMP_CONFIG 0x52
-#define W83781D_REG_BANK 0x4E
-
-#define W83781D_REG_CONFIG 0x40
-#define W83781D_REG_ALARM1 0x41
-#define W83781D_REG_ALARM2 0x42
-
-#define W83781D_REG_BEEP_CONFIG 0x4D
-#define W83781D_REG_BEEP_INTS1 0x56
-#define W83781D_REG_BEEP_INTS2 0x57
-
-#define W83781D_REG_VID_FANDIV 0x47
-
-#define W83781D_REG_CHIPID 0x49
-#define W83781D_REG_WCHIPID 0x58
-#define W83781D_REG_CHIPMAN 0x4F
-#define W83781D_REG_PIN 0x4B
-
-
-/* Conversions. Rounding is only done on the TO_REG variants. */
-#define IN_TO_REG(val,nr) (((val) * 10 + 8)/16)
-#define IN_FROM_REG(val,nr) (((val) * 16) / 10)
-
-#define FAN_TO_REG(val,div) ((val)==0?255:((1350000+(val)*(div)/2)/\
- ((val)*(div))) & 0xff)
-#define FAN_FROM_REG(val,div) ((val)==0?-1:(val)==255?0:1350000/((val)*2*(div)))
-
-#define TEMP_TO_REG(val) (((val)<0?(((val)-5)/10)&0xff:((val)+5)/10) & 0xff)
-#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*10)
-
-#define TEMP_ADD_TO_REG(val) (((((val) + 2) / 5) << 7) & 0xff80)
-#define TEMP_ADD_FROM_REG(val) (((val) >> 7) * 5)
-
-#define VID_FROM_REG(val) ((val)==0x1f?0:(val)>=0x10?510-(val)*10:\
- (val)>=0x06?0:205-(val)*5)
-#define ALARMS_FROM_REG(val) (val)
-#define BEEPS_FROM_REG(val) (val)
-#define BEEPS_TO_REG(val) ((val) & 0xffff)
-
-#define BEEP_ENABLE_TO_REG(val) (val)
-#define BEEP_ENABLE_FROM_REG(val) ((val)?1:0)
-
-#define DIV_FROM_REG(val) (1 << (val))
-#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1)
-
-/* Initial limits */
-#define W83781D_INIT_IN_0 (vid==350?280:vid)
-#define W83781D_INIT_IN_1 (vid==350?280:vid)
-#define W83781D_INIT_IN_2 330
-#define W83781D_INIT_IN_3 (((500) * 100)/168)
-#define W83781D_INIT_IN_4 (((1200) * 10)/38)
-#define W83781D_INIT_IN_5 (((-1200) * -604)/2100)
-#define W83781D_INIT_IN_6 (((-500) * -604)/909)
-
-#define W83781D_INIT_IN_PERCENTAGE 10
-
-#define W83781D_INIT_IN_MIN_0 \
- (W83781D_INIT_IN_0 - W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_0 \
- (W83781D_INIT_IN_0 + W83781D_INIT_IN_0 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_1 \
- (W83781D_INIT_IN_1 - W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_1 \
- (W83781D_INIT_IN_1 + W83781D_INIT_IN_1 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_2 \
- (W83781D_INIT_IN_2 - W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_2 \
- (W83781D_INIT_IN_2 + W83781D_INIT_IN_2 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_3 \
- (W83781D_INIT_IN_3 - W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_3 \
- (W83781D_INIT_IN_3 + W83781D_INIT_IN_3 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_4 \
- (W83781D_INIT_IN_4 - W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_4 \
- (W83781D_INIT_IN_4 + W83781D_INIT_IN_4 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_5 \
- (W83781D_INIT_IN_5 - W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_5 \
- (W83781D_INIT_IN_5 + W83781D_INIT_IN_5 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MIN_6 \
- (W83781D_INIT_IN_6 - W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-#define W83781D_INIT_IN_MAX_6 \
- (W83781D_INIT_IN_6 + W83781D_INIT_IN_6 * W83781D_INIT_IN_PERCENTAGE \
- / 100)
-
-#define W83781D_INIT_FAN_MIN_1 3000
-#define W83781D_INIT_FAN_MIN_2 3000
-#define W83781D_INIT_FAN_MIN_3 3000
-
-#define W83781D_INIT_TEMP_OVER 600
-#define W83781D_INIT_TEMP_HYST 500
-#define W83781D_INIT_TEMP2_OVER 600
-#define W83781D_INIT_TEMP2_HYST 500
-#define W83781D_INIT_TEMP3_OVER 600
-#define W83781D_INIT_TEMP3_HYST 500
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-/* There are some complications in a module like this. First off, W83781D chips
- may be both present on the SMBus and the ISA bus, and we have to handle
- those cases separately at some places. Second, there might be several
- W83781D chips available (well, actually, that is probably never done; but
- it is a clean illustration of how to handle a case like that). Finally,
- a specific chip may be attached to *both* ISA and SMBus, and we would
- not like to detect it double. Fortunately, in the case of the W83781D at
- least, a register tells us what SMBus address we are on, so that helps
- a bit - except if there could be more than one SMBus. Groan. No solution
- for this yet. */
-
-/* This module may seem overly long and complicated. In fact, it is not so
- bad. Quite a lot of bookkeeping is done. A real driver can often cut
- some corners. */
-
-/* For each registered W83781D, we need to keep some data in memory. That
- data is pointed to by w83781d_list[NR]->data. The structure itself is
- dynamically allocated, at the same time when a new w83781d client is
- allocated. */
-struct w83781d_data {
- struct semaphore lock;
- int sysctl_id;
-
- struct semaphore update_lock;
- char valid; /* !=0 if following fields are valid */
- unsigned long last_updated; /* In jiffies */
-
- u8 in[7]; /* Register value */
- u8 in_max[7]; /* Register value */
- u8 in_min[7]; /* Register value */
- u8 fan[3]; /* Register value */
- u8 fan_min[3]; /* Register value */
- u8 temp;
- u8 temp_over; /* Register value */
- u8 temp_hyst; /* Register value */
- u16 temp_add[2]; /* Register value */
- u16 temp_add_over[2]; /* Register value */
- u16 temp_add_hyst[2]; /* Register value */
- u8 fan_div[3]; /* Register encoding, shifted right */
- u8 vid; /* Register encoding, combined */
- u16 alarms; /* Register encoding, combined */
- u16 beeps; /* Register encoding, combined */
- u8 beep_enable; /* Boolean */
-};
-
-
-static int w83781d_init(void);
-static int w83781d_cleanup(void);
-
-static int w83781d_attach_adapter(struct i2c_adapter *adapter);
-static int w83781d_detect_isa(struct isa_adapter *adapter);
-static int w83781d_detect_smbus(struct i2c_adapter *adapter);
-static int w83781d_detach_client(struct i2c_client *client);
-static int w83781d_detach_isa(struct isa_client *client);
-static int w83781d_detach_smbus(struct i2c_client *client);
-static int w83781d_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client);
-static void w83781d_remove_client(struct i2c_client *client);
-static int w83781d_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void w83781d_inc_use (struct i2c_client *client);
-static void w83781d_dec_use (struct i2c_client *client);
-
-static int w83781d_read_value(struct i2c_client *client, u16 register);
-static int w83781d_write_value(struct i2c_client *client, u16 register,
- u16 value);
-static void w83781d_update_client(struct i2c_client *client);
-static void w83781d_init_client(struct i2c_client *client);
-
-
-static void w83781d_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void w83781d_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void w83781d_temp(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void w83781d_temp_add(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void w83781d_vid(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void w83781d_alarms(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-static void w83781d_beep(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results);
-static void w83781d_fan_div(struct i2c_client *client, int operation,
- int ctl_name, int *nrels_mag, long *results);
-
-/* I choose here for semi-static W83781D allocation. Complete dynamic
- allocation could also be used; the code needed for this would probably
- take more memory than the datastructure takes now. */
-#define MAX_W83781D_NR 4
-static struct i2c_client *w83781d_list[MAX_W83781D_NR];
-
-/* The driver. I choose to use type i2c_driver, as at is identical to both
- smbus_driver and isa_driver, and clients could be of either kind */
-static struct i2c_driver w83781d_driver = {
- /* name */ "W83781D sensor driver",
- /* id */ I2C_DRIVERID_W83781D,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &w83781d_attach_adapter,
- /* detach_client */ &w83781d_detach_client,
- /* command */ &w83781d_command,
- /* inc_use */ &w83781d_inc_use,
- /* dec_use */ &w83781d_dec_use
-};
-
-/* Used by w83781d_init/cleanup */
-static int w83781d_initialized = 0;
-
-/* The /proc/sys entries */
-/* These files are created for each detected W83781D. This is just a template;
- though at first sight, you might think we could use a statically
- allocated list, we need some way to get back to the parent - which
- is done through one of the 'extra' fields which are initialized
- when a new copy is allocated. */
-static ctl_table w83781d_dir_table_template[] = {
- { W83781D_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN4, "in4", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_in },
- { W83781D_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_fan },
- { W83781D_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_fan },
- { W83781D_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_fan },
- { W83781D_SYSCTL_TEMP1, "temp1", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_temp },
- { W83781D_SYSCTL_TEMP2, "temp2", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_temp_add },
- { W83781D_SYSCTL_TEMP3, "temp3", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_temp_add },
- { W83781D_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_vid },
- { W83781D_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_fan_div },
- { W83781D_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_alarms },
- { W83781D_SYSCTL_BEEP, "beep", NULL, 0, 0644, NULL, &sensors_proc_real,
- &sensors_sysctl_real, NULL, &w83781d_beep },
- { 0 }
-};
-
-
-/* This function is called when:
- * w83781d_driver is inserted (when this module is loaded), for each
- available adapter
- * when a new adapter is inserted (and w83781d_driver is still present) */
-int w83781d_attach_adapter(struct i2c_adapter *adapter)
-{
- if (i2c_is_isa_adapter(adapter))
- return w83781d_detect_isa((struct isa_adapter *) adapter);
- else
- return w83781d_detect_smbus(adapter);
-}
-
-/* This function is called whenever a client should be removed:
- * w83781d_driver is removed (when this module is unloaded)
- * when an adapter is removed which has a w83781d client (and w83781d_driver
- is still present). */
-int w83781d_detach_client(struct i2c_client *client)
-{
- if (i2c_is_isa_client(client))
- return w83781d_detach_isa((struct isa_client *) client);
- else
- return w83781d_detach_smbus(client);
-}
-
-/* Detect whether there is a W83781D on the ISA bus, register and initialize
- it. */
-int w83781d_detect_isa(struct isa_adapter *adapter)
-{
- int address,err;
- struct isa_client *new_client;
- const char *type_name;
- const char *client_name;
-
- /* OK, this is no detection. I know. It will do for now, though. */
-
- err = 0;
- for (address = 0x290; (! err) && (address <= 0x290); address += 0x08) {
- if (check_region(address, W83781D_EXTENT))
- continue;
-
- /* Awful, but true: unused port addresses should return 0xff */
- if ((inb_p(address + 1) != 0xff) || (inb_p(address + 2) != 0xff) ||
- (inb_p(address + 3) != 0xff) || (inb_p(address + 7) != 0xff))
- continue;
-
- if (inb_p(address + W83781D_ADDR_REG_OFFSET) == 0xff) {
- outb_p(0x00,address + W83781D_ADDR_REG_OFFSET);
- if (inb_p(address + W83781D_ADDR_REG_OFFSET) == 0xff)
- continue;
- }
-
- /* Real detection code goes here */
-
- /* The Winbond may be stuck in bank 1 or 2. This should reset it.
- We really need some nifty detection code, because this can lead
- to a lot of problems if there is no Winbond present! */
- outb_p(W83781D_REG_BANK,address + W83781D_ADDR_REG_OFFSET);
- outb_p(0x00,address + W83781D_DATA_REG_OFFSET);
-
- outb_p(W83781D_REG_WCHIPID,address + W83781D_ADDR_REG_OFFSET);
- err = inb_p(address + W83781D_DATA_REG_OFFSET) & 0xfe;
-
- if (err != 0x20) {
- printk("w83781d.o: Winbond W83781D detected (ISA addr=0x%X)\n",address);
- type_name = "w83781d";
- client_name = "Winbond W83781D chip";
- } else {
- #ifdef DEBUG
- printk("83781d.o: Winbond W83781D not detected (ISA)\n");
- #endif
- continue;
- }
-
- request_region(address, W83781D_EXTENT, type_name);
-
- /* Allocate space for a new client structure */
- if (! (new_client = kmalloc(sizeof(struct isa_client) +
- sizeof(struct w83781d_data),
- GFP_KERNEL)))
- {
- err=-ENOMEM;
- goto ERROR1;
- }
-
- /* Fill the new client structure with data */
- new_client->data = (struct w83781d_data *) (new_client + 1);
- new_client->addr = 0;
- strcpy(new_client->name,client_name);
- new_client->isa_addr = address;
- if ((err = w83781d_new_client((struct i2c_adapter *) adapter,
- (struct i2c_client *) new_client)))
- goto ERROR2;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = isa_attach_client(new_client)))
- goto ERROR3;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry((struct i2c_client *) new_client,
- type_name,
- w83781d_dir_table_template)) < 0)
- goto ERROR4;
- ((struct w83781d_data *) (new_client->data)) -> sysctl_id = err;
- err = 0;
-
- /* Initialize the W83781D chip */
- w83781d_init_client((struct i2c_client *) new_client);
- continue;
-
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-
-ERROR4:
- isa_detach_client(new_client);
-ERROR3:
- w83781d_remove_client((struct i2c_client *) new_client);
-ERROR2:
- kfree(new_client);
-ERROR1:
- release_region(address, W83781D_EXTENT);
- }
- return err;
-
-}
-
-/* Deregister and remove a W83781D client */
-int w83781d_detach_isa(struct isa_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_W83781D_NR; i++)
- if ((client == (struct isa_client *) (w83781d_list[i])))
- break;
- if (i == MAX_W83781D_NR) {
- printk("w83781d.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct w83781d_data *)(client->data))->sysctl_id);
-
- if ((err = isa_detach_client(client))) {
- printk("w83781d.o: Client deregistration failed, client not detached.\n");
- return err;
- }
- w83781d_remove_client((struct i2c_client *) client);
- release_region(client->isa_addr,W83781D_EXTENT);
- kfree(client);
- return 0;
-}
-
-int w83781d_detect_smbus(struct i2c_adapter *adapter)
-{
- int address,err;
- struct i2c_client *new_client;
- const char *type_name,*client_name;
-
- /* OK, this is no detection. I know. It will do for now, though. */
- err = 0;
- for (address = 0x20; (! err) && (address <= 0x2f); address ++) {
-
- /* Later on, we will keep a list of registered addresses for each
- adapter, and check whether they are used here */
-
- if (smbus_read_byte_data(adapter,address,W83781D_REG_CONFIG) < 0)
- continue;
-
- smbus_write_byte_data(adapter,address,W83781D_REG_BANK,0x00);
-
- err = smbus_read_byte_data(adapter,address,W83781D_REG_WCHIPID);
-
- if (err == 0x20) {
- printk("w83781d.o: Winbond W83781D detected (SMBus addr 0x%X)\n",address);
- type_name = "w83781d";
- client_name = "Winbond W83781D chip";
- } else {
- #ifdef DEBUG
- printk("83781d.o: Winbond W83781D not detected (SMBus/I2C)\n");
- #endif
- continue;
- }
-
- /* Allocate space for a new client structure. To counter memory
- ragmentation somewhat, we only do one kmalloc. */
- if (! (new_client = kmalloc(sizeof(struct i2c_client) +
- sizeof(struct w83781d_data),
- GFP_KERNEL))) {
- err = -ENOMEM;
- continue;
- }
-
- /* Fill the new client structure with data */
- new_client->data = (struct w83781d_data *) (new_client + 1);
- new_client->addr = address;
- strcpy(new_client->name,client_name);
- if ((err = w83781d_new_client(adapter,new_client)))
- goto ERROR2;
-
- /* Tell i2c-core a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR3;
-
- /* Register a new directory entry with module sensors */
- if ((err = sensors_register_entry(new_client,type_name,
- w83781d_dir_table_template)) < 0)
- goto ERROR4;
- ((struct w83781d_data *) (new_client->data))->sysctl_id = err;
- err = 0;
-
- /* Initialize the W83781D chip */
- w83781d_init_client(new_client);
- continue;
-
-/* OK, this is not exactly good programming practice, usually. But it is
- very code-efficient in this case. */
-ERROR4:
- i2c_detach_client(new_client);
-ERROR3:
- w83781d_remove_client((struct i2c_client *) new_client);
-ERROR2:
- kfree(new_client);
- }
- return err;
-}
-
-int w83781d_detach_smbus(struct i2c_client *client)
-{
- int err,i;
- for (i = 0; i < MAX_W83781D_NR; i++)
- if (client == w83781d_list[i])
- break;
- if ((i == MAX_W83781D_NR)) {
- printk("w83781d.o: Client to detach not found.\n");
- return -ENOENT;
- }
-
- sensors_deregister_entry(((struct w83781d_data *)(client->data))->sysctl_id);
-
- if ((err = i2c_detach_client(client))) {
- printk("w83781d.o: Client deregistration failed, client not detached.\n");
- return err;
- }
- w83781d_remove_client(client);
- kfree(client);
- return 0;
-}
-
-
-/* Find a free slot, and initialize most of the fields */
-int w83781d_new_client(struct i2c_adapter *adapter,
- struct i2c_client *new_client)
-{
- int i;
- struct w83781d_data *data;
-
- /* First, seek out an empty slot */
- for(i = 0; i < MAX_W83781D_NR; i++)
- if (! w83781d_list[i])
- break;
- if (i == MAX_W83781D_NR) {
- printk("w83781d.o: No empty slots left, recompile and heighten "
- "MAX_W83781D_NR!\n");
- return -ENOMEM;
- }
-
- w83781d_list[i] = new_client;
- new_client->id = i;
- new_client->adapter = adapter;
- new_client->driver = &w83781d_driver;
- data = new_client->data;
- data->valid = 0;
- data->lock = MUTEX;
- data->update_lock = MUTEX;
- return 0;
-}
-
-/* Inverse of w83781d_new_client */
-void w83781d_remove_client(struct i2c_client *client)
-{
- int i;
- for (i = 0; i < MAX_W83781D_NR; i++)
- if (client == w83781d_list[i])
- w83781d_list[i] = NULL;
-}
-
-/* No commands defined yet */
-int w83781d_command(struct i2c_client *client, unsigned int cmd, void *arg)
-{
- return 0;
-}
-
-/* Nothing here yet */
-void w83781d_inc_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-}
-
-/* Nothing here yet */
-void w83781d_dec_use (struct i2c_client *client)
-{
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-}
-
-
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
- bank switches. ISA access must always be locked explicitely!
- We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
- would slow down the W83781D access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
-int w83781d_read_value(struct i2c_client *client, u16 reg)
-{
- int res,word_sized;
-
- word_sized = (reg & 0xff00) && (((reg & 0x00ff) == 0x50) ||
- ((reg & 0x00ff) == 0x53) ||
- ((reg & 0x00ff) == 0x55));
- down((struct semaphore *) (client->data));
- if (i2c_is_isa_client(client)) {
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- }
- outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- res = inb_p((((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- if (word_sized) {
- outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- res = (res << 8) + inb_p((((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- }
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- outb_p(0,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- }
- } else {
- if (reg & 0xff00)
- smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,
- reg >> 8);
- res = smbus_read_byte_data(client->adapter,client->addr, reg);
- if (word_sized)
- res = (res << 8) + smbus_read_byte_data(client->adapter,client->addr,
- reg);
- if (reg & 0xff00)
- smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0);
- }
- up((struct semaphore *) (client->data));
- return res;
-}
-
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
- bank switches. ISA access must always be locked explicitely!
- We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
- would slow down the W83781D access and should not be necessary.
- There are some ugly typecasts here, but the good new is - they should
- nowhere else be necessary! */
-int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
-{
- int word_sized;
-
- word_sized = (reg & 0xff00) && (((reg & 0x00ff) == 0x50) ||
- ((reg & 0x00ff) == 0x53) ||
- ((reg & 0x00ff) == 0x55));
- down((struct semaphore *) (client->data));
- if (i2c_is_isa_client(client)) {
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- outb_p(reg >> 8,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- }
- outb_p(reg & 0xff,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- if (word_sized) {
- outb_p(value >> 8,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- outb_p((reg & 0xff)+1,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- }
- outb_p(value &0xff,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,(((struct isa_client *) client)->isa_addr) +
- W83781D_ADDR_REG_OFFSET);
- outb_p(0,(((struct isa_client *) client)->isa_addr) +
- W83781D_DATA_REG_OFFSET);
- }
- } else {
- if (reg & 0xff00)
- smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,
- reg >> 8);
- if (word_sized) {
- smbus_write_byte_data(client->adapter,client->addr, reg, value >> 8);
- smbus_write_byte_data(client->adapter,client->addr, reg+1, value &0xff);
- } else
- smbus_write_byte_data(client->adapter,client->addr, reg, value &0xff);
- if (reg & 0xff00)
- smbus_write_byte_data(client->adapter,client->addr,W83781D_REG_BANK,0);
- }
- up((struct semaphore *) (client->data));
- return 0;
-}
-
-/* Called when we have found a new W83781D. It should set limits, etc. */
-void w83781d_init_client(struct i2c_client *client)
-{
- int vid;
-
- /* Reset all except Watchdog values and last conversion values
- This sets fan-divs to 2, among others */
- w83781d_write_value(client,W83781D_REG_CONFIG,0x80);
-
- vid = w83781d_read_value(client,W83781D_REG_VID_FANDIV) & 0x0f;
- vid |= (w83781d_read_value(client,W83781D_REG_CHIPID) & 0x01) >> 4;
- vid = VID_FROM_REG(vid);
-
- w83781d_write_value(client,W83781D_REG_IN_MIN(0),
- IN_TO_REG(W83781D_INIT_IN_MIN_0,0));
- w83781d_write_value(client,W83781D_REG_IN_MAX(0),
- IN_TO_REG(W83781D_INIT_IN_MAX_0,0));
- w83781d_write_value(client,W83781D_REG_IN_MIN(1),
- IN_TO_REG(W83781D_INIT_IN_MIN_1,1));
- w83781d_write_value(client,W83781D_REG_IN_MAX(1),
- IN_TO_REG(W83781D_INIT_IN_MAX_1,1));
- w83781d_write_value(client,W83781D_REG_IN_MIN(2),
- IN_TO_REG(W83781D_INIT_IN_MIN_2,2));
- w83781d_write_value(client,W83781D_REG_IN_MAX(2),
- IN_TO_REG(W83781D_INIT_IN_MAX_2,2));
- w83781d_write_value(client,W83781D_REG_IN_MIN(3),
- IN_TO_REG(W83781D_INIT_IN_MIN_3,3));
- w83781d_write_value(client,W83781D_REG_IN_MAX(3),
- IN_TO_REG(W83781D_INIT_IN_MAX_3,3));
- w83781d_write_value(client,W83781D_REG_IN_MIN(4),
- IN_TO_REG(W83781D_INIT_IN_MIN_4,4));
- w83781d_write_value(client,W83781D_REG_IN_MAX(4),
- IN_TO_REG(W83781D_INIT_IN_MAX_4,4));
- w83781d_write_value(client,W83781D_REG_IN_MIN(5),
- IN_TO_REG(W83781D_INIT_IN_MIN_5,5));
- w83781d_write_value(client,W83781D_REG_IN_MAX(5),
- IN_TO_REG(W83781D_INIT_IN_MAX_5,5));
- w83781d_write_value(client,W83781D_REG_IN_MIN(6),
- IN_TO_REG(W83781D_INIT_IN_MIN_6,6));
- w83781d_write_value(client,W83781D_REG_IN_MAX(6),
- IN_TO_REG(W83781D_INIT_IN_MAX_6,6));
- w83781d_write_value(client,W83781D_REG_FAN_MIN(1),
- FAN_TO_REG(W83781D_INIT_FAN_MIN_1,2));
- w83781d_write_value(client,W83781D_REG_FAN_MIN(2),
- FAN_TO_REG(W83781D_INIT_FAN_MIN_2,2));
- w83781d_write_value(client,W83781D_REG_FAN_MIN(3),
- FAN_TO_REG(W83781D_INIT_FAN_MIN_3,2));
-
- w83781d_write_value(client,W83781D_REG_TEMP_OVER,
- TEMP_TO_REG(W83781D_INIT_TEMP_OVER));
- w83781d_write_value(client,W83781D_REG_TEMP_HYST,
- TEMP_TO_REG(W83781D_INIT_TEMP_HYST));
- w83781d_write_value(client,W83781D_REG_TEMP_CONFIG,0x00);
-
- w83781d_write_value(client,W83781D_REG_TEMP2_OVER,
- TEMP_ADD_TO_REG(W83781D_INIT_TEMP2_OVER));
- w83781d_write_value(client,W83781D_REG_TEMP2_HYST,
- TEMP_ADD_TO_REG(W83781D_INIT_TEMP2_HYST));
- w83781d_write_value(client,W83781D_REG_TEMP2_CONFIG,0x00);
-
- w83781d_write_value(client,W83781D_REG_TEMP3_OVER,
- TEMP_ADD_TO_REG(W83781D_INIT_TEMP3_OVER));
- w83781d_write_value(client,W83781D_REG_TEMP3_HYST,
- TEMP_ADD_TO_REG(W83781D_INIT_TEMP3_HYST));
- w83781d_write_value(client,W83781D_REG_TEMP3_CONFIG,0x00);
-
- /* Start monitoring */
- w83781d_write_value(client,W83781D_REG_CONFIG,
- (w83781d_read_value(client,
- W83781D_REG_CONFIG) & 0xf7) | 0x01);
-}
-
-void w83781d_update_client(struct i2c_client *client)
-{
- struct w83781d_data *data = client->data;
- int i;
-
- down(&data->update_lock);
-
- if ((jiffies - data->last_updated > HZ+HZ/2 ) ||
- (jiffies < data->last_updated) || ! data->valid) {
-
-#ifdef DEBUG
- printk("Starting w83781d update\n");
-#endif
- for (i = 0; i <= 6; i++) {
- data->in[i] = w83781d_read_value(client,W83781D_REG_IN(i));
- data->in_min[i] = w83781d_read_value(client,W83781D_REG_IN_MIN(i));
- data->in_max[i] = w83781d_read_value(client,W83781D_REG_IN_MAX(i));
- }
- for (i = 1; i <= 3; i++) {
- data->fan[i-1] = w83781d_read_value(client,W83781D_REG_FAN(i));
- data->fan_min[i-1] = w83781d_read_value(client,W83781D_REG_FAN_MIN(i));
- }
- data->temp = w83781d_read_value(client,W83781D_REG_TEMP);
- data->temp_over = w83781d_read_value(client,W83781D_REG_TEMP_OVER);
- data->temp_hyst = w83781d_read_value(client,W83781D_REG_TEMP_HYST);
- data->temp_add[0] = w83781d_read_value(client,W83781D_REG_TEMP2);
- data->temp_add_over[0] = w83781d_read_value(client,W83781D_REG_TEMP2_OVER);
- data->temp_add_hyst[0] = w83781d_read_value(client,W83781D_REG_TEMP2_HYST);
- data->temp_add[1] = w83781d_read_value(client,W83781D_REG_TEMP3);
- data->temp_add_over[1] = w83781d_read_value(client,W83781D_REG_TEMP3_OVER);
- data->temp_add_hyst[1] = w83781d_read_value(client,W83781D_REG_TEMP3_HYST);
- i = w83781d_read_value(client,W83781D_REG_VID_FANDIV);
- data->vid = i & 0x0f;
- data->vid |= (w83781d_read_value(client,W83781D_REG_CHIPID) & 0x01) >> 4;
- data->fan_div[0] = (i >> 4) & 0x03;
- data->fan_div[1] = i >> 6;
- data->fan_div[2] = (w83781d_read_value(client,W83781D_REG_PIN) >> 6) & 0x03;
- data->alarms = w83781d_read_value(client,W83781D_REG_ALARM1) +
- (w83781d_read_value(client,W83781D_REG_ALARM2) << 8);
- i = w83781d_read_value(client,W83781D_REG_BEEP_INTS2);
- data->beep_enable = i >> 7;
- data->beeps = ((i & 0x7f) << 8) +
- w83781d_read_value(client,W83781D_REG_BEEP_INTS1);
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- up(&data->update_lock);
-}
-
-
-/* The next few functions are the call-back functions of the /proc/sys and
- sysctl files. Which function is used is defined in the ctl_table in
- the extra1 field.
- Each function must return the magnitude (power of 10 to divide the date
- with) if it is called with operation==SENSORS_PROC_REAL_INFO. It must
- put a maximum of *nrels elements in results reflecting the data of this
- file, and set *nrels to the number it actually put in it, if operation==
- SENSORS_PROC_REAL_READ. Finally, it must get upto *nrels elements from
- results and write them to the chip, if operations==SENSORS_PROC_REAL_WRITE.
- Note that on SENSORS_PROC_REAL_READ, I do not check whether results is
- large enough (by checking the incoming value of *nrels). This is not very
- good practice, but as long as you put less than about 5 values in results,
- you can assume it is large enough. */
-void w83781d_in(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- int nr = ctl_name - W83781D_SYSCTL_IN0;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = IN_FROM_REG(data->in_min[nr],nr);
- results[1] = IN_FROM_REG(data->in_max[nr],nr);
- results[2] = IN_FROM_REG(data->in[nr],nr);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->in_min[nr] = IN_TO_REG(results[0],nr);
- w83781d_write_value(client,W83781D_REG_IN_MIN(nr),data->in_min[nr]);
- }
- if (*nrels_mag >= 2) {
- data->in_max[nr] = IN_TO_REG(results[1],nr);
- w83781d_write_value(client,W83781D_REG_IN_MAX(nr),data->in_max[nr]);
- }
- }
-}
-
-void w83781d_fan(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- int nr = ctl_name - W83781D_SYSCTL_FAN1 + 1;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = FAN_FROM_REG(data->fan_min[nr-1],data->fan_div[nr-1]);
- results[1] = FAN_FROM_REG(data->fan[nr-1],data->fan_div[nr-1]);
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->fan_min[nr-1] = FAN_TO_REG(results[0],data->fan_div[nr-1]);
- w83781d_write_value(client,W83781D_REG_FAN_MIN(nr),data->fan_min[nr-1]);
- }
- }
-}
-
-
-void w83781d_temp(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = TEMP_FROM_REG(data->temp_over);
- results[1] = TEMP_FROM_REG(data->temp_hyst);
- results[2] = TEMP_FROM_REG(data->temp);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_over = TEMP_TO_REG(results[0]);
- w83781d_write_value(client,W83781D_REG_TEMP_OVER,data->temp_over);
- }
- if (*nrels_mag >= 2) {
- data->temp_hyst = TEMP_TO_REG(results[1]);
- w83781d_write_value(client,W83781D_REG_TEMP_HYST,data->temp_hyst);
- }
- }
-}
-
-
-void w83781d_temp_add(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- int nr = ctl_name - W83781D_SYSCTL_TEMP2;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 1;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = TEMP_ADD_FROM_REG(data->temp_add_over[nr]);
- results[1] = TEMP_ADD_FROM_REG(data->temp_add_hyst[nr]);
- results[2] = TEMP_ADD_FROM_REG(data->temp_add[nr]);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 1) {
- data->temp_add_over[nr] = TEMP_ADD_TO_REG(results[0]);
- w83781d_write_value(client,
- nr?W83781D_REG_TEMP3_OVER:W83781D_REG_TEMP2_OVER,
- data->temp_add_over[nr]);
- }
- if (*nrels_mag >= 2) {
- data->temp_add_hyst[nr] = TEMP_ADD_TO_REG(results[1]);
- w83781d_write_value(client,
- nr?W83781D_REG_TEMP3_HYST:W83781D_REG_TEMP2_HYST,
- data->temp_add_hyst[nr]);
- }
- }
-}
-
-
-void w83781d_vid(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 2;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = VID_FROM_REG(data->vid);
- *nrels_mag = 1;
- }
-}
-
-void w83781d_alarms(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = ALARMS_FROM_REG(data->alarms);
- *nrels_mag = 1;
- }
-}
-
-void w83781d_beep(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- int val;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = BEEP_ENABLE_FROM_REG(data->beep_enable);
- results[1] = BEEPS_FROM_REG(data->beeps);
- *nrels_mag = 2;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- if (*nrels_mag >= 2) {
- data->beeps = BEEPS_TO_REG(results[1]);
- w83781d_write_value(client,W83781D_REG_BEEP_INTS1,data->beeps & 0xff);
- val = data->beeps >> 8;
- } else if (*nrels_mag >= 1)
- val = w83781d_read_value(client,W83781D_REG_BEEP_INTS1) & 0x7f;
- if (*nrels_mag >= 1) {
- data->beep_enable = BEEP_ENABLE_TO_REG(results[0]);
- w83781d_write_value(client,W83781D_REG_BEEP_INTS2,
- val | data->beep_enable << 7);
- }
- }
-}
-
-void w83781d_fan_div(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
-{
- struct w83781d_data *data = client->data;
- int old;
-
- if (operation == SENSORS_PROC_REAL_INFO)
- *nrels_mag = 0;
- else if (operation == SENSORS_PROC_REAL_READ) {
- w83781d_update_client(client);
- results[0] = DIV_FROM_REG(data->fan_div[0]);
- results[1] = DIV_FROM_REG(data->fan_div[1]);
- results[2] = DIV_FROM_REG(data->fan_div[2]);
- *nrels_mag = 3;
- } else if (operation == SENSORS_PROC_REAL_WRITE) {
- old = w83781d_read_value(client,W83781D_REG_VID_FANDIV);
- if (*nrels_mag >= 2) {
- data->fan_div[1] = DIV_TO_REG(results[1]);
- old = (old & 0x3f) | (data->fan_div[1] << 6);
- }
- if (*nrels_mag >= 1) {
- data->fan_div[0] = DIV_TO_REG(results[0]);
- old = (old & 0xcf) | (data->fan_div[0] << 4);
- w83781d_write_value(client,W83781D_REG_VID_FANDIV,old);
- }
- if (*nrels_mag >= 3) {
- data->fan_div[2] = DIV_TO_REG(results[2]);
- w83781d_write_value(client,W83781D_REG_PIN,
- w83781d_read_value(client,W83781D_REG_PIN));
- }
- }
-}
-
-int w83781d_init(void)
-{
- int res;
-
- printk("w83781d.o version %s (%s)\n",LM_VERSION,LM_DATE);
- w83781d_initialized = 0;
-
- if ((res =i2c_add_driver(&w83781d_driver))) {
- printk("w83781d.o: Driver registration failed, module not inserted.\n");
- w83781d_cleanup();
- return res;
- }
- w83781d_initialized ++;
- return 0;
-}
-
-int w83781d_cleanup(void)
-{
- int res;
-
- if (w83781d_initialized >= 1) {
- if ((res = i2c_del_driver(&w83781d_driver))) {
- printk("w83781d.o: Driver deregistration failed, module not removed.\n");
- return res;
- }
- w83781d_initialized --;
- }
- return 0;
-}
-
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Philip Edelbrock <phil@netroedge.com>");
-MODULE_DESCRIPTION("W83781D driver");
-
-int init_module(void)
-{
- return w83781d_init();
-}
-
-int cleanup_module(void)
-{
- return w83781d_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/compat.h b/kernel/compat.h
deleted file mode 100644
index 04b0c455..00000000
--- a/kernel/compat.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- compat.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_COMPAT_H
-#define SENSORS_COMPAT_H
-
-/* This useful macro is not defined in the 2.0 kernels */
-
-#include <linux/version.h>
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
-#endif
-
-#ifdef MODULE
-#include <linux/module.h>
-#ifndef MODULE_AUTHOR
-#define MODULE_AUTHOR(whatever)
-#endif
-#ifndef MODULE_DESCRIPTION
-#define MODULE_DESCRIPTION(whatever)
-#endif
-#endif /* def MODULE */
-
-/* copy_from/to_usr is called memcpy_from/to_fs in 2.0 kernels
- get_user was redefined in 2.1 kernels to use two arguments, and returns
- an error code */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,4))
-#define copy_from_user memcpy_fromfs
-#define copy_to_user memcpy_tofs
-#define get_user_data(to,from) ((to) = get_user(from),0)
-#else
-#include <asm/uaccess.h>
-#define get_user_data(to,from) get_user(to,from)
-#endif
-
-/* Add a scheduling fix for the new code in kernel 2.1.127 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,127))
-#define schedule_timeout(x) ( current->timeout = jiffies + (x), schedule() )
-#endif
-
-/* If the new PCI interface is not present, fall back on the old PCI BIOS
- interface. We also define some things to unite both interfaces. Not
- very nice, but it works like a charm.
- device is the 2.1 struct pci_dev, bus is the 2.0 bus number, dev is the
- 2.0 device/function code, com is the PCI command, and res is the result. */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54))
-#define pci_present pcibios_present
-#define pci_read_config_byte_united(device,bus,dev,com,res) \
- pcibios_read_config_byte(bus,dev,com,res);
-#define pci_read_config_word_united(device,bus,dev,com,res) \
- pcibios_read_config_word(bus,dev,com,res);
-#define pci_write_config_byte_united(device,bus,dev,com,res) \
- pcibios_write_config_byte(bus,dev,com,res);
-#define pci_write_config_word_united(device,bus,dev,com,res) \
- pcibios_write_config_word(bus,dev,com,res);
-#else
-#define pci_read_config_byte_united(device,bus,dev,com,res) \
- pci_read_config_byte(device,com,res);
-#define pci_read_config_word_united(device,bus,dev,com,res) \
- pci_read_config_word(device,com,res);
-#define pci_write_config_byte_united(device,bus,dev,com,res) \
- pci_write_config_byte(device,com,res);
-#define pci_write_config_word_united(device,bus,dev,com,res) \
- pci_write_config_byte(device,com,res);
-#endif
-
-
-#endif /* SENSORS_COMPAT_H */
diff --git a/kernel/i2c-proc.c b/kernel/i2c-proc.c
deleted file mode 100644
index 383386d5..00000000
--- a/kernel/i2c-proc.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/proc_fs.h>
-
-#include "i2c.h"
-#include "smbus.h"
-#include "isa.h"
-#include "version.h"
-#include "compat.h"
-#include "sensors.h"
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* def MODULE */
-
-static int i2cproc_init(void);
-static int i2cproc_cleanup(void);
-static int i2cproc_attach_adapter(struct i2c_adapter *adapter);
-static int i2cproc_detach_client(struct i2c_client *client);
-static int i2cproc_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-static void i2cproc_inc_use(struct i2c_client *client);
-static void i2cproc_dec_use(struct i2c_client *client);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
-static void monitor_bus_i2c(struct inode *inode, int fill);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
-
-static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
- loff_t *ppos);
-static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
- int *eof , void *private);
-
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
-
-static int i2cproc_bus_read(struct inode * inode, struct file * file,
- char * buf, int count);
-static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
- int unused);
-
-static struct proc_dir_entry proc_bus_dir =
- {
- /* low_ino */ 0, /* Set by proc_register_dynamic */
- /* namelen */ 3,
- /* name */ "bus",
- /* mode */ S_IRUGO | S_IXUGO | S_IFDIR,
- /* nlink */ 2, /* Corrected by proc_register[_dynamic] */
- /* uid */ 0,
- /* gid */ 0,
- /* size */ 0,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,36))
- /* ops */ &proc_dir_inode_operations,
-#endif
- };
-
-static struct proc_dir_entry proc_bus_i2c_dir =
- {
- /* low_ino */ 0, /* Set by proc_register_dynamic */
- /* namelen */ 3,
- /* name */ "i2c",
- /* mode */ S_IRUGO | S_IFREG,
- /* nlink */ 1,
- /* uid */ 0,
- /* gid */ 0,
- /* size */ 0,
- /* ops */ NULL,
- /* get_info */ &read_bus_i2c
- };
-
-/* List of registered entries in /proc/bus */
-static struct proc_dir_entry *i2cproc_proc_entries[I2C_ADAP_MAX];
-
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
-
-/* To implement the dynamic /proc/bus/i2c-? files, we need our own
- implementation of the read hook */
-static struct file_operations i2cproc_operations = {
- NULL,
- i2cproc_bus_read,
-};
-
-static struct inode_operations i2cproc_inode_operations = {
- &i2cproc_operations
-};
-
-
-/* Used by init/cleanup */
-static int i2cproc_initialized;
-
-/* This is a sorted list of all adapters that will have entries in /proc/bus */
-static struct i2c_adapter *i2cproc_adapters[I2C_ADAP_MAX];
-
-/* Inodes of /dev/bus/i2c-? files */
-static int i2cproc_inodes[I2C_ADAP_MAX];
-
-/* We will use a nasty trick: we register a driver, that will be notified
- for each adapter. Then, we register a dummy client on the adapter, that
- will get notified if the adapter is removed. This is the same trick as
- used in i2c/i2c-dev.c */
-static struct i2c_driver i2cproc_driver = {
- /* name */ "i2c-proc dummy driver",
- /* id */ I2C_DRIVERID_I2CPROC,
- /* flags */ DF_NOTIFY,
- /* attach_adapter */ &i2cproc_attach_adapter,
- /* detach_client */ &i2cproc_detach_client,
- /* command */ &i2cproc_command,
- /* inc_use */ &i2cproc_inc_use,
- /* dec_use */ &i2cproc_dec_use
-};
-
-static struct i2c_client i2cproc_client_template = {
- /* name */ "i2c-proc dummy client",
- /* id */ 1,
- /* flags */ 0,
- /* addr */ -1,
- /* adapter */ NULL,
- /* driver */ &i2cproc_driver,
- /* data */ NULL
-};
-
-
-int i2cproc_init(void)
-{
- int res;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- struct proc_dir_entry *proc_bus_i2c;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
-
- printk("i2c-proc.o version %s (%s)\n",LM_VERSION,LM_DATE);
- i2cproc_initialized = 0;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- if (! proc_bus) {
- printk("i2c-proc.o: /proc/bus/ does not exist, module not inserted.\n");
- i2cproc_cleanup();
- return -ENOENT;
- }
- proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
- if (!proc_bus_i2c) {
- printk("i2c-proc.o: Could not create /proc/bus/i2c, "
- "module not inserted.\n");
- i2cproc_cleanup();
- return -ENOENT;
- }
- proc_bus_i2c->read_proc = &read_bus_i2c;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
- proc_bus_i2c->fill_inode = &monitor_bus_i2c;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
- i2cproc_initialized += 2;
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
- /* In Linux 2.0.x, there is no /proc/bus! But I hope no other module
- introduced it, or we are fucked. And 2.0.35 and earlier does not
- export proc_dir_inode_operations, so we grab it from proc_net,
- which also uses it. Not nice. */
-/* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,36) */
- proc_bus_dir.ops = proc_net.ops;
-/* #endif */
- if ((res = proc_register_dynamic(&proc_root, &proc_bus_dir))) {
- printk("i2c-proc.o: Could not create /proc/bus/, module not inserted.\n");
- i2cproc_cleanup();
- return res;
- }
- i2cproc_initialized ++;
- if ((res = proc_register_dynamic(&proc_bus_dir, &proc_bus_i2c_dir))) {
- printk("i2c-proc.o: Could not create /proc/bus/i2c, "
- "module not inserted.\n");
- i2cproc_cleanup();
- return res;
- }
- i2cproc_initialized ++;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
- if ((res = i2c_add_driver(&i2cproc_driver))) {
- printk("i2c-proc.o: Driver registration failed, module not inserted.\n");
- i2cproc_cleanup();
- return res;
- }
- i2cproc_initialized ++;
- return 0;
-}
-
-int i2cproc_cleanup(void)
-{
- int res;
-
- if (i2cproc_initialized >= 3) {
- if ((res = i2c_del_driver(&i2cproc_driver))) {
- printk("i2c-proc.o: Driver deregistration failed, "
- "module not removed.\n");
- return res;
- }
- i2cproc_initialized--;
- }
- if (i2cproc_initialized >= 1) {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- remove_proc_entry("i2c",proc_bus);
- i2cproc_initialized -= 2;
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
- if (i2cproc_initialized >= 2) {
- if ((res = proc_unregister(&proc_bus_dir,proc_bus_i2c_dir.low_ino))) {
- printk("i2c-proc.o: could not delete /proc/bus/i2c, "
- "module not removed.");
- return res;
- }
- i2cproc_initialized --;
- }
- if ((res = proc_unregister(&proc_root,proc_bus_dir.low_ino))) {
- printk("i2c-proc.o: could not delete /proc/bus/, "
- "module not removed.");
- return res;
- }
- i2cproc_initialized --;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
- }
- return 0;
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
-/* Monitor access to /proc/bus/i2c*; make unloading i2c-proc.o impossible
- if some process still uses it or some file in it */
-void monitor_bus_i2c(struct inode *inode, int fill)
-{
- if (fill)
- MOD_INC_USE_COUNT;
- else
- MOD_DEC_USE_COUNT;
-}
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-
-
-/* This function generates the output for /proc/bus/i2c */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
-int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
- void *private)
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
-int read_bus_i2c(char *buf, char **start, off_t offset, int len, int unused)
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
-{
- int i;
- len = 0;
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if (i2cproc_adapters[i])
- len += sprintf(buf+len, "i2c-%d\t%s\t%-32s\t%-32s\n",
- i2c_adapter_id(i2cproc_adapters[i]),
- i2c_is_smbus_adapter(i2cproc_adapters[i])?"smbus":
-#ifdef DEBUG
- i2c_is_isa_adapter(i2cproc_adapters[i])?"isa":
-#endif /* def DEBUG */
- "i2c",
- i2cproc_adapters[i]->name,
- i2cproc_adapters[i]->algo->name);
- return len;
-}
-
-/* This function generates the output for /proc/bus/i2c-? */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
-ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
- loff_t *ppos)
-{
- struct inode * inode = file->f_dentry->d_inode;
-#else (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29))
-int i2cproc_bus_read(struct inode * inode, struct file * file,char * buf,
- int count)
-{
-#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- char *kbuf;
- struct i2c_client *client;
- int i,j,len=0;
-
- if (count < 0)
- return -EINVAL;
- if (count > 4000)
- count = 4000;
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if (i2cproc_inodes[i] == inode->i_ino) {
- if (! (kbuf = kmalloc(count,GFP_KERNEL)))
- return -ENOMEM;
- for (j = 0; j < I2C_CLIENT_MAX; j++)
- if ((client = i2cproc_adapters[i]->clients[j]))
- /* Filter out dummy clients */
-#ifndef DEBUG
- if (client->driver->id != I2C_DRIVERID_I2CPROC)
-#endif /* ndef DEBUG */
- len += sprintf(kbuf+len,"%x\t%-32s\t%-32s\n",
-#ifdef DEBUG
- i2c_is_isa_client(client)?
- ((struct isa_client *) client)->isa_addr&0xffffff:
-#endif /* def DEBUG */
- client->addr,
- client->name,client->driver->name);
- if (file->f_pos+len > count)
- len = count - file->f_pos;
- len = len - file->f_pos;
- if (len < 0)
- len = 0;
- copy_to_user (buf,kbuf+file->f_pos,len);
- file->f_pos += len;
- kfree(kbuf);
- return len;
- }
- return -ENOENT;
-}
-
-
-/* We need to add the adapter to i2cproc_adapters, if it is interesting
- enough */
-int i2cproc_attach_adapter(struct i2c_adapter *adapter)
-{
- struct i2c_client *client;
- int i,res;
- char name[8];
-
- struct proc_dir_entry *proc_entry;
-
-#ifndef DEBUG
- if (i2c_is_isa_adapter(adapter))
- return 0;
-#endif /* ndef DEBUG */
-
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if(!i2cproc_adapters[i])
- break;
- if (i == I2C_ADAP_MAX) {
- printk("i2c-proc.o: Too many adapters!\n");
- return -ENOMEM;
- }
-
-#ifndef DEBUG
- if (! (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) {
-#else /* def DEBUG */
- if (! (client = kmalloc(sizeof(struct isa_client),GFP_KERNEL))) {
-#endif
- printk("i2c-proc.o: Out of memory!\n");
- return -ENOMEM;
- }
- memcpy(client,&i2cproc_client_template,sizeof(struct i2c_client));
-#ifdef DEBUG
- ((struct isa_client *) client) -> isa_addr = -1;
-#endif /* def DEBUG */
- client->adapter = adapter;
- if ((res = i2c_attach_client(client))) {
- printk("i2c-proc.o: Attaching client failed.\n");
- kfree(client);
- return res;
- }
- i2cproc_adapters[i] = adapter;
-
- sprintf(name,"i2c-%d",i2c_adapter_id(adapter));
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- proc_entry = create_proc_entry(name,0,proc_bus);
- if (! proc_entry) {
- printk("i2c-proc.o: Could not create /proc/bus/%s\n",name);
- kfree(client);
- return -ENOENT;
- }
- proc_entry->ops = &i2cproc_inode_operations;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
- proc_entry->fill_inode = &monitor_bus_i2c;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
- if (!(proc_entry = kmalloc(sizeof(struct proc_dir_entry)+strlen(name)+1,
- GFP_KERNEL))) {
- printk("i2c-proc.o: Out of memory!\n");
- return -ENOMEM;
- }
-
- memset(proc_entry,0,sizeof(struct proc_dir_entry));
- proc_entry->namelen = strlen(name);
- proc_entry->name = (char *) (proc_entry + 1);
- proc_entry->mode = S_IRUGO | S_IFREG;
- proc_entry->nlink = 1;
- proc_entry->ops = &i2cproc_inode_operations;
- strcpy((char *) proc_entry->name,name);
-
- if ((res = proc_register_dynamic(&proc_bus_dir, proc_entry))) {
- printk("i2c-proc.o: Could not create %s.\n",name);
- kfree(proc_entry);
- kfree(client);
- return res;
- }
-
- i2cproc_proc_entries[i] = proc_entry;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
-
- i2cproc_inodes[i] = proc_entry->low_ino;
- return 0;
-}
-
-int i2cproc_detach_client(struct i2c_client *client)
-{
- int i,res;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- char name[8];
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
-
-#ifndef DEBUG
- if (i2c_is_isa_client(client))
- return 0;
-#endif /* ndef DEBUG */
-
- for (i = 0; i < I2C_ADAP_MAX; i++)
- if (client->adapter == i2cproc_adapters[i]) {
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29))
- sprintf(name,"i2c-%d",i2c_adapter_id(i2cproc_adapters[i]));
- remove_proc_entry(name,proc_bus);
-#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,29)) */
- if ((res = proc_unregister(&proc_bus_dir,
- i2cproc_proc_entries[i]->low_ino))) {
- printk("i2c-proc.o: Deregistration of /proc entry failed, "
- "client not detached.\n");
- return res;
- }
- kfree(i2cproc_proc_entries[i]);
- i2cproc_proc_entries[i] = NULL;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,29)) */
- if ((res = i2c_detach_client(client))) {
- printk("i2c-proc.o: Client deregistration failed, "
- "client not detached.\n");
- return res;
- }
- i2cproc_adapters[i] = NULL;
- i2cproc_inodes[i] = 0;
- kfree(client);
- return 0;
- }
- return -ENOENT;
-}
-
-/* Nothing here yet */
-int i2cproc_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- return -1;
-}
-
-/* Nothing here yet */
-void i2cproc_inc_use(struct i2c_client *client)
-{
-}
-
-/* Nothing here yet */
-void i2cproc_dec_use(struct i2c_client *client)
-{
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("I2C /proc/bus entries driver");
-
-int init_module(void)
-{
- return i2cproc_init();
-}
-
-int cleanup_module(void)
-{
- return i2cproc_cleanup();
-}
-
-#endif /* def MODULE */
-
diff --git a/kernel/include/compat.h b/kernel/include/compat.h
deleted file mode 100644
index 04b0c455..00000000
--- a/kernel/include/compat.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- compat.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_COMPAT_H
-#define SENSORS_COMPAT_H
-
-/* This useful macro is not defined in the 2.0 kernels */
-
-#include <linux/version.h>
-#ifndef KERNEL_VERSION
-#define KERNEL_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
-#endif
-
-#ifdef MODULE
-#include <linux/module.h>
-#ifndef MODULE_AUTHOR
-#define MODULE_AUTHOR(whatever)
-#endif
-#ifndef MODULE_DESCRIPTION
-#define MODULE_DESCRIPTION(whatever)
-#endif
-#endif /* def MODULE */
-
-/* copy_from/to_usr is called memcpy_from/to_fs in 2.0 kernels
- get_user was redefined in 2.1 kernels to use two arguments, and returns
- an error code */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,4))
-#define copy_from_user memcpy_fromfs
-#define copy_to_user memcpy_tofs
-#define get_user_data(to,from) ((to) = get_user(from),0)
-#else
-#include <asm/uaccess.h>
-#define get_user_data(to,from) get_user(to,from)
-#endif
-
-/* Add a scheduling fix for the new code in kernel 2.1.127 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,127))
-#define schedule_timeout(x) ( current->timeout = jiffies + (x), schedule() )
-#endif
-
-/* If the new PCI interface is not present, fall back on the old PCI BIOS
- interface. We also define some things to unite both interfaces. Not
- very nice, but it works like a charm.
- device is the 2.1 struct pci_dev, bus is the 2.0 bus number, dev is the
- 2.0 device/function code, com is the PCI command, and res is the result. */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,54))
-#define pci_present pcibios_present
-#define pci_read_config_byte_united(device,bus,dev,com,res) \
- pcibios_read_config_byte(bus,dev,com,res);
-#define pci_read_config_word_united(device,bus,dev,com,res) \
- pcibios_read_config_word(bus,dev,com,res);
-#define pci_write_config_byte_united(device,bus,dev,com,res) \
- pcibios_write_config_byte(bus,dev,com,res);
-#define pci_write_config_word_united(device,bus,dev,com,res) \
- pcibios_write_config_word(bus,dev,com,res);
-#else
-#define pci_read_config_byte_united(device,bus,dev,com,res) \
- pci_read_config_byte(device,com,res);
-#define pci_read_config_word_united(device,bus,dev,com,res) \
- pci_read_config_word(device,com,res);
-#define pci_write_config_byte_united(device,bus,dev,com,res) \
- pci_write_config_byte(device,com,res);
-#define pci_write_config_word_united(device,bus,dev,com,res) \
- pci_write_config_byte(device,com,res);
-#endif
-
-
-#endif /* SENSORS_COMPAT_H */
diff --git a/kernel/include/i2c-isa.h b/kernel/include/i2c-isa.h
deleted file mode 100644
index df8bb5ff..00000000
--- a/kernel/include/i2c-isa.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- isa.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_SENSOR_H
-#define SENSORS_SENSOR_H
-
-#ifdef __KERNEL__
-
-/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
- OK, earlier versions are not; later versions will probably give problems
- too.
-*/
-#include <asm/types.h>
-
-/* SPINLOCK is defined in i2c.h. */
-#ifdef SPINLOCK
-#include <asm/spinlock.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#ifdef LM_SENSORS
-#include "i2c.h"
-#else /* ndef LM_SENSORS */
-#include <linux/i2c.h>
-#endif /* def LM_SENSORS */
-
-/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
- We do not need SMBus facilities if we are on the ISA bus, after all */
-
-/* Declarations, to keep the compiler happy */
-struct isa_driver;
-struct isa_client;
-struct isa_algorithm;
-struct isa_adapter;
-
-/* A driver tells us how we should handle a specific kind of chip.
- A specific instance of such a chip is called a client.
- This structure is essentially the same as i2c_driver. */
-struct isa_driver {
- char name[32];
- int id;
- unsigned int flags;
- int (* attach_adapter) (struct isa_adapter *);
- int (* detach_client) (struct isa_client *);
- int (* command) (struct isa_client *, unsigned int cmd, void *arg);
- void (* inc_use) (struct isa_client *);
- void (* dec_use) (struct isa_client *);
-};
-
-/* A client is a specifc instance of a chip: for each detected chip, there will
- be a client. Its operation is controlled by a driver.
- This structure is an extension of i2c_client. */
-struct isa_client {
- char name[32];
- int id;
- unsigned int flags;
- unsigned char addr;
- struct isa_adapter *adapter;
- struct isa_driver *driver;
- void *data;
-
- /* Here ended i2c_client */
- unsigned int isa_addr;
-};
-
-/* An algorithm describes how a certain class of busses can be accessed.
- A specific instance of sucj a bus is called an adapter.
- This structure is essentially the same as i2c_adapter. */
-struct isa_algorithm {
- char name[32];
- unsigned int id;
- int (* master_xfer) (struct isa_adapter *adap, struct i2c_msg msgs[],
- int num);
- int (* slave_send) (struct isa_adapter *,char *, int);
- int (* slave_recv) (struct isa_adapter *,char *, int);
- int (* algo_control) (struct isa_adapter *, unsigned int, unsigned long);
- int (* client_register) (struct isa_client *);
- int (* client_unregister) (struct isa_client *);
-};
-
-/* An adapter is a specifc instance of a bus: for each detected bus, there will
- be an adapter. Its operation is controlled by an algorithm.
- SPINLOCK must be the same as declared in i2c.h.
- This structure is essentially the same as i2c_algorithm. */
-struct isa_adapter {
- char name[32];
- unsigned int id;
- struct isa_algorithm *algo;
- void *data;
-#ifdef SPINLOCK
- spinlock_t lock;
- unsigned long lockflags;
-#else
- struct semaphore lock;
-#endif
- unsigned int flags;
- struct isa_client *clients[I2C_CLIENT_MAX];
- int client_count;
- int timeout;
- int retries;
-};
-
-
-/* Detect whether we are on the isa bus. If this returns true, all i2c
- access will fail! */
-#define i2c_is_isa_client(clientptr) \
- ((clientptr)->adapter->algo->id == ALGO_ISA)
-#define i2c_is_isa_adapter(adapptr) \
- ((adapptr)->algo->id == ALGO_ISA)
-
-/* Next: define ISA variants of registering. */
-#define isa_add_algorithm(algoptr) \
- i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
-#define isa_del_algorithm(algoptr) \
- i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
-
-#define isa_add_adapter(adapptr) \
- i2c_add_adapter((struct i2c_adapter *) (adapptr))
-#define isa_del_adapter(adapptr) \
- i2c_del_adapter((struct i2c_adapter *) (adapptr))
-
-#define isa_add_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-#define isa_del_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-
-#define isa_attach_client(clientptr) \
- i2c_attach_client((struct i2c_client *) (clientptr))
-#define isa_detach_client(clientptr) \
- i2c_detach_client((struct i2c_client *) (clientptr))
-
-#endif /* def __KERNEL__ */
-
-/* We need to mark ISA algorithms in the algorithm structure. */
-#define ALGO_ISA 0x50000
-
-/* ISA Adapter ids */
-#define ISA_MAIN 1
-
-#endif /* ndef SENSORS_ISA_H */
diff --git a/kernel/include/i2c.h b/kernel/include/i2c.h
deleted file mode 100644
index 644565c5..00000000
--- a/kernel/include/i2c.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- i2c.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-
-/* This is a stub files, that either includes <linux/i2c.h> (the kernel
- header) or "i2c/i2c.h" (the header in the i2c directory). */
-
-#ifdef I2C
-#include "i2c/i2c.h"
-#else /* def I2C */
-#include <linux/i2c.h>
-#endif /* def I2C */
-
diff --git a/kernel/include/isa.h b/kernel/include/isa.h
deleted file mode 100644
index df8bb5ff..00000000
--- a/kernel/include/isa.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- isa.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_SENSOR_H
-#define SENSORS_SENSOR_H
-
-#ifdef __KERNEL__
-
-/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
- OK, earlier versions are not; later versions will probably give problems
- too.
-*/
-#include <asm/types.h>
-
-/* SPINLOCK is defined in i2c.h. */
-#ifdef SPINLOCK
-#include <asm/spinlock.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#ifdef LM_SENSORS
-#include "i2c.h"
-#else /* ndef LM_SENSORS */
-#include <linux/i2c.h>
-#endif /* def LM_SENSORS */
-
-/* Note that this driver is *not* built upon smbus.c, but is parallel to it.
- We do not need SMBus facilities if we are on the ISA bus, after all */
-
-/* Declarations, to keep the compiler happy */
-struct isa_driver;
-struct isa_client;
-struct isa_algorithm;
-struct isa_adapter;
-
-/* A driver tells us how we should handle a specific kind of chip.
- A specific instance of such a chip is called a client.
- This structure is essentially the same as i2c_driver. */
-struct isa_driver {
- char name[32];
- int id;
- unsigned int flags;
- int (* attach_adapter) (struct isa_adapter *);
- int (* detach_client) (struct isa_client *);
- int (* command) (struct isa_client *, unsigned int cmd, void *arg);
- void (* inc_use) (struct isa_client *);
- void (* dec_use) (struct isa_client *);
-};
-
-/* A client is a specifc instance of a chip: for each detected chip, there will
- be a client. Its operation is controlled by a driver.
- This structure is an extension of i2c_client. */
-struct isa_client {
- char name[32];
- int id;
- unsigned int flags;
- unsigned char addr;
- struct isa_adapter *adapter;
- struct isa_driver *driver;
- void *data;
-
- /* Here ended i2c_client */
- unsigned int isa_addr;
-};
-
-/* An algorithm describes how a certain class of busses can be accessed.
- A specific instance of sucj a bus is called an adapter.
- This structure is essentially the same as i2c_adapter. */
-struct isa_algorithm {
- char name[32];
- unsigned int id;
- int (* master_xfer) (struct isa_adapter *adap, struct i2c_msg msgs[],
- int num);
- int (* slave_send) (struct isa_adapter *,char *, int);
- int (* slave_recv) (struct isa_adapter *,char *, int);
- int (* algo_control) (struct isa_adapter *, unsigned int, unsigned long);
- int (* client_register) (struct isa_client *);
- int (* client_unregister) (struct isa_client *);
-};
-
-/* An adapter is a specifc instance of a bus: for each detected bus, there will
- be an adapter. Its operation is controlled by an algorithm.
- SPINLOCK must be the same as declared in i2c.h.
- This structure is essentially the same as i2c_algorithm. */
-struct isa_adapter {
- char name[32];
- unsigned int id;
- struct isa_algorithm *algo;
- void *data;
-#ifdef SPINLOCK
- spinlock_t lock;
- unsigned long lockflags;
-#else
- struct semaphore lock;
-#endif
- unsigned int flags;
- struct isa_client *clients[I2C_CLIENT_MAX];
- int client_count;
- int timeout;
- int retries;
-};
-
-
-/* Detect whether we are on the isa bus. If this returns true, all i2c
- access will fail! */
-#define i2c_is_isa_client(clientptr) \
- ((clientptr)->adapter->algo->id == ALGO_ISA)
-#define i2c_is_isa_adapter(adapptr) \
- ((adapptr)->algo->id == ALGO_ISA)
-
-/* Next: define ISA variants of registering. */
-#define isa_add_algorithm(algoptr) \
- i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
-#define isa_del_algorithm(algoptr) \
- i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
-
-#define isa_add_adapter(adapptr) \
- i2c_add_adapter((struct i2c_adapter *) (adapptr))
-#define isa_del_adapter(adapptr) \
- i2c_del_adapter((struct i2c_adapter *) (adapptr))
-
-#define isa_add_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-#define isa_del_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-
-#define isa_attach_client(clientptr) \
- i2c_attach_client((struct i2c_client *) (clientptr))
-#define isa_detach_client(clientptr) \
- i2c_detach_client((struct i2c_client *) (clientptr))
-
-#endif /* def __KERNEL__ */
-
-/* We need to mark ISA algorithms in the algorithm structure. */
-#define ALGO_ISA 0x50000
-
-/* ISA Adapter ids */
-#define ISA_MAIN 1
-
-#endif /* ndef SENSORS_ISA_H */
diff --git a/kernel/include/sensors.h b/kernel/include/sensors.h
deleted file mode 100644
index 575a29db..00000000
--- a/kernel/include/sensors.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- sensors.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_SENSORS_H
-#define SENSORS_SENSORS_H
-
-#ifdef __KERNEL__
-
-/* Next two must be included before sysctl.h can be included, in 2.0 kernels */
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/sysctl.h>
-
-/* The type of callback functions used in sensors_{proc,sysctl}_real */
-typedef void (*sensors_real_callback) (struct i2c_client *client,
- int operation, int ctl_name,
- int *nrels_mag, long *results);
-
-/* Values for the operation field in the above function type */
-#define SENSORS_PROC_REAL_INFO 1
-#define SENSORS_PROC_REAL_READ 2
-#define SENSORS_PROC_REAL_WRITE 3
-
-/* These funcion reads or writes a 'real' value (encoded by the combination
- of an integer and a magnitude, the last is the power of ten the value
- should be divided with) to a /proc/sys directory. To use these functions,
- you must (before registering the ctl_table) set the extra2 field to the
- client, and the extra1 field to a function of the form:
- void func(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
- This last function can be called for three values of operation. If
- operation equals SENSORS_PROC_REAL_INFO, the magnitude should be returned
- in nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
- be read into results. nrels_mag should return the number of elements
- read; the maximum number is put in it on entry. Finally, if operation
- equals SENSORS_PROC_REAL_WRITE, the values in results should be
- written to the chip. nrels_mag contains on entry the number of elements
- found.
- In all cases, client points to the client we wish to interact with,
- and ctl_name is the SYSCTL id of the file we are accessing. */
-extern int sensors_sysctl_real (ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp, void *newval,
- size_t newlen, void **context);
-extern int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp);
-
-
-
-/* These rather complex functions must be called when you want to add or
- delete an entry in /proc/sys/dev/sensors/chips (not yet implemented). It
- also creates a new directory within /proc/sys/dev/sensors/.
- ctl_template should be a template of the newly created directory. It is
- copied in memory. The extra2 field of each file is set to point to client.
- If any driver wants subdirectories within the newly created directory,
- these functions must be updated! */
-extern int sensors_register_entry(struct i2c_client *client,
- const char *prefix, ctl_table *ctl_template);
-extern void sensors_deregister_entry(int id);
-
-#endif /* def __KERNEL__ */
-
-
-/* The maximum length of the prefix */
-#define SENSORS_PREFIX_MAX 20
-
-/* Driver IDs */
-#define I2C_DRIVERID_I2CPROC 1001
-#define I2C_DRIVERID_LM78 1002
-#define I2C_DRIVERID_LM75 1003
-#define I2C_DRIVERID_GL518 1004
-#define I2C_DRIVERID_EEPROM 1005
-#define I2C_DRIVERID_W83781D 1006
-#define I2C_DRIVERID_LM80 1007
-
-/* Sysctl IDs */
-#ifdef DEV_HWMON
-#define DEV_SENSORS DEV_HWMON
-#else /* ndef DEV_HWMOM */
-#define DEV_SENSORS 2 /* The id of the lm_sensors directory within the
- dev table */
-#endif /* def DEV_HWMON */
-
-#define SENSORS_CHIPS 1
-struct sensors_chips_data {
- int sysctl_id;
- char name[SENSORS_PREFIX_MAX + 13];
-};
-
-#define LM78_SYSCTL_IN0 1000 /* Volts * 100 */
-#define LM78_SYSCTL_IN1 1001
-#define LM78_SYSCTL_IN2 1002
-#define LM78_SYSCTL_IN3 1003
-#define LM78_SYSCTL_IN4 1004
-#define LM78_SYSCTL_IN5 1005
-#define LM78_SYSCTL_IN6 1006
-#define LM78_SYSCTL_FAN1 1101 /* Rotations/min */
-#define LM78_SYSCTL_FAN2 1102
-#define LM78_SYSCTL_FAN3 1103
-#define LM78_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */
-#define LM78_SYSCTL_VID 1300 /* Volts * 100 */
-#define LM78_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
-#define LM78_SYSCTL_ALARMS 2001 /* bitvector */
-
-#define LM78_ALARM_IN0 0x0001
-#define LM78_ALARM_IN1 0x0002
-#define LM78_ALARM_IN2 0x0004
-#define LM78_ALARM_IN3 0x0008
-#define LM78_ALARM_IN4 0x0100
-#define LM78_ALARM_IN5 0x0200
-#define LM78_ALARM_IN6 0x0400
-#define LM78_ALARM_FAN1 0x0040
-#define LM78_ALARM_FAN2 0x0080
-#define LM78_ALARM_FAN3 0x0800
-#define LM78_ALARM_TEMP 0x0010
-#define LM78_ALARM_BTI 0x0020
-#define LM78_ALARM_CHAS 0x1000
-#define LM78_ALARM_FIFO 0x2000
-#define LM78_ALARM_SMI_IN 0x4000
-
-#define W83781D_SYSCTL_IN0 1000 /* Volts * 100 */
-#define W83781D_SYSCTL_IN1 1001
-#define W83781D_SYSCTL_IN2 1002
-#define W83781D_SYSCTL_IN3 1003
-#define W83781D_SYSCTL_IN4 1004
-#define W83781D_SYSCTL_IN5 1005
-#define W83781D_SYSCTL_IN6 1006
-#define W83781D_SYSCTL_FAN1 1101 /* Rotations/min */
-#define W83781D_SYSCTL_FAN2 1102
-#define W83781D_SYSCTL_FAN3 1103
-#define W83781D_SYSCTL_TEMP1 1200 /* Degrees Celcius * 10 */
-#define W83781D_SYSCTL_TEMP2 1201 /* Degrees Celcius * 10 */
-#define W83781D_SYSCTL_TEMP3 1202 /* Degrees Celcius * 10 */
-#define W83781D_SYSCTL_VID 1300 /* Volts * 100 */
-#define W83781D_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
-#define W83781D_SYSCTL_ALARMS 2001 /* bitvector */
-#define W83781D_SYSCTL_BEEP 2002 /* bitvector */
-
-#define W83781D_ALARM_IN0 0x0001
-#define W83781D_ALARM_IN1 0x0002
-#define W83781D_ALARM_IN2 0x0004
-#define W83781D_ALARM_IN3 0x0008
-#define W83781D_ALARM_IN4 0x0100
-#define W83781D_ALARM_IN5 0x0200
-#define W83781D_ALARM_IN6 0x0400
-#define W83781D_ALARM_FAN1 0x0040
-#define W83781D_ALARM_FAN2 0x0080
-#define W83781D_ALARM_FAN3 0x0800
-#define W83781D_ALARM_TEMP1 0x0010
-#define W83781D_ALARM_TEMP23 0x0020
-#define W83781D_ALARM_CHAS 0x1000
-
-#define LM75_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */
-
-#define GL518_SYSCTL_VDD 1000 /* Volts * 100 */
-#define GL518_SYSCTL_VIN1 1001
-#define GL518_SYSCTL_VIN2 1002
-#define GL518_SYSCTL_VIN3 1003
-#define GL518_SYSCTL_FAN1 1101 /* RPM */
-#define GL518_SYSCTL_FAN2 1102
-#define GL518_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */
-#define GL518_SYSCTL_VID 1300
-#define GL518_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
-#define GL518_SYSCTL_ALARMS 2001 /* bitvector */
-#define GL518_SYSCTL_BEEP 2002 /* bitvector */
-
-#define GL518_ALARM_VDD 0x01
-#define GL518_ALARM_VIN1 0x02
-#define GL518_ALARM_VIN2 0x04
-#define GL518_ALARM_VIN3 0x08
-#define GL518_ALARM_TEMP 0x10
-#define GL518_ALARM_FAN1 0x20
-#define GL518_ALARM_FAN2 0x40
-
-#define EEPROM_SYSCTL1 1000
-#define EEPROM_SYSCTL2 1001
-#define EEPROM_SYSCTL3 1002
-#define EEPROM_SYSCTL4 1003
-#define EEPROM_SYSCTL5 1004
-#define EEPROM_SYSCTL6 1005
-#define EEPROM_SYSCTL7 1006
-#define EEPROM_SYSCTL8 1007
-
-#define LM80_SYSCTL_IN0 1000 /* Volts * 100 */
-#define LM80_SYSCTL_IN1 1001
-#define LM80_SYSCTL_IN2 1002
-#define LM80_SYSCTL_IN3 1003
-#define LM80_SYSCTL_IN4 1004
-#define LM80_SYSCTL_IN5 1005
-#define LM80_SYSCTL_IN6 1006
-#define LM80_SYSCTL_FAN1 1101 /* Rotations/min */
-#define LM80_SYSCTL_FAN2 1102
-#define LM80_SYSCTL_TEMP 1250 /* Degrees Celcius * 100 */
-#define LM80_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */
-#define LM80_SYSCTL_ALARMS 2001 /* bitvector */
-
-#define LM80_ALARM_IN0 0x0001
-#define LM80_ALARM_IN1 0x0002
-#define LM80_ALARM_IN2 0x0004
-#define LM80_ALARM_IN3 0x0008
-#define LM80_ALARM_IN4 0x0010
-#define LM80_ALARM_IN5 0x0020
-#define LM80_ALARM_IN6 0x0040
-#define LM80_ALARM_FAN1 0x0400
-#define LM80_ALARM_FAN2 0x0800
-#define LM80_ALARM_TEMP_HOT 0x0100
-#define LM80_ALARM_TEMP_OS 0x2000
-#define LM80_ALARM_CHAS 0x1000
-#define LM80_ALARM_BTI 0x0200
-#define LM80_ALARM_INT_IN 0x0080
-#endif /* def SENSORS_SENSORS_H */
diff --git a/kernel/include/smbus.h b/kernel/include/smbus.h
deleted file mode 100644
index c50ce233..00000000
--- a/kernel/include/smbus.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- smbus.h - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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.
-*/
-
-#ifndef SENSORS_SMBUS_H
-#define SENSORS_SMBUS_H
-
-#ifdef __KERNEL__
-
-/* This file must interface with Simon Vogl's i2c driver. Version 19981006 is
- OK, earlier versions are not; later versions will probably give problems
- too.
-*/
-#include <asm/types.h>
-
-/* SPINLOCK is defined in i2c.h. */
-#ifdef SPINLOCK
-#include <asm/spinlock.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#ifdef LM_SENSORS
-#include "i2c.h"
-#else
-#include <linux/i2c.h>
-#endif
-
-/* Declarations, to keep the compiler happy */
-struct smbus_driver;
-struct smbus_client;
-struct smbus_algorithm;
-struct smbus_adapter;
-union smbus_data;
-
-/* A driver tells us how we should handle a specific kind of chip.
- A specific instance of such a chip is called a client.
- This structure is essentially the same as i2c_driver. */
-struct smbus_driver {
- char name[32];
- int id;
- unsigned int flags;
- int (* attach_adapter) (struct smbus_adapter *);
- int (* detach_client) (struct smbus_client *);
- int (* command) (struct smbus_client *, unsigned int cmd, void *arg);
- void (* inc_use) (struct smbus_client *);
- void (* dec_use) (struct smbus_client *);
-};
-
-/* A client is a specifc instance of a chip: for each detected chip, there will
- be a client. Its operation is controlled by a driver.
- This structure is essentially the same as i2c_client. */
-struct smbus_client {
- char name[32];
- int id;
- unsigned int flags;
- unsigned char addr;
- struct smbus_adapter *adapter;
- struct smbus_driver *driver;
- void *data;
-};
-
-/* An algorithm describes how a certain class of busses can be accessed.
- A specific instance of sucj a bus is called an adapter.
- This structure is essentially the same as i2c_adapter. */
-struct smbus_algorithm {
- char name[32];
- unsigned int id;
- int (* master_xfer) (struct smbus_adapter *adap, struct i2c_msg msgs[],
- int num);
- int (* slave_send) (struct smbus_adapter *,char *, int);
- int (* slave_recv) (struct smbus_adapter *,char *, int);
- int (* algo_control) (struct smbus_adapter *, unsigned int, unsigned long);
- int (* client_register) (struct smbus_client *);
- int (* client_unregister) (struct smbus_client *);
-};
-
-/* An adapter is a specifc instance of a bus: for each detected bus, there will
- be an adapter. Its operation is controlled by an algorithm.
- SPINLOCK must be the same as declared in i2c.h.
- This structure is an extension of i2c_algorithm. */
-struct smbus_adapter {
- char name[32];
- unsigned int id;
- struct smbus_algorithm *algo;
- void *data;
-#ifdef SPINLOCK
- spinlock_t lock;
- unsigned long lockflags;
-#else
- struct semaphore lock;
-#endif
- unsigned int flags;
- struct smbus_client *clients[I2C_CLIENT_MAX];
- int client_count;
- int timeout;
- int retries;
-
- /* Here ended i2c_adapter */
- s32 (* smbus_access) (u8 addr, char read_write,
- u8 command, int size, union smbus_data * data);
-};
-
-/* We need to mark SMBus algorithms in the algorithm structure.
- Note that any and all adapters using a non-i2c driver use in this
- setup ALGO_SMBUS. Adapters define their own smbus access routine.
- This also means that adapter->smbus_access is only available if
- this flag is set! */
-#define ALGO_SMBUS 0x40000
-
-/* SMBus Adapter ids */
-#define SMBUS_PIIX4 1
-
-/* Detect whether we are on an SMBus-only bus. Note that if this returns
- false, you can still use the smbus access routines, as these emulate
- the SMBus on I2C. Unless they are undefined on your algorithm, of
- course. */
-#define i2c_is_smbus_client(clientptr) \
- ((clientptr)->adapter->algo->id == ALGO_SMBUS)
-#define i2c_is_smbus_adapter(adapptr) \
- ((adapptr)->algo->id == ALGO_SMBUS)
-
-/* This union is used within smbus_access routines */
-union smbus_data {
- u8 byte;
- u16 word;
- u8 block[32];
-};
-
-/* smbus_access read or write markers */
-#define SMBUS_READ 1
-#define SMBUS_WRITE 0
-
-/* SMBus transaction types (size parameter in the above functions)
- Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
-#define SMBUS_QUICK 0
-#define SMBUS_BYTE 1
-#define SMBUS_BYTE_DATA 2
-#define SMBUS_WORD_DATA 3
-#define SMBUS_PROC_CALL 4
-#define SMBUS_BLOCK_DATA 5
-
-/* Declare an algorithm structure. All SMBus derived adapters should use this
- algorithm! */
-extern struct smbus_algorithm smbus_algorithm;
-
-/* This is the very generalized SMBus access routine. You probably do not
- want to use this, though; one of the functions below may be much easier,
- and probably just as fast.
- Note that we use i2c_adapter here, because you do not need a specific
- smbus adapter to call this function. */
-extern s32 smbus_access (struct i2c_adapter * adapter, u8 addr,
- char read_write, u8 command, int size,
- union smbus_data * data);
-
-/* Now follow the 'nice' access routines. These also document the calling
- conventions of smbus_access. */
-
-extern inline s32 smbus_write_quick(struct i2c_adapter * adapter, u8 addr,
- u8 value)
-{
- return smbus_access(adapter,addr,value,0,SMBUS_QUICK,NULL);
-}
-
-extern inline s32 smbus_read_byte(struct i2c_adapter * adapter,u8 addr)
-{
- union smbus_data data;
- if (smbus_access(adapter,addr,SMBUS_READ,0,SMBUS_BYTE,&data))
- return -1;
- else
- return data.byte;
-}
-
-extern inline s32 smbus_write_byte(struct i2c_adapter * adapter, u8 addr,
- u8 value)
-{
- return smbus_access(adapter,addr,SMBUS_WRITE,value, SMBUS_BYTE,NULL);
-}
-
-extern inline s32 smbus_read_byte_data(struct i2c_adapter * adapter,
- u8 addr, u8 command)
-{
- union smbus_data data;
- if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_BYTE_DATA,&data))
- return -1;
- else
- return data.byte;
-}
-
-extern inline s32 smbus_write_byte_data(struct i2c_adapter * adapter,
- u8 addr, u8 command, u8 value)
-{
- union smbus_data data;
- data.byte = value;
- return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BYTE_DATA,&data);
-}
-
-extern inline s32 smbus_read_word_data(struct i2c_adapter * adapter,
- u8 addr, u8 command)
-{
- union smbus_data data;
- if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_WORD_DATA,&data))
- return -1;
- else
- return data.word;
-}
-
-extern inline s32 smbus_write_word_data(struct i2c_adapter * adapter,
- u8 addr, u8 command, u16 value)
-{
- union smbus_data data;
- data.word = value;
- return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_WORD_DATA,&data);
-}
-
-extern inline s32 smbus_process_call(struct i2c_adapter * adapter,
- u8 addr, u8 command, u16 value)
-{
- union smbus_data data;
- data.word = value;
- if (smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_PROC_CALL,&data))
- return -1;
- else
- return data.word;
-}
-
-/* Returns the number of read bytes */
-extern inline s32 smbus_read_block_data(struct i2c_adapter * adapter,
- u8 addr, u8 command, u8 *values)
-{
- union smbus_data data;
- int i;
- if (smbus_access(adapter,addr,SMBUS_READ,command,SMBUS_BLOCK_DATA,&data))
- return -1;
- else {
- for (i = 1; i <= data.block[0]; i++)
- values[i-1] = data.block[i];
- return data.block[0];
- }
-}
-
-extern inline int smbus_write_block_data(struct i2c_adapter * adapter,
- u8 addr, u8 command, u8 length,
- u8 *values)
-{
- union smbus_data data;
- int i;
- if (length > 32)
- length = 32;
- for (i = 1; i <= length; i++)
- data.block[i] = values[i-1];
- data.block[0] = length;
- return smbus_access(adapter,addr,SMBUS_WRITE,command,SMBUS_BLOCK_DATA,&data);
-}
-
-
-/* Next: define SMBus variants of registering. */
-
-#define smbus_add_algorithm(algoptr) \
- i2c_add_algorithm((struct i2c_algorithm *) (algoptr))
-#define smbus_del_algorithm(algoptr) \
- i2c_del_algorithm((struct i2c_algorithm *) (algoptr))
-
-#define smbus_add_adapter(adapptr) \
- i2c_add_adapter((struct i2c_adapter *) (adapptr))
-#define smbus_del_adapter(adapptr) \
- i2c_del_adapter((struct i2c_adapter *) (adapptr))
-
-#define smbus_add_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-#define smbus_del_driver(driverptr) \
- i2c_add_driver((struct i2c_driver *) (driverptr))
-
-#define smbus_attach_client(clientptr) \
- i2c_attach_client((struct i2c_client *) (clientptr))
-#define smbus_detach_client(clientptr) \
- i2c_detach_client((struct i2c_client *) (clientptr))
-
-
-#endif /* def __KERNEL__ */
-
-#endif /* ndef SENSORS_SMBUS_H */
-
diff --git a/kernel/sensors.c b/kernel/sensors.c
deleted file mode 100644
index 20aad3c4..00000000
--- a/kernel/sensors.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- sensors.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/malloc.h>
-#include <linux/ctype.h>
-#include <linux/sysctl.h>
-#include <linux/proc_fs.h>
-
-#include "version.h"
-#include "compat.h"
-#include "i2c.h"
-#include "isa.h"
-#include "sensors.h"
-
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-static int sensors_create_name(char **name, const char *prefix,
- struct i2c_adapter * adapter, int addr);
-static void sensors_parse_reals(int *nrels, void *buffer, int bufsize,
- long *results, int magnitude);
-static void sensors_write_reals(int nrels,void *buffer,int *bufsize,
- long *results, int magnitude);
-static int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp);
-static int sensors_sysctl_chips (ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp, void *newval,
- size_t newlen, void **context);
-
-static int sensors_init(void);
-static int sensors_cleanup(void);
-
-#define SENSORS_ENTRY_MAX 20
-static struct ctl_table_header *sensors_entries[SENSORS_ENTRY_MAX];
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
-static struct i2c_client *sensors_clients[SENSORS_ENTRY_MAX];
-static unsigned short sensors_inodes[SENSORS_ENTRY_MAX];
-static void sensors_fill_inode(struct inode *inode, int fill);
-static void sensors_dir_fill_inode(struct inode *inode, int fill);
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-
-static ctl_table sysctl_table[] = {
- { CTL_DEV, "dev", NULL, 0, 0555 },
- { 0 },
- { DEV_SENSORS, "sensors", NULL, 0, 0555 },
- { 0 },
- { 0, NULL, NULL, 0, 0555 },
- { 0 }
-};
-
-static ctl_table sensors_proc_dev_sensors[] = {
- { SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &sensors_proc_chips,
- &sensors_sysctl_chips },
- { 0 }
-};
-
-static ctl_table sensors_proc_dev[] = {
- { DEV_SENSORS, "sensors", NULL, 0, 0555, sensors_proc_dev_sensors },
- { 0 },
-};
-
-
-static ctl_table sensors_proc[] = {
- { CTL_DEV, "dev", NULL, 0, 0555, sensors_proc_dev },
- { 0 }
-};
-
-
-static struct ctl_table_header *sensors_proc_header;
-static int sensors_initialized;
-
-/* This returns a nice name for a new directory; for example lm78-isa-0310
- (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
- a LM75 chip on the third i2c bus at address 0x4e).
- name is allocated first. */
-int sensors_create_name(char **name, const char *prefix,
- struct i2c_adapter * adapter, int addr)
-{
- char name_buffer[50];
- int id;
- if (i2c_is_isa_adapter(adapter))
- sprintf(name_buffer,"%s-isa-%04x",prefix,addr);
- else {
- if ((id = i2c_adapter_id(adapter)) < 0)
- return -ENOENT;
- sprintf(name_buffer,"%s-i2c-%d-%02x",prefix,id,addr);
- }
- *name = kmalloc(strlen(name_buffer)+1,GFP_KERNEL);
- strcpy(*name,name_buffer);
- return 0;
-}
-
-/* This rather complex function must be called when you want to add an entry
- to /proc/sys/dev/sensors/chips (not yet implemented). It also creates
- a new directory within /proc/sys/dev/sensors/.
- ctl_template should be a template of the newly created directory. It is
- copied in memory. The extra2 field of each file is set to point to client.
- If any driver wants subdirectories within the newly created directory,
- this function must be updated! */
-int sensors_register_entry(struct i2c_client *client ,const char *prefix,
- ctl_table *ctl_template)
-{
- int i,res,len,id;
- ctl_table *new_table;
- char *name;
- struct ctl_table_header *new_header;
-
- if ((res = sensors_create_name(&name,prefix,client->adapter,
- i2c_is_isa_client(client)?
- ((struct isa_client *) client)->isa_addr:
- client->addr)))
- return res;
-
- for (id = 0; id < SENSORS_ENTRY_MAX; id++)
- if (! sensors_entries[id]) {
- break;
- }
- if (id == SENSORS_ENTRY_MAX) {
- kfree(name);
- return -ENOMEM;
- }
- id += 256;
-
- len = 0;
- while (ctl_template[len].procname)
- len++;
- len += 7;
- if (! (new_table = kmalloc(sizeof(ctl_table) * len,GFP_KERNEL))) {
- kfree(name);
- return -ENOMEM;
- }
-
- memcpy(new_table,sysctl_table,6 * sizeof(ctl_table));
- new_table[0].child = &new_table[2];
- new_table[2].child = &new_table[4];
- new_table[4].child = &new_table[6];
- new_table[4].procname = name;
- new_table[4].ctl_name = id;
- memcpy(new_table+6,ctl_template,(len-6) * sizeof(ctl_table));
- for (i = 6; i < len; i++)
- new_table[i].extra2 = client;
-
- if (! (new_header = register_sysctl_table(new_table,0))) {
- kfree(new_table);
- kfree(name);
- return -ENOMEM;
- }
-
- sensors_entries[id-256] = new_header;
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
- sensors_clients[id-256] = client;
-#ifdef DEBUG
- if (!new_header || !new_header->ctl_table ||
- !new_header->ctl_table->child ||
- !new_header->ctl_table->child->child ||
- !new_header->ctl_table->child->child->de) {
- printk("sensors.o: NULL pointer when trying to install fill_inode fix!\n");
- return id;
- }
-#endif /* DEBUG */
- sensors_inodes[id-256] = new_header->ctl_table->child->child->de->low_ino;
- new_header->ctl_table->child->child->de->fill_inode = &sensors_dir_fill_inode;
-#endif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
-
- return id;
-}
-
-void sensors_deregister_entry(int id)
-{
- ctl_table *table;
- id -= 256;
- if (sensors_entries[id]) {
- table = sensors_entries[id]->ctl_table;
- unregister_sysctl_table(sensors_entries[id]);
- kfree((void *) (table[4].procname));
- kfree(table);
- sensors_entries[id] = NULL;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
- sensors_clients[id] = NULL;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
- }
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
-/* Monitor access for /proc/sys/dev/sensors; make unloading sensors.o
- impossible if some process still uses it or some file in it */
-void sensors_fill_inode(struct inode *inode, int fill)
-{
- if (fill)
- MOD_INC_USE_COUNT;
- else
- MOD_DEC_USE_COUNT;
-}
-
-/* Monitor access for /proc/sys/dev/sensors/* directories; make unloading
- the corresponding module impossible if some process still uses it or
- some file in it */
-void sensors_dir_fill_inode(struct inode *inode, int fill)
-{
- int i;
- struct i2c_client *client;
-
-#ifdef DEBUG
- if (! inode) {
- printk("sensors.o: Warning: inode NULL in fill_inode()\n");
- return;
- }
-#endif /* def DEBUG */
-
- for (i = 0; i < SENSORS_ENTRY_MAX; i++)
- if (sensors_clients[i] && (sensors_inodes[i] == inode->i_ino))
- break;
-#ifdef DEBUG
- if (i == SENSORS_ENTRY_MAX) {
- printk("sensors.o: Warning: inode (%ld) not found in fill_inode()\n",
- inode->i_ino);
- return;
- }
-#endif /* def DEBUG */
- client = sensors_clients[i];
- if (fill)
- client->driver->inc_use(client);
- else
- client->driver->dec_use(client);
-}
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
-
-int sensors_proc_chips(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp)
-{
- char BUF[SENSORS_PREFIX_MAX + 30];
- int buflen,curbufsize,i;
- struct ctl_table *client_tbl;
-
- if (write)
- return 0;
-
- /* If buffer is size 0, or we try to read when not at the start, we
- return nothing. Note that I think writing when not at the start
- does not work either, but anyway, this is straight from the kernel
- sources. */
- if (!*lenp || (filp->f_pos && !write)) {
- *lenp = 0;
- return 0;
- }
- curbufsize = 0;
- for (i = 0; i < SENSORS_ENTRY_MAX; i ++)
- if (sensors_entries[i]) {
- client_tbl = sensors_entries[i]->ctl_table->child->child;
- buflen = sprintf(BUF,"%d\t%s\n",client_tbl->ctl_name,
- client_tbl->procname);
- if (buflen + curbufsize > *lenp)
- buflen=*lenp-curbufsize;
- copy_to_user(buffer,BUF,buflen);
- curbufsize += buflen;
- (char *) buffer += buflen;
- }
- *lenp = curbufsize;
- filp->f_pos += curbufsize;
- return 0;
-}
-
-int sensors_sysctl_chips (ctl_table *table, int *name, int nlen, void *oldval,
- size_t *oldlenp, void *newval, size_t newlen,
- void **context)
-{
- struct sensors_chips_data data;
- int i,oldlen,nrels,maxels;
- struct ctl_table *client_tbl;
-
- if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
- maxels = oldlen / sizeof(struct sensors_chips_data);
- nrels = 0;
- for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels); i++)
- if (sensors_entries[i]) {
- client_tbl = sensors_entries[i]->ctl_table->child->child;
- data.sysctl_id = client_tbl->ctl_name;
- strcpy(data.name,client_tbl->procname);
- copy_to_user(oldval,&data,sizeof(struct sensors_chips_data));
- (char *) oldval += sizeof(struct sensors_chips_data);
- nrels++;
- }
- oldlen = nrels * sizeof(struct sensors_chips_data);
- put_user(oldlen,oldlenp);
- }
- return 0;
-}
-
-
-/* This funcion reads or writes a 'real' value (encoded by the combination
- of an integer and a magnitude, the last is the power of ten the value
- should be divided with) to a /proc/sys directory. To use this function,
- you must (before registering the ctl_table) set the extra2 field to the
- client, and the extra1 field to a function of the form:
- void func(struct i2c_client *client, int operation, int ctl_name,
- int *nrels_mag, long *results)
- This function can be called for three values of operation. If operation
- equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in
- nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
- be read into results. nrels_mag should return the number of elements
- read; the maximum number is put in it on entry. Finally, if operation
- equals SENSORS_PROC_REAL_WRITE, the values in results should be
- written to the chip. nrels_mag contains on entry the number of elements
- found.
- In all cases, client points to the client we wish to interact with,
- and ctl_name is the SYSCTL id of the file we are accessing. */
-int sensors_proc_real(ctl_table *ctl, int write, struct file * filp,
- void *buffer, size_t *lenp)
-{
-#define MAX_RESULTS 20
- int mag,nrels=MAX_RESULTS;
- long results[MAX_RESULTS];
- sensors_real_callback callback = ctl -> extra1;
- struct i2c_client *client = ctl -> extra2;
-
- /* If buffer is size 0, or we try to read when not at the start, we
- return nothing. Note that I think writing when not at the start
- does not work either, but anyway, this is straight from the kernel
- sources. */
- if (!*lenp || (filp->f_pos && !write)) {
- *lenp = 0;
- return 0;
- }
-
- /* Get the magnitude */
- callback(client,SENSORS_PROC_REAL_INFO,ctl->ctl_name,&mag,NULL);
-
- if (write) {
- /* Read the complete input into results, converting to longs */
- sensors_parse_reals(&nrels,buffer,*lenp,results,mag);
-
- if (! nrels)
- return 0;
-
- /* Now feed this information back to the client */
- callback(client,SENSORS_PROC_REAL_WRITE,ctl->ctl_name,&nrels,results);
-
- filp->f_pos += *lenp;
- return 0;
- } else { /* read */
- /* Get the information from the client into results */
- callback(client,SENSORS_PROC_REAL_READ,ctl->ctl_name,&nrels,results);
-
- /* And write them to buffer, converting to reals */
- sensors_write_reals(nrels,buffer,lenp,results,mag);
- filp->f_pos += *lenp;
- return 0;
- }
-}
-
-/* This function is equivalent to sensors_proc_real, only it interacts with
- the sysctl(2) syscall, and returns no reals, but integers */
-int sensors_sysctl_real (ctl_table *table, int *name, int nlen, void *oldval,
- size_t *oldlenp, void *newval, size_t newlen,
- void **context)
-{
- long results[MAX_RESULTS];
- int oldlen,nrels=MAX_RESULTS;
- sensors_real_callback callback = table -> extra1;
- struct i2c_client *client = table -> extra2;
-
- /* Check if we need to output the old values */
- if (oldval && oldlenp && ! get_user_data(oldlen,oldlenp) && oldlen) {
- callback(client,SENSORS_PROC_REAL_READ,table->ctl_name,&nrels,results);
-
- /* Note the rounding factor! */
- if (nrels * sizeof(long) < oldlen)
- oldlen = nrels * sizeof(long);
- oldlen = (oldlen / sizeof(long)) * sizeof(long);
- copy_to_user(oldval,results,oldlen);
- put_user(oldlen,oldlenp);
- }
-
- if (newval && newlen) {
- /* Note the rounding factor! */
- newlen -= newlen % sizeof(long);
- nrels = newlen / sizeof(long);
- copy_from_user(results,newval,newlen);
-
- /* Get the new values back to the client */
- callback(client,SENSORS_PROC_REAL_WRITE,table->ctl_name,&nrels,results);
- }
- return 0;
-}
-
-
-/* nrels contains initially the maximum number of elements which can be
- put in results, and finally the number of elements actually put there.
- A magnitude of 1 will multiply everything with 10; etc.
- buffer, bufsize is the character buffer we read from and its length.
- results will finally contain the parsed integers.
-
- Buffer should contain several reals, separated by whitespace. A real
- has the following syntax:
- [ Minus ] Digit* [ Dot Digit* ]
- (everything between [] is optional; * means zero or more).
- When the next character is unparsable, everything is skipped until the
- next whitespace.
-
- WARNING! This is tricky code. I have tested it, but there may still be
- hidden bugs in it, even leading to crashes and things!
-*/
-void sensors_parse_reals(int *nrels, void *buffer, int bufsize,
- long *results, int magnitude)
-{
- int maxels,min,mag;
- long res;
- char nextchar=0;
-
- maxels = *nrels;
- *nrels = 0;
-
- while (bufsize && (*nrels < maxels)) {
-
- /* Skip spaces at the start */
- while (bufsize && ! get_user_data(nextchar,(char *) buffer) &&
- isspace((int) nextchar)) {
- bufsize --;
- ((char *) buffer)++;
- }
-
- /* Well, we may be done now */
- if (! bufsize)
- return;
-
- /* New defaults for our result */
- min = 0;
- res = 0;
- mag = magnitude;
-
- /* Check for a minus */
- if (! get_user_data(nextchar,(char *) buffer) && (nextchar == '-')) {
- min=1;
- bufsize--;
- ((char *) buffer)++;
- }
-
- /* Digits before a decimal dot */
- while (bufsize && !get_user_data(nextchar,(char *) buffer) &&
- isdigit((int) nextchar)) {
- res = res * 10 + nextchar - '0';
- bufsize--;
- ((char *) buffer)++;
- }
-
- /* If mag < 0, we must actually divide here! */
- while (mag < 0) {
- res = res / 10;
- mag++;
- }
-
- if (bufsize && (nextchar == '.')) {
- /* Skip the dot */
- bufsize--;
- ((char *) buffer)++;
-
- /* Read digits while they are significant */
- while(bufsize && (mag > 0) &&
- !get_user_data(nextchar,(char *) buffer) &&
- isdigit((int) nextchar)) {
- res = res * 10 + nextchar - '0';
- mag--;
- bufsize--;
- ((char *) buffer)++;
- }
- }
- /* If we are out of data, but mag > 0, we need to scale here */
- while (mag > 0) {
- res = res * 10;
- mag --;
- }
-
- /* Skip everything until we hit whitespace */
- while(bufsize && !get_user_data(nextchar,(char *) buffer) &&
- isspace ((int) nextchar)) {
- bufsize --;
- ((char *) buffer) ++;
- }
-
- /* Put res in results */
- results[*nrels] = (min?-1:1)*res;
- (*nrels)++;
- }
-
- /* Well, there may be more in the buffer, but we need no more data.
- Ignore anything that is left. */
- return;
-}
-
-void sensors_write_reals(int nrels,void *buffer,int *bufsize,long *results,
- int magnitude)
-{
- #define BUFLEN 20
- char BUF[BUFLEN+1]; /* An individual representation should fit in here! */
- char printfstr[10];
- int nr=0;
- int buflen,mag,times;
- int curbufsize=0;
-
- while ((nr < nrels) && (curbufsize < *bufsize)) {
- mag=magnitude;
-
- if (nr != 0) {
- put_user(' ', (char *) buffer);
- curbufsize ++;
- ((char *) buffer) ++;
- }
-
- /* Fill BUF with the representation of the next string */
- if (mag <= 0) {
-
- buflen=sprintf(BUF,"%ld",results[nr]);
- if (buflen < 0) { /* Oops, a sprintf error! */
- *bufsize=0;
- return;
- }
- while ((mag < 0) && (buflen < BUFLEN)) {
- BUF[buflen++]='0';
- mag++;
- }
- BUF[buflen]=0;
- } else {
- times=1;
- for (times=1; mag-- > 0; times *= 10);
- if (results[nr] < 0) {
- BUF[0] = '-';
- buflen = 1;
- } else
- buflen=0;
- strcpy(printfstr,"%ld.%0Xld");
- printfstr[6]=magnitude+'0';
- buflen+=sprintf(BUF+buflen,printfstr,abs(results[nr])/times,
- abs(results[nr])%times);
- if (buflen < 0) { /* Oops, a sprintf error! */
- *bufsize=0;
- return;
- }
- }
-
- /* Now copy it to the user-space buffer */
- if (buflen + curbufsize > *bufsize)
- buflen=*bufsize-curbufsize;
- copy_to_user(buffer,BUF,buflen);
- curbufsize += buflen;
- (char *) buffer += buflen;
-
- nr ++;
- }
- if (curbufsize < *bufsize) {
- put_user('\n', (char *) buffer);
- curbufsize ++;
- }
- *bufsize=curbufsize;
-}
-
-int sensors_init(void)
-{
- printk("sensors.o version %s (%s)\n",LM_VERSION,LM_DATE);
- sensors_initialized = 0;
- if (! (sensors_proc_header = register_sysctl_table(sensors_proc,0)))
- return -ENOMEM;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58))
- sensors_proc_header->ctl_table->child->de->fill_inode = &sensors_fill_inode;
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,58)) */
- sensors_initialized ++;
- return 0;
-}
-
-int sensors_cleanup(void)
-{
- if (sensors_initialized >= 1) {
- unregister_sysctl_table(sensors_proc_header);
- sensors_initialized --;
- }
- return 0;
-}
-
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("LM78 driver");
-
-int init_module(void)
-{
- return sensors_init();
-}
-
-int cleanup_module(void)
-{
- return sensors_cleanup();
-}
-
-#endif /* MODULE */
-
diff --git a/kernel/smbus.c b/kernel/smbus.c
deleted file mode 100644
index d61c2e94..00000000
--- a/kernel/smbus.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- smbus.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- Copyright (c) 1998 Frodo Looijaard <frodol@dds.nl>
-
- 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 <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-
-#include "i2c.h"
-#ifdef SPINLOCK
-#include <asm/spinlock.h>
-#else
-#include <asm/semaphore.h>
-#endif
-
-#include "version.h"
-#include "smbus.h"
-
-static s32 smbus_access_i2c (struct i2c_adapter * adapter, u8 addr,
- char read_write, u8 command, int size,
- union smbus_data * data);
-
-static int smbus_master_xfer (struct smbus_adapter *adap,
- struct i2c_msg msgs[], int num);
-static int smbus_slave_send (struct smbus_adapter *adap, char *data, int len);
-static int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len);
-static int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd,
- unsigned long arg);
-static int smbus_client_register (struct smbus_client *client);
-static int smbus_client_unregister (struct smbus_client *client);
-
-static int smbus_init(void);
-static int smbus_cleanup(void);
-
-#ifdef MODULE
-extern int init_module(void);
-extern int cleanup_module(void);
-#endif /* MODULE */
-
-/* This is the actual algorithm we define */
-struct smbus_algorithm smbus_algorithm = {
- /* name */ "Non-I2C SMBus adapter",
- /* id */ ALGO_SMBUS,
- /* master_xfer */ &smbus_master_xfer,
- /* slave_send */ &smbus_slave_send,
- /* slave_rcv */ &smbus_slave_recv,
- /* algo_control */ &smbus_algo_control,
- /* client_register */ &smbus_client_register,
- /* client_unregister*/&smbus_client_unregister
-};
-
-
-/* OK, so you want to access a bus using the SMBus protocols. Well, it either
- is registered as a SMBus-only adapter (like the PIIX4), or we need to
- simulate the SMBus commands using the i2c access routines.
- We do all locking here, so you can ignore that in the adapter-specific
- smbus_accesss routine. */
-s32 smbus_access (struct i2c_adapter * adapter, u8 addr, char read_write,
- u8 command, int size, union smbus_data * data)
-{
- int res;
- if ((adapter->id & ALGO_MASK) == ALGO_SMBUS) {
-#ifdef SPINLOCK
- spin_lock_irqsave(&adapter->lock,adapter->lockflags);
-#else
- down(&adapter->lock);
-#endif
- res = ((struct smbus_adapter *) adapter) ->
- smbus_access(addr,read_write,command,size,data);
-#ifdef SPINLOCK
- spin_unlock_irqrestore(&adapter->lock,adapter->lockflags);
-#else
- up(&adapter->lock);
-#endif
- } else
- res = smbus_access_i2c(adapter,addr,read_write,command,size,data);
- return res;
-}
-
-/* Simulate a SMBus command using the i2c protocol
- No checking of paramters is done! */
-s32 smbus_access_i2c(struct i2c_adapter * adapter, u8 addr, char read_write,
- u8 command, int size, union smbus_data * data)
-{
- /* So we need to generate a series of msgs. In the case of writing, we
- need to use only one message; when reading, we need two. We initialize
- most things with sane defaults, to keep the code below somewhat
- simpler. */
- char msgbuf0[33];
- char msgbuf1[33];
- int num = read_write == SMBUS_READ?2:1;
- struct i2c_msg msg[2] = { { addr, 0, 1, msgbuf0 },
- { addr, I2C_M_RD, 0, msgbuf1 }
- };
- int i;
-
- msgbuf0[0] = command;
- switch(size) {
- case SMBUS_QUICK:
- msg[0].len = 0;
- num = 1; /* Special case: The read/write field is used as data */
- break;
- case SMBUS_BYTE:
- if (read_write == SMBUS_READ)
- /* Special case: only a read! */
- msg[0].flags = I2C_M_RD;
- break;
- case SMBUS_BYTE_DATA:
- if (read_write == SMBUS_READ)
- msg[1].len = 1;
- else {
- msg[0].len = 2;
- msgbuf0[1] = data->byte;
- }
- break;
- case SMBUS_WORD_DATA:
- if (read_write == SMBUS_READ)
- msg[1].len = 2;
- else {
- msg[0].len=3;
- msgbuf0[1] = data->word & 0xff;
- msgbuf0[2] = (data->word >> 8) & 0xff;
- }
- break;
- case SMBUS_PROC_CALL:
- num = 2; /* Special case */
- msg[0].len = 3;
- msg[1].len = 2;
- msgbuf0[1] = data->word & 0xff;
- msgbuf0[2] = (data->word >> 8) & 0xff;
- break;
- case SMBUS_BLOCK_DATA:
- if (read_write == SMBUS_READ) {
- printk("smbus.o: Block read not supported under I2C emulation!\n");
- return -1;
- } else {
- msg[1].len = data->block[0] + 1;
- if (msg[1].len > 32) {
- printk("smbus.o: smbus_access called with invalid block write "
- "size (%d)\n",msg[1].len);
- return -1;
- }
- for (i = 1; i <= msg[1].len; i++)
- msgbuf0[i] = data->block[1];
- }
- break;
- default:
- printk("smbus.o: smbus_access called with invalid size (%d)\n",size);
- return -1;
- }
-
- if (i2c_transfer(adapter, msg, num) < 0)
- return -1;
-
- if(read_write == SMBUS_READ)
- switch(size) {
- case SMBUS_BYTE:
- data->byte = msgbuf0[0];
- break;
- case SMBUS_BYTE_DATA:
- data->byte = msgbuf1[0];
- break;
- case SMBUS_WORD_DATA:
- case SMBUS_PROC_CALL:
- data->word = msgbuf1[0] + (msgbuf1[1] << 8);
- break;
- }
- return 0;
-}
-
-/* Algorithm master_xfer call-back implementation. Can't do that... */
-int smbus_master_xfer (struct smbus_adapter *adap, struct i2c_msg msgs[],
- int num)
-{
-#ifdef DEBUG
- printk("smbus.o: smbus_master_xfer called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Algorithm slave_send call-back implementation. Can't do that... */
-int smbus_slave_send (struct smbus_adapter *adap, char *data, int len)
-{
-#ifdef DEBUG
- printk("smbus.o: smbus_slave_send called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Algorithm slave_recv call-back implementation. Can't do that... */
-int smbus_slave_recv (struct smbus_adapter *adap, char *data, int len)
-{
-#ifdef DEBUG
- printk("smbus.o: smbus_slave_recv called for adapter `%s' "
- "(no i2c level access possible!)\n",
- adap->name);
-#endif
- return -1;
-}
-
-/* Here we can put additional calls to modify the workings of the algorithm.
- But right now, there is no need for that. */
-int smbus_algo_control (struct smbus_adapter *adap, unsigned int cmd,
- unsigned long arg)
-{
- return 0;
-}
-
-/* Ehm... This is called when a client is registered to an adapter. We could
- do all kinds of neat stuff here like, ehm - returning success? */
-int smbus_client_register (struct smbus_client *client)
-{
- return 0;
-}
-
-int smbus_client_unregister (struct smbus_client *client)
-{
- return 0;
-}
-
-int smbus_init(void)
-{
- int res;
- printk("smbus.o version %s (%s)\n",LM_VERSION,LM_DATE);
- if ((res = smbus_add_algorithm(&smbus_algorithm)))
- printk("smbus.o: Algorithm registration failed, module not inserted.\n");
- else
- printk("smbus.o initialized\n");
- return res;
-}
-
-int smbus_cleanup(void)
-{
- int res;
- if ((res = smbus_del_algorithm(&smbus_algorithm)))
- printk("smbus.o: Algorithm deregistration failed, module not removed\n");
- return res;
-}
-
-/* OK, this will for now _only_ compile as a module, but this is neat for
- later, if we want to compile it straight into the kernel */
-#ifdef MODULE
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
-MODULE_DESCRIPTION("System Management Bus (SMBus) access");
-
-int init_module(void)
-{
- return smbus_init();
-}
-
-int cleanup_module(void)
-{
- return smbus_cleanup();
-}
-
-#endif /* MODULE */