mirror of
https://github.com/lm-sensors/lm-sensors
synced 2025-08-30 22:05:11 +00:00
Bug-fixes: lm78.c is now working!
Yes, our first chip driver is now fully operative. Some parts of it can still be moved to sensors.o and reused by other drivers, but this can be done later. Bug fixes: * i2c-core.c: Corrected previous patch (a client was now unloaded twice, which caused problems, as could be expected). * lm78.c, sensors.c: some minor typos, which caused the crashes * lm78.c: FAN_DIV only has two fields (fan 3 is not changable) * sensors.c: ISA/SMBus addresses are prefixed with zeros in directory names git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@20 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
16
TODO
16
TODO
@@ -3,16 +3,22 @@ Many, many things. Most notably:
|
||||
* 2.1 kernel tests; at this moment, only 2.0 compiles have been tried.
|
||||
* Make it SMP-safe: there are no spinlocks yet. They are needed at many
|
||||
places, probably (everywhere where global vars are accessed).
|
||||
* Extend sensors.c with a file /proc/sys/dev/sensors/chips, which lists
|
||||
all directories under /proc/sys/dev/sensors with their SYSCTL id
|
||||
(needed for good sysctl access).
|
||||
* Write smbus_access_i2c in smbus.c
|
||||
* Write piix4_* in piix4.c
|
||||
* Complete lm78 driver
|
||||
* Extend dev interface for SMBus
|
||||
* Create entries in /proc/bus: a list of all registered busses, and for
|
||||
each bus, a file with registered clients (partially done)
|
||||
* Make lm78.c detect 'double hits', (same chip connected to both SMBus and
|
||||
ISA).
|
||||
* Check whether some lm78 functionality is chip-generic and can be moved to
|
||||
sensors.c.
|
||||
* Rename i2c-proc.c to i2c-user.c, and extend it with /dev entries;
|
||||
or, create a better i2c-dev.c, that understands SMBus commands.
|
||||
* Write all other drivers
|
||||
* How to make drivers detect thing *not*; for example, if a Winbond is
|
||||
present, the LM75 driver should not try to access its simulated
|
||||
LM75 chips!
|
||||
LM75 chips (in this case, simply disable them - but what if the LM75
|
||||
driver was loaded first?).
|
||||
* Write a userland-library for SMBus/i2c access (through the /dev interface)
|
||||
* Write a userland detection program for busses (clients are less important;
|
||||
but perhaps needed too).
|
||||
|
@@ -17,7 +17,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#define RCSID "$Id: i2c-core.c,v 1.4 1998/11/27 22:02:09 frodo Exp $"
|
||||
#define RCSID "$Id: i2c-core.c,v 1.5 1998/12/01 21:11:32 frodo Exp $"
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -248,7 +248,7 @@ int i2c_del_driver(struct i2c_driver *driver)
|
||||
if (client != NULL && client->driver == driver) {
|
||||
DEB2(printk("i2c: detaching client %s:\n",
|
||||
client->name));
|
||||
i2c_detach_client(client);
|
||||
/* i2c_detach_client(client); */
|
||||
driver->detach_client(client);
|
||||
}
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ static int lm78_in_conv[7] = {10000, 10000, 10000, 16892, 38000,
|
||||
#define LM78_INIT_IN_5 -1200
|
||||
#define LM78_INIT_IN_6 -500
|
||||
|
||||
#define LM78_INIT_IN_PERCENTAGE 100
|
||||
#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)
|
||||
@@ -256,13 +256,13 @@ static ctl_table lm78_dir_table_template[] = {
|
||||
{ LM78_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN2, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN3, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
|
||||
{ LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl }
|
||||
{ LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ int lm78_detect_isa(struct isa_adapter *adapter)
|
||||
|
||||
/* Register a new directory entry with module sensors */
|
||||
if ((err = sensors_register_entry((struct i2c_client *) new_client,"lm78",
|
||||
lm78_dir_table_template) < 0))
|
||||
lm78_dir_table_template)) < 0)
|
||||
goto ERROR4;
|
||||
((struct lm78_data *) (new_client->data)) -> sysctl_id = err;
|
||||
|
||||
@@ -380,8 +380,8 @@ int lm78_detach_isa(struct isa_client *client)
|
||||
return err;
|
||||
}
|
||||
lm78_remove_client((struct i2c_client *) client);
|
||||
kfree(client);
|
||||
release_region(client->isa_addr,LM78_EXTENT);
|
||||
kfree(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ int lm78_detect_smbus(struct i2c_adapter *adapter)
|
||||
|
||||
/* Register a new directory entry with module sensors */
|
||||
if ((err = sensors_register_entry(new_client,"lm78",
|
||||
lm78_dir_table_template) < 0))
|
||||
lm78_dir_table_template)) < 0)
|
||||
goto ERROR4;
|
||||
((struct lm78_data *) (new_client->data))->sysctl_id = err;
|
||||
|
||||
@@ -592,7 +592,7 @@ void lm78_init_client(struct i2c_client *client)
|
||||
|
||||
void lm78_update_client(struct i2c_client *client)
|
||||
{
|
||||
struct lm78_data *data = client->data;
|
||||
struct lm78_data *data = client->data;
|
||||
int i;
|
||||
|
||||
down(&data->update_lock);
|
||||
@@ -600,6 +600,9 @@ void lm78_update_client(struct i2c_client *client)
|
||||
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));
|
||||
@@ -650,11 +653,12 @@ int lm78_proc (ctl_table *ctl, int write, struct file * filp,
|
||||
nrels=3;
|
||||
mag=2;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN_DIV: case LM78_SYSCTL_TEMP:
|
||||
case LM78_SYSCTL_TEMP:
|
||||
nrels=3;
|
||||
mag=0;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN1: case LM78_SYSCTL_FAN2: case LM78_SYSCTL_FAN3:
|
||||
case LM78_SYSCTL_FAN_DIV:
|
||||
nrels=2;
|
||||
mag=0;
|
||||
break;
|
||||
@@ -736,10 +740,11 @@ int lm78_sysctl (ctl_table *table, int *name, int nlen, void *oldval,
|
||||
switch (table->ctl_name) {
|
||||
case LM78_SYSCTL_IN0: case LM78_SYSCTL_IN1: case LM78_SYSCTL_IN2:
|
||||
case LM78_SYSCTL_IN3: case LM78_SYSCTL_IN4: case LM78_SYSCTL_IN5:
|
||||
case LM78_SYSCTL_IN6: case LM78_SYSCTL_TEMP: case LM78_SYSCTL_FAN_DIV:
|
||||
case LM78_SYSCTL_IN6: case LM78_SYSCTL_TEMP:
|
||||
nrels=3;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN1: case LM78_SYSCTL_FAN2: case LM78_SYSCTL_FAN3:
|
||||
case LM78_SYSCTL_FAN_DIV:
|
||||
nrels=2;
|
||||
break;
|
||||
case LM78_SYSCTL_VID: case LM78_SYSCTL_ALARMS:
|
||||
@@ -825,8 +830,8 @@ void read_in(struct i2c_client *client, int nr, long *results)
|
||||
{
|
||||
struct lm78_data *data = client->data;
|
||||
results[0] = IN_FROM_REG(data->in_min[nr],nr);
|
||||
results[1] = IN_FROM_REG(data->in_min[nr],nr);
|
||||
results[2] = 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);
|
||||
}
|
||||
|
||||
void write_fan(struct i2c_client *client, int nr, int nrels, long *results)
|
||||
|
@@ -62,11 +62,11 @@ int sensors_create_name(char **name, const char *prefix,
|
||||
char name_buffer[50];
|
||||
int id;
|
||||
if (i2c_is_isa_adapter(adapter))
|
||||
sprintf(name_buffer,"%s-isa-%d",prefix,addr);
|
||||
sprintf(name_buffer,"%s-isa-%04x",prefix,addr);
|
||||
else {
|
||||
if ((id = i2c_adapter_id(adapter)) < 0);
|
||||
return -ENOENT;
|
||||
sprintf(name_buffer,"%s-i2c-%d-%d",prefix,id,addr);
|
||||
sprintf(name_buffer,"%s-i2c-%d-%02x",prefix,id,addr);
|
||||
}
|
||||
*name = kmalloc(strlen(name_buffer)+1,GFP_KERNEL);
|
||||
strcpy(*name,name_buffer);
|
||||
@@ -94,7 +94,7 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix,
|
||||
client->addr)))
|
||||
return res;
|
||||
|
||||
for (id = 0; id < SENSORS_ENTRY_MAX; i++)
|
||||
for (id = 0; id < SENSORS_ENTRY_MAX; id++)
|
||||
if (! sensors_entries[id]) {
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sensors_entries[i] = new_header;
|
||||
sensors_entries[id-256] = new_header;
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void sensors_deregister_entry(int id)
|
||||
if (sensors_entries[id]) {
|
||||
table = sensors_entries[id]->ctl_table;
|
||||
unregister_sysctl_table(sensors_entries[id]);
|
||||
kfree((void *) (table->procname));
|
||||
kfree((void *) (table[4].procname));
|
||||
kfree(table);
|
||||
sensors_entries[id] = 0;
|
||||
}
|
||||
|
31
src/lm78.c
31
src/lm78.c
@@ -91,7 +91,7 @@ static int lm78_in_conv[7] = {10000, 10000, 10000, 16892, 38000,
|
||||
#define LM78_INIT_IN_5 -1200
|
||||
#define LM78_INIT_IN_6 -500
|
||||
|
||||
#define LM78_INIT_IN_PERCENTAGE 100
|
||||
#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)
|
||||
@@ -256,13 +256,13 @@ static ctl_table lm78_dir_table_template[] = {
|
||||
{ LM78_SYSCTL_IN5, "in5", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_IN6, "in6", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN1, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN2, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN3, "fan1", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN2, "fan2", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN3, "fan3", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_TEMP, "temp", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_VID, "vid", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ LM78_SYSCTL_FAN_DIV, "fan_div", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
|
||||
{ LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl }
|
||||
{ LM78_SYSCTL_ALARMS, "alarms", NULL, 0, 0644, NULL, &lm78_proc, &lm78_sysctl },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ int lm78_detect_isa(struct isa_adapter *adapter)
|
||||
|
||||
/* Register a new directory entry with module sensors */
|
||||
if ((err = sensors_register_entry((struct i2c_client *) new_client,"lm78",
|
||||
lm78_dir_table_template) < 0))
|
||||
lm78_dir_table_template)) < 0)
|
||||
goto ERROR4;
|
||||
((struct lm78_data *) (new_client->data)) -> sysctl_id = err;
|
||||
|
||||
@@ -380,8 +380,8 @@ int lm78_detach_isa(struct isa_client *client)
|
||||
return err;
|
||||
}
|
||||
lm78_remove_client((struct i2c_client *) client);
|
||||
kfree(client);
|
||||
release_region(client->isa_addr,LM78_EXTENT);
|
||||
kfree(client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ int lm78_detect_smbus(struct i2c_adapter *adapter)
|
||||
|
||||
/* Register a new directory entry with module sensors */
|
||||
if ((err = sensors_register_entry(new_client,"lm78",
|
||||
lm78_dir_table_template) < 0))
|
||||
lm78_dir_table_template)) < 0)
|
||||
goto ERROR4;
|
||||
((struct lm78_data *) (new_client->data))->sysctl_id = err;
|
||||
|
||||
@@ -592,7 +592,7 @@ void lm78_init_client(struct i2c_client *client)
|
||||
|
||||
void lm78_update_client(struct i2c_client *client)
|
||||
{
|
||||
struct lm78_data *data = client->data;
|
||||
struct lm78_data *data = client->data;
|
||||
int i;
|
||||
|
||||
down(&data->update_lock);
|
||||
@@ -600,6 +600,9 @@ void lm78_update_client(struct i2c_client *client)
|
||||
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));
|
||||
@@ -650,11 +653,12 @@ int lm78_proc (ctl_table *ctl, int write, struct file * filp,
|
||||
nrels=3;
|
||||
mag=2;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN_DIV: case LM78_SYSCTL_TEMP:
|
||||
case LM78_SYSCTL_TEMP:
|
||||
nrels=3;
|
||||
mag=0;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN1: case LM78_SYSCTL_FAN2: case LM78_SYSCTL_FAN3:
|
||||
case LM78_SYSCTL_FAN_DIV:
|
||||
nrels=2;
|
||||
mag=0;
|
||||
break;
|
||||
@@ -736,10 +740,11 @@ int lm78_sysctl (ctl_table *table, int *name, int nlen, void *oldval,
|
||||
switch (table->ctl_name) {
|
||||
case LM78_SYSCTL_IN0: case LM78_SYSCTL_IN1: case LM78_SYSCTL_IN2:
|
||||
case LM78_SYSCTL_IN3: case LM78_SYSCTL_IN4: case LM78_SYSCTL_IN5:
|
||||
case LM78_SYSCTL_IN6: case LM78_SYSCTL_TEMP: case LM78_SYSCTL_FAN_DIV:
|
||||
case LM78_SYSCTL_IN6: case LM78_SYSCTL_TEMP:
|
||||
nrels=3;
|
||||
break;
|
||||
case LM78_SYSCTL_FAN1: case LM78_SYSCTL_FAN2: case LM78_SYSCTL_FAN3:
|
||||
case LM78_SYSCTL_FAN_DIV:
|
||||
nrels=2;
|
||||
break;
|
||||
case LM78_SYSCTL_VID: case LM78_SYSCTL_ALARMS:
|
||||
@@ -825,8 +830,8 @@ void read_in(struct i2c_client *client, int nr, long *results)
|
||||
{
|
||||
struct lm78_data *data = client->data;
|
||||
results[0] = IN_FROM_REG(data->in_min[nr],nr);
|
||||
results[1] = IN_FROM_REG(data->in_min[nr],nr);
|
||||
results[2] = 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);
|
||||
}
|
||||
|
||||
void write_fan(struct i2c_client *client, int nr, int nrels, long *results)
|
||||
|
@@ -62,11 +62,11 @@ int sensors_create_name(char **name, const char *prefix,
|
||||
char name_buffer[50];
|
||||
int id;
|
||||
if (i2c_is_isa_adapter(adapter))
|
||||
sprintf(name_buffer,"%s-isa-%d",prefix,addr);
|
||||
sprintf(name_buffer,"%s-isa-%04x",prefix,addr);
|
||||
else {
|
||||
if ((id = i2c_adapter_id(adapter)) < 0);
|
||||
return -ENOENT;
|
||||
sprintf(name_buffer,"%s-i2c-%d-%d",prefix,id,addr);
|
||||
sprintf(name_buffer,"%s-i2c-%d-%02x",prefix,id,addr);
|
||||
}
|
||||
*name = kmalloc(strlen(name_buffer)+1,GFP_KERNEL);
|
||||
strcpy(*name,name_buffer);
|
||||
@@ -94,7 +94,7 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix,
|
||||
client->addr)))
|
||||
return res;
|
||||
|
||||
for (id = 0; id < SENSORS_ENTRY_MAX; i++)
|
||||
for (id = 0; id < SENSORS_ENTRY_MAX; id++)
|
||||
if (! sensors_entries[id]) {
|
||||
break;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ int sensors_register_entry(struct i2c_client *client ,const char *prefix,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sensors_entries[i] = new_header;
|
||||
sensors_entries[id-256] = new_header;
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -141,7 +141,7 @@ void sensors_deregister_entry(int id)
|
||||
if (sensors_entries[id]) {
|
||||
table = sensors_entries[id]->ctl_table;
|
||||
unregister_sysctl_table(sensors_entries[id]);
|
||||
kfree((void *) (table->procname));
|
||||
kfree((void *) (table[4].procname));
|
||||
kfree(table);
|
||||
sensors_entries[id] = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user