From cb3131905c15dd20ed60e2ec20be4d0e3cded498 Mon Sep 17 00:00:00 2001 From: Frodo Looijaard Date: Sun, 11 Apr 1999 16:12:36 +0000 Subject: [PATCH] Major SIS5595 overhaul * sis5595.c now understand insmod parameters * sis5595.c now uses sis5595_ prefix instead of lm78_ prefix * sis5595.c now supports the correct subset of the LM78 features (it only knows about 4 voltages, 2 fans and no vid) * added SIS5595 defines to sensors.h * fixed a small problem in compat.h git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@379 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/chips/sis5595.c | 766 ++++++++++++++++++--------------------- kernel/include/compat.h | 16 +- kernel/include/sensors.h | 18 + 3 files changed, 383 insertions(+), 417 deletions(-) diff --git a/kernel/chips/sis5595.c b/kernel/chips/sis5595.c index 839710c4..1fb935df 100644 --- a/kernel/chips/sis5595.c +++ b/kernel/chips/sis5595.c @@ -39,41 +39,49 @@ #include "i2c.h" #include "compat.h" +/* Addresses to scan. + Note that we can't determine the ISA address until we have initialized + our module */ +static unsigned short normal_i2c[] = {SENSORS_I2C_END}; +static unsigned short normal_i2c_range[] = {SENSORS_I2C_END}; +static unsigned int normal_isa[] = {0x0000,SENSORS_ISA_END}; +static unsigned int normal_isa_range[] = {SENSORS_ISA_END}; + +/* Insmod parameters */ +SENSORS_INSMOD_1(sis5595); + /* - SiS southbridge has lm78 integrated on the same IC, - This drives is a customized copy of lm78.c + SiS southbridge has a LM78-like chip integrated on the same IC. + This driver is a customized copy of lm78.c */ -/* Many LM78 constants specified below */ +/* Many SIS5595 constants specified below */ /* Length of ISA address segment */ -#define LM78_EXTENT 8 -#define LM78_BASE_REG 0x68 +#define SIS5595_EXTENT 8 +#define SIS5595_BASE_REG 0x68 /* Where are the ISA address/data registers relative to the base address */ -#define LM78_ADDR_REG_OFFSET 5 -#define LM78_DATA_REG_OFFSET 6 +#define SIS5595_ADDR_REG_OFFSET 5 +#define SIS5595_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)) +/* The SIS5595 registers */ +#define SIS5595_REG_IN_MAX(nr) (0x2b + (nr) * 2) +#define SIS5595_REG_IN_MIN(nr) (0x2c + (nr) * 2) +#define SIS5595_REG_IN(nr) (0x20 + (nr)) -#define LM78_REG_FAN_MIN(nr) (0x3a + (nr)) -#define LM78_REG_FAN(nr) (0x27 + (nr)) +#define SIS5595_REG_FAN_MIN(nr) (0x3a + (nr)) +#define SIS5595_REG_FAN(nr) (0x27 + (nr)) -#define LM78_REG_TEMP 0x27 -#define LM78_REG_TEMP_OVER 0x39 -#define LM78_REG_TEMP_HYST 0x3a +#define SIS5595_REG_TEMP 0x27 +#define SIS5595_REG_TEMP_OVER 0x39 +#define SIS5595_REG_TEMP_HYST 0x3a -#define LM78_REG_ALARM1 0x41 -/* Not available in SiS 5595 -#define LM78_REG_ALARM2 0x42 -*/ +#define SIS5595_REG_ALARM1 0x41 -#define LM78_REG_VID_FANDIV 0x47 +#define SIS5595_REG_FANDIV 0x47 -#define LM78_REG_CONFIG 0x40 +#define SIS5595_REG_CONFIG 0x40 /* Conversions. Rounding is only done on the TO_REG variants. */ #define IN_TO_REG(val) (((val) * 10 + 8)/16) @@ -97,60 +105,42 @@ FAN_TO_REG (unsigned rpm, unsigned divisor) #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) + specified in the SIS5595 sheet. Use the config file to set better limits. */ +#define SIS5595_INIT_IN_0 (((1200) * 10)/38) +#define SIS5595_INIT_IN_1 (((500) * 100)/168) +#define SIS5595_INIT_IN_2 330 +#define SIS5595_INIT_IN_3 250 -#define LM78_INIT_IN_PERCENTAGE 10 +#define SIS5595_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 SIS5595_INIT_IN_MIN_0 \ + (SIS5595_INIT_IN_0 - SIS5595_INIT_IN_0 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MAX_0 \ + (SIS5595_INIT_IN_0 + SIS5595_INIT_IN_0 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MIN_1 \ + (SIS5595_INIT_IN_1 - SIS5595_INIT_IN_1 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MAX_1 \ + (SIS5595_INIT_IN_1 + SIS5595_INIT_IN_1 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MIN_2 \ + (SIS5595_INIT_IN_2 - SIS5595_INIT_IN_2 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MAX_2 \ + (SIS5595_INIT_IN_2 + SIS5595_INIT_IN_2 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MIN_3 \ + (SIS5595_INIT_IN_3 - SIS5595_INIT_IN_3 * SIS5595_INIT_IN_PERCENTAGE / 100) +#define SIS5595_INIT_IN_MAX_3 \ + (SIS5595_INIT_IN_3 + SIS5595_INIT_IN_3 * SIS5595_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 SIS5595_INIT_FAN_MIN_1 3000 +#define SIS5595_INIT_FAN_MIN_2 3000 -#define LM78_INIT_TEMP_OVER 600 -#define LM78_INIT_TEMP_HYST 500 +#define SIS5595_INIT_TEMP_OVER 600 +#define SIS5595_INIT_TEMP_HYST 500 #ifdef MODULE extern int init_module(void); @@ -161,341 +151,327 @@ extern int cleanup_module(void); bad. Quite a lot of bookkeeping is done. A real driver can often cut some corners. */ -/* Types of chips supported */ -enum lm78_type { lm78 }; - -/* 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 +/* For each registered SIS5595, we need to keep some data in memory. That + data is pointed to by sis5595_list[NR]->data. The structure itself is + dynamically allocated, at the same time when a new sis5595 client is allocated. */ -struct lm78_data { +struct sis5595_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 in[4]; /* Register value */ + u8 in_max[4]; /* Register value */ + u8 in_min[4]; /* Register value */ + u8 fan[2]; /* Register value */ + u8 fan_min[2]; /* 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 */ + u8 fan_div[2]; /* Register encoding, shifted right */ + u8 alarms; /* Register encoding, combined */ }; -static int lm78_init(void); -static int lm78_cleanup(void); +static int sis5595_init(void); +static int sis5595_cleanup(void); -static int lm78_attach_adapter(struct i2c_adapter *adapter); -static int lm78_detect_isa(struct isa_adapter *adapter); -static int lm78_detach_client(struct i2c_client *client); -static int lm78_detach_isa(struct isa_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, +static int sis5595_attach_adapter(struct i2c_adapter *adapter); +static int sis5595_detect(struct i2c_adapter *adapter, int address, int kind); +static int sis5595_detach_client(struct i2c_client *client); +static int sis5595_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 void sis5595_inc_use (struct i2c_client *client); +static void sis5595_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 int sis5595_read_value(struct i2c_client *client, u8 register); +static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value); +static void sis5595_update_client(struct i2c_client *client); +static void sis5595_init_client(struct i2c_client *client); +static int sis5595_find_sis(int *address); -static void lm78_in(struct i2c_client *client, int operation, int ctl_name, +static void sis5595_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, +static void sis5595_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, +static void sis5595_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, +static void sis5595_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, +static void sis5595_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 +/* I choose here for semi-static SIS5595 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]; +#define MAX_SIS5595_NR 4 +static struct i2c_client *sis5595_list[MAX_SIS5595_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 = { +static struct i2c_driver sis5595_driver = { /* name */ "SiS 5595", /* id */ I2C_DRIVERID_SIS5595, /* 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 + /* attach_adapter */ &sis5595_attach_adapter, + /* detach_client */ &sis5595_detach_client, + /* command */ &sis5595_command, + /* inc_use */ &sis5595_inc_use, + /* dec_use */ &sis5595_dec_use }; -/* Used by lm78_init/cleanup */ -static int lm78_initialized = 0; +/* Used by sis5595_init/cleanup */ +static int sis5595_initialized = 0; /* The /proc/sys entries */ -/* These files are created for each detected LM78. This is just a template; +/* These files are created for each detected SIS5595. 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, 0444, 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, 0444, NULL, &sensors_proc_real, - &sensors_sysctl_real, NULL, &lm78_alarms }, +static ctl_table sis5595_dir_table_template[] = { + { SIS5595_SYSCTL_IN0, "in0", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_in }, + { SIS5595_SYSCTL_IN1, "in1", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_in }, + { SIS5595_SYSCTL_IN2, "in2", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_in }, + { SIS5595_SYSCTL_IN3, "in3", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_in }, + { SIS5595_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_fan }, + { SIS5595_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_fan }, + { SIS5595_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_temp }, + { SIS5595_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_fan_div }, + { SIS5595_SYSCTL_ALARMS, "alarms", NULL, 0, 0444, NULL, &sensors_proc_real, + &sensors_sysctl_real, NULL, &sis5595_alarms }, { 0 } }; /* This is called when the module is loaded */ -int lm78_attach_adapter(struct i2c_adapter *adapter) +int sis5595_attach_adapter(struct i2c_adapter *adapter) { - return lm78_detect_isa((struct isa_adapter *) adapter); + return sensors_detect(adapter,&addr_data,sis5595_detect); } -/* This is called when the module is loaded */ -int lm78_detach_client(struct i2c_client *client) -{ - return lm78_detach_isa((struct isa_client *) client); -} - -/* Locate SiS bridge and correct base address for LM78 */ -#if LINUX_VERSION_CODE >= 0x020136 /* 2.1.54 */ -static int find_sis(int *address) +/* Locate SiS bridge and correct base address for SIS5595 */ +int sis5595_find_sis(int *address) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54)) struct pci_dev *s_bridge; +#else + unsigned char SIS_bus, SIS_devfn; +#endif u16 val; if (! pci_present()) return -ENODEV; - s_bridge = pci_find_device( - PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, NULL); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,54)) + if (! (s_bridge = pci_find_device( + PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, NULL))); - if (! s_bridge) - return -ENODEV; - - if ( PCIBIOS_SUCCESSFUL != - pci_read_config_word(s_bridge, LM78_BASE_REG, &val)) - return -ENODEV; - - *address = (val & 0xfff8); - return 0; -} - #else + if(pcibios_find_device( + PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, 0, + &SIS_bus, &SIS_devfn)) +#endif + return -ENODEV; -static int find_sis(int *address) -{ - unsigned char SIS_bus, SIS_devfn; - u16 val; - - if (! pcibios_present()) + + if ( PCIBIOS_SUCCESSFUL != + pci_read_config_word_united(s_bridge, SIS_bus, SIS_devfn, + SIS5595_BASE_REG, &val)) return -ENODEV; - if(pcibios_find_device( - PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, 0, - &SIS_bus, &SIS_devfn)) - return -ENODEV; - - if ( PCIBIOS_SUCCESSFUL != - pcibios_read_config_word(SIS_bus, SIS_devfn, LM78_BASE_REG, &val)) - return -ENODEV; - *address = (val & 0xfff8); return 0; } + +int sis5595_detect(struct i2c_adapter *adapter, int address, int kind) +{ + int i; + struct i2c_client *new_client; + struct sis5595_data *data; + int err=0; + const char *type_name = ""; + const char *client_name = ""; + + /* Make sure we are probing the ISA bus!! This is just a safety check + at this moment; sensors_detect really won't call us for I2C busses. */ +#ifdef DEBUG + if (!i2c_is_isa_adapter(adapter)) { + printk("sis5595.o: sis5595_detect called for an I2C bus adapter?!?\n"); + return 0; + } #endif + if (check_region(address,SIS5595_EXTENT)) + goto ERROR0; -/* Register and initialize lm78 it. */ -int lm78_detect_isa(struct isa_adapter *adapter) -{ - int address = 0, err = 0; - struct isa_client *new_client; - enum lm78_type type; - const char *type_name; - const char *client_name; + /* If this is the address as indicated by the SIS5595 chipset, we don't + do any futher probing */ + if ((kind < 0) && (address == normal_isa[0])) + kind = 0; - /* OK, this is detection. */ + /* Probe whether there is anything available on this address. */ + if (kind < 0) { +#define REALLY_SLOW_IO + /* We need the timeouts for at least some LM78-like chips. But only + if we read 'undefined' registers. */ + i = inb_p(address + 1); + if (inb_p(address + 2) != i) + goto ERROR0; + if (inb_p(address + 3) != i) + goto ERROR0; + if (inb_p(address + 7) != i) + goto ERROR0; +#undef REALLY_SLOW_IO - if ((err=find_sis(&address))) { - printk("SiS 5595 southbridge not found\n"); - return err; - } - - if ( (err = check_region(address, LM78_EXTENT)) < 0 ) - { - printk("sis5595.o: IO 0x%x-0x%x already in use\n", - address, address + LM78_EXTENT); - return err; + /* Let's just hope nothing breaks here */ + i = inb_p(address + 5) & 0x7f; + outb_p(~i & 0x7f,address+5); + if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { + outb_p(i,address+5); + return 0; + } } -/* - printk("sis5595.o: lm78 io base at 0x%4x\n", address); -*/ - type = lm78; - type_name = "sis5595"; - client_name = "SiS 5595 Sensor"; - request_region(address, LM78_EXTENT, type_name); + /* OK. For now, we presume we have a valid client. We now create the + client structure, even though we cannot fill it completely yet. + But it allows us to access sis5595_{read,write}_value. */ - /* 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; - } + if (! (new_client = kmalloc(sizeof(struct isa_client) + + sizeof(struct sis5595_data), + GFP_KERNEL))) { + err = -ENOMEM; + goto ERROR0; + } - /* Fill the new client structure with data */ - new_client->data = (struct lm78_data *) (new_client + 1); + data = (struct sis5595_data *) (((struct isa_client *) new_client) + 1); new_client->addr = 0; + ((struct isa_client *) new_client)->isa_addr = address; + data->lock = MUTEX; + new_client->data = data; + new_client->adapter = adapter; + new_client->driver = &sis5595_driver; + + /* Now, we do the remaining detection. */ + + if (kind < 0) { + if (sis5595_read_value(new_client,SIS5595_REG_CONFIG) & 0x80) + goto ERROR1; + } + + /* Determine the chip type. */ + if (kind <= 0) + kind = sis5595; + + if (kind == sis5595) { + type_name = "sis5595"; + client_name = "SIS5595 chip"; + } else { +#ifdef DEBUG + printk("sis5595.o: Internal error: unknown kind (%d)?!?",kind); +#endif + goto ERROR1; + } + + /* Reserve the ISA region */ + request_region(address, SIS5595_EXTENT, type_name); + + /* Fill in the remaining client fields and put it into the global list */ 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))) + + for(i = 0; i < MAX_SIS5595_NR; i++) + if (! sis5595_list[i]) + break; + if (i == MAX_SIS5595_NR) { + printk("sis5595.o: No empty slots left, recompile and heighten " + "MAX_SIS5595_NR!\n"); + err = -ENOMEM; goto ERROR2; + } + sis5595_list[i] = new_client; + new_client->id = i; + data->valid = 0; + data->update_lock = MUTEX; - /* Tell i2c-core a new client has arrived */ - if ((err = isa_attach_client(new_client))) + /* Tell the I2C layer 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((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); - return err; + /* Register a new directory entry with module sensors */ + if ((i = sensors_register_entry((struct i2c_client *) new_client, + type_name, + sis5595_dir_table_template)) < 0) { + err = i; + goto ERROR4; + } + data->sysctl_id = i; + + /* Initialize the SIS5595 chip */ + sis5595_init_client(new_client); + return 0; /* OK, this is not exactly good programming practice, usually. But it is very code-efficient in this case. */ ERROR4: - isa_detach_client(new_client); + i2c_detach_client(new_client); ERROR3: - lm78_remove_client((struct i2c_client *) new_client); + for (i = 0; i < MAX_SIS5595_NR; i++) + if (new_client == sis5595_list[i]) + sis5595_list[i] = NULL; ERROR2: - kfree(new_client); + release_region(address,SIS5595_EXTENT); ERROR1: - release_region(address, LM78_EXTENT); - + kfree(new_client); +ERROR0: return err; } -/* Deregister and remove a LM78 client */ -int lm78_detach_isa(struct isa_client *client) +int sis5595_detach_client(struct i2c_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("sis5595.o: Client to detach not found.\n"); - return -ENOENT; - } - sensors_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id); + sensors_deregister_entry(((struct sis5595_data *)(client->data))->sysctl_id); - if ((err = isa_detach_client(client))) { + if ((err = i2c_detach_client(client))) { printk("sis5595.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; -} -/* 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]) + for (i = 0; i < MAX_SIS5595_NR; i++) + if (client == sis5595_list[i]) break; - if (i == MAX_LM78_NR) { - printk("sis5595.o: No empty slots left, recompile and heighten " - "MAX_LM78_NR!\n"); - return -ENOMEM; + if ((i == MAX_SIS5595_NR)) { + printk("sis5595.o: Client to detach not found.\n"); + return -ENOENT; } - - 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; -} + sis5595_list[i] = NULL; -/* 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; + release_region(((struct isa_client *)client)->isa_addr,SIS5595_EXTENT); + kfree(client); + + return 0; } /* No commands defined yet */ -int lm78_command(struct i2c_client *client, unsigned int cmd, void *arg) +int sis5595_command(struct i2c_client *client, unsigned int cmd, void *arg) { return 0; } /* Nothing here yet */ -void lm78_inc_use (struct i2c_client *client) +void sis5595_inc_use (struct i2c_client *client) { #ifdef MODULE MOD_INC_USE_COUNT; @@ -503,7 +479,7 @@ void lm78_inc_use (struct i2c_client *client) } /* Nothing here yet */ -void lm78_dec_use (struct i2c_client *client) +void sis5595_dec_use (struct i2c_client *client) { #ifdef MODULE MOD_DEC_USE_COUNT; @@ -514,76 +490,63 @@ void lm78_dec_use (struct i2c_client *client) /* The SMBus locks itself, but ISA access must be locked explicitely! 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 sis5595_read_value(struct i2c_client *client, u8 reg) { int res; down((struct semaphore *) (client->data)); + down(& (((struct sis5595_data *) (client->data)) -> lock)); outb_p(reg,(((struct isa_client *) client)->isa_addr) + - LM78_ADDR_REG_OFFSET); + SIS5595_ADDR_REG_OFFSET); res = inb_p((((struct isa_client *) client)->isa_addr) + - LM78_DATA_REG_OFFSET); - up((struct semaphore *) (client->data)); + SIS5595_DATA_REG_OFFSET); + up( & (((struct sis5595_data *) (client->data)) -> lock)); return res; } /* The SMBus locks itself, but ISA access muse be locked explicitely! 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) +int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value) { - 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)); + down(& (((struct sis5595_data *) (client->data)) -> lock)); + outb_p(reg,((struct isa_client *) client)->isa_addr + SIS5595_ADDR_REG_OFFSET); + outb_p(value,((struct isa_client *) client)->isa_addr + SIS5595_DATA_REG_OFFSET); + up( & (((struct sis5595_data *) (client->data)) -> lock)); return 0; } -/* Called when we have found a new LM78. It should set limits, etc. */ -void lm78_init_client(struct i2c_client *client) +/* Called when we have found a new SIS5595. It should set limits, etc. */ +void sis5595_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); + sis5595_write_value(client,SIS5595_REG_CONFIG,0x80); - vid = lm78_read_value(client,LM78_REG_VID_FANDIV) & 0x0f; - 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)); + sis5595_write_value(client,SIS5595_REG_IN_MIN(0),IN_TO_REG(SIS5595_INIT_IN_MIN_0)); + sis5595_write_value(client,SIS5595_REG_IN_MAX(0),IN_TO_REG(SIS5595_INIT_IN_MAX_0)); + sis5595_write_value(client,SIS5595_REG_IN_MIN(1),IN_TO_REG(SIS5595_INIT_IN_MIN_1)); + sis5595_write_value(client,SIS5595_REG_IN_MAX(1),IN_TO_REG(SIS5595_INIT_IN_MAX_1)); + sis5595_write_value(client,SIS5595_REG_IN_MIN(2),IN_TO_REG(SIS5595_INIT_IN_MIN_2)); + sis5595_write_value(client,SIS5595_REG_IN_MAX(2),IN_TO_REG(SIS5595_INIT_IN_MAX_2)); + sis5595_write_value(client,SIS5595_REG_IN_MIN(3),IN_TO_REG(SIS5595_INIT_IN_MIN_3)); + sis5595_write_value(client,SIS5595_REG_IN_MAX(3),IN_TO_REG(SIS5595_INIT_IN_MAX_3)); + sis5595_write_value(client,SIS5595_REG_FAN_MIN(1), + FAN_TO_REG(SIS5595_INIT_FAN_MIN_1,2)); + sis5595_write_value(client,SIS5595_REG_FAN_MIN(2), + FAN_TO_REG(SIS5595_INIT_FAN_MIN_2,2)); + sis5595_write_value(client,SIS5595_REG_TEMP_OVER,TEMP_TO_REG(SIS5595_INIT_TEMP_OVER)); + sis5595_write_value(client,SIS5595_REG_TEMP_HYST,TEMP_TO_REG(SIS5595_INIT_TEMP_HYST)); /* Start monitoring */ - lm78_write_value(client,LM78_REG_CONFIG, - (lm78_read_value(client,LM78_REG_CONFIG) & 0xf7) | 0x01); + sis5595_write_value(client,SIS5595_REG_CONFIG, + (sis5595_read_value(client,SIS5595_REG_CONFIG) & 0xf7) | 0x01); } -void lm78_update_client(struct i2c_client *client) +void sis5595_update_client(struct i2c_client *client) { - struct lm78_data *data = client->data; + struct sis5595_data *data = client->data; int i; down(&data->update_lock); @@ -592,33 +555,26 @@ void lm78_update_client(struct i2c_client *client) (jiffies < data->last_updated) || ! data->valid) { #ifdef DEBUG - printk("Starting lm78 update\n"); + printk("Starting sis5595 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 = 0; i <= 3; i++) { + data->in[i] = sis5595_read_value(client,SIS5595_REG_IN(i)); + data->in_min[i] = sis5595_read_value(client,SIS5595_REG_IN_MIN(i)); + data->in_max[i] = sis5595_read_value(client,SIS5595_REG_IN_MAX(i)); } - for (i = 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)); + for (i = 1; i <= 2; i++) { + data->fan[i-1] = sis5595_read_value(client,SIS5595_REG_FAN(i)); + data->fan_min[i-1] = sis5595_read_value(client,SIS5595_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; - data->vid |= 0x10; + data->temp = sis5595_read_value(client,SIS5595_REG_TEMP); + data->temp_over = sis5595_read_value(client,SIS5595_REG_TEMP_OVER); + data->temp_hyst = sis5595_read_value(client,SIS5595_REG_TEMP_HYST); + i = sis5595_read_value(client,SIS5595_REG_FANDIV); data->fan_div[0] = (i >> 4) & 0x03; data->fan_div[1] = i >> 6; - data->alarms = lm78_read_value(client,LM78_REG_ALARM1); -/* Not available in SiS 5595 - + (lm78_read_value(client,LM78_REG_ALARM2) << 8); -*/ + data->alarms = sis5595_read_value(client,SIS5595_REG_ALARM1); data->last_updated = jiffies; data->valid = 1; - - data->fan_div[2] = 1; } up(&data->update_lock); @@ -638,16 +594,16 @@ void lm78_update_client(struct i2c_client *client) 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, +void sis5595_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; + struct sis5595_data *data = client->data; + int nr = ctl_name - SIS5595_SYSCTL_IN0; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 2; else if (operation == SENSORS_PROC_REAL_READ) { - lm78_update_client(client); + sis5595_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]); @@ -655,25 +611,25 @@ void lm78_in(struct i2c_client *client, int operation, int ctl_name, } 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]); + sis5595_write_value(client,SIS5595_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]); + sis5595_write_value(client,SIS5595_REG_IN_MAX(nr),data->in_max[nr]); } } } -void lm78_fan(struct i2c_client *client, int operation, int ctl_name, +void sis5595_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; + struct sis5595_data *data = client->data; + int nr = ctl_name - SIS5595_SYSCTL_FAN1 + 1; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 0; else if (operation == SENSORS_PROC_REAL_READ) { - lm78_update_client(client); + sis5595_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], @@ -683,20 +639,20 @@ void lm78_fan(struct i2c_client *client, int operation, int ctl_name, 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]); + sis5595_write_value(client,SIS5595_REG_FAN_MIN(nr),data->fan_min[nr-1]); } } } -void lm78_temp(struct i2c_client *client, int operation, int ctl_name, +void sis5595_temp(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { - struct lm78_data *data = client->data; + struct sis5595_data *data = client->data; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 1; else if (operation == SENSORS_PROC_REAL_READ) { - lm78_update_client(client); + sis5595_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); @@ -704,57 +660,43 @@ void lm78_temp(struct i2c_client *client, int operation, int ctl_name, } 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); + sis5595_write_value(client,SIS5595_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); + sis5595_write_value(client,SIS5595_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, +void sis5595_alarms(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { - struct lm78_data *data = client->data; + struct sis5595_data *data = client->data; if (operation == SENSORS_PROC_REAL_INFO) *nrels_mag = 0; else if (operation == SENSORS_PROC_REAL_READ) { - lm78_update_client(client); + sis5595_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, +void sis5595_fan_div(struct i2c_client *client, int operation, int ctl_name, int *nrels_mag, long *results) { - struct lm78_data *data = client->data; + struct sis5595_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); + sis5595_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; + *nrels_mag = 2; } else if (operation == SENSORS_PROC_REAL_WRITE) { - old = lm78_read_value(client,LM78_REG_VID_FANDIV); + old = sis5595_read_value(client,SIS5595_REG_FANDIV); if (*nrels_mag >= 2) { data->fan_div[1] = DIV_TO_REG(results[1]); old = (old & 0x3f) | (data->fan_div[1] << 6); @@ -762,37 +704,43 @@ void lm78_fan_div(struct i2c_client *client, int operation, int ctl_name, 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); + sis5595_write_value(client,SIS5595_REG_FANDIV,old); } } } -int lm78_init(void) +int sis5595_init(void) { - int res; + int res,addr; printk("sis5595.o version %s (%s)\n",LM_VERSION,LM_DATE); - lm78_initialized = 0; + sis5595_initialized = 0; - if ((res =i2c_add_driver(&lm78_driver))) { + if (sis5595_find_sis(&addr)) { + normal_isa[0] = SENSORS_ISA_END; + printk("sis5595.o: Warning: No SIS5595 southbridge found!\n"); + } else + normal_isa[0] = addr; + + if ((res =i2c_add_driver(&sis5595_driver))) { printk("sis5595.o: Driver registration failed, module not inserted.\n"); - lm78_cleanup(); + sis5595_cleanup(); return res; } - lm78_initialized ++; + sis5595_initialized ++; return 0; } -int lm78_cleanup(void) +int sis5595_cleanup(void) { int res; - if (lm78_initialized >= 1) { - if ((res = i2c_del_driver(&lm78_driver))) { + if (sis5595_initialized >= 1) { + if ((res = i2c_del_driver(&sis5595_driver))) { printk("sis5595.o: Driver deregistration failed, module not removed.\n"); return res; } - lm78_initialized --; + sis5595_initialized --; } return 0; } @@ -805,12 +753,12 @@ MODULE_DESCRIPTION("SiS 5595 Sensor device"); int init_module(void) { - return lm78_init(); + return sis5595_init(); } int cleanup_module(void) { - return lm78_cleanup(); + return sis5595_cleanup(); } #endif /* MODULE */ diff --git a/kernel/include/compat.h b/kernel/include/compat.h index 3d5673cd..1ac33670 100644 --- a/kernel/include/compat.h +++ b/kernel/include/compat.h @@ -63,22 +63,22 @@ #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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + pci_write_config_byte(device,com,res) #endif diff --git a/kernel/include/sensors.h b/kernel/include/sensors.h index 86d0e43a..516cf906 100644 --- a/kernel/include/sensors.h +++ b/kernel/include/sensors.h @@ -501,6 +501,24 @@ struct sensors_chips_data { #define MAXI_ALARM_FAN2 0x2000 #define MAXI_ALARM_FAN3 0x4000 +#define SIS5595_SYSCTL_IN0 1000 /* Volts * 100 */ +#define SIS5595_SYSCTL_IN1 1001 +#define SIS5595_SYSCTL_IN2 1002 +#define SIS5595_SYSCTL_IN3 1003 +#define SIS5595_SYSCTL_FAN1 1101 /* Rotations/min */ +#define SIS5595_SYSCTL_FAN2 1102 +#define SIS5595_SYSCTL_TEMP 1200 /* Degrees Celcius * 10 */ +#define SIS5595_SYSCTL_FAN_DIV 2000 /* 1, 2, 4 or 8 */ +#define SIS5595_SYSCTL_ALARMS 2001 /* bitvector */ + +#define SIS5595_ALARM_IN0 0x01 +#define SIS5595_ALARM_IN1 0x02 +#define SIS5595_ALARM_IN2 0x04 +#define SIS5595_ALARM_IN3 0x08 +#define SIS5595_ALARM_TEMP 0x10 +#define SIS5595_ALARM_BTI 0x20 +#define SIS5595_ALARM_FAN1 0x40 +#define SIS5595_ALARM_FAN2 0x80 #define ICSPLL_SYSCTL1 1000 #endif /* def SENSORS_SENSORS_H */