mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-31 13:10:30 +00:00
The lm75 module now understands the new insmod parameters.
Also fixed a few nasty sensors.c bugs, and a minor LM78 one. If the new parameters give trouble, please recompile sensors.c with DEBUG=1 and examine the dmesg output! git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@338 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
876fdf9a43
commit
66d89242d4
3 files changed
+189
-85
No files matched your search
+129
-75
@@ -26,6 +26,15 @@
|
||||
#include "i2c-isa.h"
|
||||
#include "version.h"
|
||||
|
||||
/* Addresses to scan */
|
||||
static unsigned short normal_i2c[] = {SENSORS_I2C_END};
|
||||
static unsigned short normal_i2c_range[] = {0x48,0x4f,SENSORS_I2C_END};
|
||||
static unsigned int normal_isa[] = {SENSORS_ISA_END};
|
||||
static unsigned int normal_isa_range[] = {SENSORS_ISA_END};
|
||||
|
||||
/* Insmod parameters */
|
||||
SENSORS_INSMOD_1(lm75);
|
||||
|
||||
/* Many LM75 constants specified below */
|
||||
|
||||
/* The LM75 registers */
|
||||
@@ -61,6 +70,8 @@ extern int cleanup_module(void);
|
||||
static int lm75_init(void);
|
||||
static int lm75_cleanup(void);
|
||||
static int lm75_attach_adapter(struct i2c_adapter *adapter);
|
||||
static int lm75_detect(struct i2c_adapter *adapter, int address, int kind);
|
||||
static void lm75_init_client(struct i2c_client *client);
|
||||
static int lm75_detach_client(struct i2c_client *client);
|
||||
static int lm75_command(struct i2c_client *client, unsigned int cmd,
|
||||
void *arg);
|
||||
@@ -100,110 +111,134 @@ static ctl_table lm75_dir_table_template[] = {
|
||||
/* Used by init/cleanup */
|
||||
static int lm75_initialized = 0;
|
||||
|
||||
/* I choose here for semi-static LM78 allocation. Complete dynamic
|
||||
/* I choose here for semi-static LM75 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
|
||||
#define MAX_LM75_NR 16
|
||||
static struct i2c_client *lm75_list[MAX_LM75_NR];
|
||||
|
||||
|
||||
int lm75_attach_adapter(struct i2c_adapter *adapter)
|
||||
{
|
||||
int address,err,i;
|
||||
return sensors_detect(adapter,&addr_data,lm75_detect);
|
||||
}
|
||||
|
||||
/* This function is called by sensors_detect */
|
||||
int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
{
|
||||
int i,cur,conf,hyst,os;
|
||||
struct i2c_client *new_client;
|
||||
struct lm75_data *data;
|
||||
int err=0;
|
||||
const char *type_name,*client_name;
|
||||
|
||||
err = 0;
|
||||
/* Make sure we aren't probing the ISA bus!! */
|
||||
if (i2c_is_isa_adapter(adapter)) return 0;
|
||||
/* Make sure we aren't probing the ISA bus!! This is just a safety check
|
||||
at this moment; sensors_detect really won't call us. */
|
||||
#ifdef DEBUG
|
||||
if (i2c_is_isa_adapter(adapter)) {
|
||||
printk("lm75.o: lm75_detect called for an ISA bus adapter?!?\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* OK, this is no detection. I know. It will do for now, though. */
|
||||
/* Here, we have to do the address registration check for the I2C bus.
|
||||
But that is not yet implemented. */
|
||||
|
||||
/* 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 ++) {
|
||||
/* 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 lm75_{read,write}_value. */
|
||||
if (! (new_client = kmalloc(sizeof(struct i2c_client) +
|
||||
sizeof(struct lm75_data),
|
||||
GFP_KERNEL))) {
|
||||
err = -ENOMEM;
|
||||
goto ERROR0;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
data = (struct lm75_data *) (((struct i2c_client *) new_client) + 1);
|
||||
new_client->addr = address;
|
||||
new_client->data = data;
|
||||
new_client->adapter = adapter;
|
||||
new_client->driver = &lm75_driver;
|
||||
|
||||
/* 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");
|
||||
/* Now, we do the remaining detection. It is lousy. */
|
||||
cur = smbus_read_word_data(adapter,address,0);
|
||||
conf = smbus_read_byte_data(adapter,address,1);
|
||||
hyst = smbus_read_word_data(adapter,address,2);
|
||||
os = smbus_read_word_data(adapter,address,3);
|
||||
if ((hyst & 0x7f00) || (os & 0x7f00) || (cur & 0x7f00))
|
||||
goto ERROR1;
|
||||
for (i = 0; i <= 0x1f; i++)
|
||||
if ((smbus_read_byte_data(adapter,address,i*8+1) != conf) ||
|
||||
(smbus_read_word_data(adapter,address,i*8+2) != hyst) ||
|
||||
(smbus_read_word_data(adapter,address,i*8+3) != os))
|
||||
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;
|
||||
|
||||
/* Determine the chip type - only one kind supported! */
|
||||
if (kind <= 0)
|
||||
kind = lm75;
|
||||
|
||||
/* 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);
|
||||
if (kind == lm75) {
|
||||
type_name = "lm75";
|
||||
client_name = "LM75 chip";
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printk("lm75.o: Internal error: unknown kind (%d)?!?",kind);
|
||||
#endif
|
||||
goto ERROR1;
|
||||
}
|
||||
|
||||
/* Fill in the remaining client fields and put it into the global list */
|
||||
strcpy(new_client->name,client_name);
|
||||
|
||||
/* 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 ERROR2;
|
||||
}
|
||||
lm75_list[i] = new_client;
|
||||
new_client->id = i;
|
||||
data->valid = 0;
|
||||
data->update_lock = MUTEX;
|
||||
|
||||
/* 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 ((i = sensors_register_entry(new_client,type_name,
|
||||
lm75_dir_table_template)) < 0) {
|
||||
err = i;
|
||||
goto ERROR4;
|
||||
}
|
||||
data->sysctl_id = i;
|
||||
|
||||
lm75_init_client((struct i2c_client *) new_client);
|
||||
return 0;
|
||||
|
||||
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:
|
||||
i2c_detach_client(new_client);
|
||||
for (i = 0; i < MAX_LM75_NR; i++)
|
||||
if (new_client == lm75_list[i])
|
||||
lm75_list[i] = NULL;
|
||||
ERROR2:
|
||||
lm75_list[i] = NULL;
|
||||
ERROR1:
|
||||
kfree(new_client);
|
||||
}
|
||||
kfree(new_client);
|
||||
ERROR0:
|
||||
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);
|
||||
|
||||
@@ -212,8 +247,17 @@ int lm75_detach_client(struct i2c_client *client)
|
||||
return err;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
lm75_list[i] = NULL;
|
||||
|
||||
kfree(client);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -268,6 +312,16 @@ int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
|
||||
swap_bytes(value));
|
||||
}
|
||||
|
||||
void lm75_init_client(struct i2c_client *client)
|
||||
{
|
||||
/* Initialize the LM75 chip */
|
||||
lm75_write_value(client,LM75_REG_TEMP_OS,
|
||||
TEMP_TO_REG(LM75_INIT_TEMP_OS));
|
||||
lm75_write_value(client,LM75_REG_TEMP_HYST,
|
||||
TEMP_TO_REG(LM75_INIT_TEMP_HYST));
|
||||
lm75_write_value(client,LM75_REG_CONF,0);
|
||||
}
|
||||
|
||||
void lm75_update_client(struct i2c_client *client)
|
||||
{
|
||||
struct lm75_data *data = client->data;
|
||||
|
||||
+13
-3
@@ -307,10 +307,16 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
const char *client_name = "";
|
||||
int is_isa = i2c_is_isa_adapter(adapter);
|
||||
|
||||
|
||||
if (kind < 0) {
|
||||
/* We need address registration for the I2C bus too. That is not yet
|
||||
implemented. */
|
||||
if (is_isa) {
|
||||
if (check_region(address,LM78_EXTENT))
|
||||
goto ERROR0;
|
||||
}
|
||||
|
||||
/* Probe whether there is anything available on this address. Already
|
||||
done for SMBus clients */
|
||||
if (kind < 0) {
|
||||
if (is_isa) {
|
||||
|
||||
#define REALLY_SLOW_IO
|
||||
@@ -393,8 +399,12 @@ int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
|
||||
} else if (kind == lm79) {
|
||||
type_name = "lm79";
|
||||
client_name = "LM79 chip";
|
||||
} else
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
printk("lm78.o: Internal error: unknown kind (%d)?!?",kind);
|
||||
#endif
|
||||
goto ERROR1;
|
||||
}
|
||||
|
||||
/* Reserve the ISA region */
|
||||
if (is_isa)
|
||||
|
||||
+47
-7
@@ -607,6 +607,10 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
if (((adapter_id == this_force->force[j]) ||
|
||||
((this_force->force[j] == SENSORS_ANY_I2C_BUS) && !is_isa)) &&
|
||||
(addr == this_force->force[j+1])) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found force parameter for adapter %d, addr %04x\n",
|
||||
adapter_id,addr);
|
||||
#endif
|
||||
if ((err = found_proc(adapter,addr,this_force->kind)))
|
||||
return err;
|
||||
found = 1;
|
||||
@@ -624,6 +628,10 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
if (((adapter_id == address_data->ignore[i]) ||
|
||||
((address_data->ignore[i] == SENSORS_ANY_I2C_BUS) && !is_isa)) &&
|
||||
(addr == address_data->ignore[i+1])) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found ignore parameter for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
@@ -633,8 +641,13 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
if (((adapter_id == address_data->ignore_range[i]) ||
|
||||
((address_data->ignore_range[i]==SENSORS_ANY_I2C_BUS) & !is_isa)) &&
|
||||
(addr >= address_data->ignore_range[i+1]) &&
|
||||
(addr <= address_data->ignore_range[i+2]))
|
||||
(addr <= address_data->ignore_range[i+2])) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found ignore_range parameter for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
@@ -646,15 +659,24 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
!found && (address_data->normal_isa[i] != SENSORS_ISA_END);
|
||||
i += 1) {
|
||||
if (addr == address_data->normal_isa[i]) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found normal isa entry for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
for (i = 0;
|
||||
!found && (address_data->normal_isa_range[i] != SENSORS_ISA_END);
|
||||
i += 3) {
|
||||
if ((addr >= address_data->normal_isa_range[i]) &&
|
||||
(addr <= address_data->normal_isa_range[i+1]) &&
|
||||
((addr - address_data->normal_isa_range[i]) %
|
||||
address_data->normal_isa_range[i+2] == 0));
|
||||
if ((addr >= address_data->normal_isa_range[i]) &&
|
||||
(addr <= address_data->normal_isa_range[i+1]) &&
|
||||
((addr - address_data->normal_isa_range[i]) %
|
||||
address_data->normal_isa_range[i+2] == 0)) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found normal isa_range entry for adapter %d, "
|
||||
"addr %04x", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
@@ -664,12 +686,21 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
i += 1) {
|
||||
if (addr == address_data->normal_i2c[i]) {
|
||||
found = 1;
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found normal i2c entry for adapter %d, "
|
||||
"addr %02x", adapter_id,addr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
for (i = 0;
|
||||
!found && (address_data->normal_i2c_range[i] != SENSORS_I2C_END);
|
||||
i += 2) {
|
||||
if ((addr >= address_data->normal_i2c_range[i]) &&
|
||||
(addr <= address_data->normal_i2c_range[i+1]))
|
||||
(addr <= address_data->normal_i2c_range[i+1])) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found normal i2c_range entry for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
@@ -681,16 +712,25 @@ int sensors_detect(struct i2c_adapter *adapter,
|
||||
if (((adapter_id == address_data->probe[i]) ||
|
||||
((address_data->probe[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) &&
|
||||
(addr == address_data->probe[i+1])) {
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found probe parameter for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
for (i = 0;
|
||||
!found && (address_data->probe_range[i] != SENSORS_I2C_END);
|
||||
i += 3) {
|
||||
if (((adapter_id == address_data->probe_range[i]) ||
|
||||
((address_data->probe_range[i] == SENSORS_ANY_I2C_BUS) & !is_isa)) &&
|
||||
(addr >= address_data->probe_range[i+1]) &&
|
||||
(addr <= address_data->probe_range[i+2]))
|
||||
(addr <= address_data->probe_range[i+2])) {
|
||||
found = 1;
|
||||
#ifdef DEBUG
|
||||
printk("sensors.o: found probe_range parameter for adapter %d, "
|
||||
"addr %04x\n", adapter_id,addr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
|
||||
Reference in new issue
Block a user