/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ int i2c_detect(struct i2c_adapter *adapter, struct i2c_address_data *address_data, i2c_found_addr_proc * found_proc) { int addr, i, found, j, err; struct i2c_force_data *this_force; int is_isa = i2c_is_isa_adapter(adapter); int adapter_id = is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter); /* Forget it if we can't probe using SMBUS_QUICK */ if ((!is_isa) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) return -1; for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { if ((is_isa && check_region(addr, 1)) || (!is_isa && i2c_check_addr(adapter, addr))) continue; /* If it is in one of the force entries, we don't do any detection at all */ found = 0; for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { for (j = 0; !found && (this_force->force[j] != SENSORS_I2C_END); j += 2) { 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 ("i2c-proc.o: found force parameter for adapter %d, addr %04x\n", adapter_id, addr); #endif if ( (err = found_proc(adapter, addr, 0, this_force-> kind))) return err; found = 1; } } } if (found) continue; /* If this address is in one of the ignores, we can forget about it right now */ for (i = 0; !found && (address_data->ignore[i] != SENSORS_I2C_END); i += 2) { 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 ("i2c-proc.o: found ignore parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } for (i = 0; !found && (address_data->ignore_range[i] != SENSORS_I2C_END); i += 3) { 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])) { #ifdef DEBUG printk ("i2c-proc.o: found ignore_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } if (found) continue; /* Now, we will do a detection, but only if it is in the normal or probe entries */ if (is_isa) { for (i = 0; !found && (address_data->normal_isa[i] != SENSORS_ISA_END); i += 1) { if (addr == address_data->normal_isa[i]) { #ifdef DEBUG printk ("i2c-proc.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)) { #ifdef DEBUG printk ("i2c-proc.o: found normal isa_range entry for adapter %d, " "addr %04x", adapter_id, addr); #endif found = 1; } } } else { for (i = 0; !found && (address_data->normal_i2c[i] != SENSORS_I2C_END); i += 1) { if (addr == address_data->normal_i2c[i]) { found = 1; #ifdef DEBUG printk ("i2c-proc.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])) { #ifdef DEBUG printk ("i2c-proc.o: found normal i2c_range entry for adapter %d, " "addr %04x\n", adapter_id, addr); #endif found = 1; } } } for (i = 0; !found && (address_data->probe[i] != SENSORS_I2C_END); i += 2) { 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 ("i2c-proc.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])) { found = 1; #ifdef DEBUG printk ("i2c-proc.o: found probe_range parameter for adapter %d, " "addr %04x\n", adapter_id, addr); #endif } } if (!found) continue; /* OK, so we really should examine this address. First check whether there is some client here at all! */ if (is_isa || (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) if ((err = found_proc(adapter, addr, 0, -1))) return err; } return 0; }
/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */ int i2c_detect(struct i2c_adapter *adapter, struct i2c_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)) { int addr, i, found, j, err; struct i2c_force_data *this_force; int is_isa = i2c_is_isa_adapter(adapter); int adapter_id = is_isa ? ANY_I2C_ISA_BUS : i2c_adapter_id(adapter); unsigned short *normal_i2c; unsigned int *normal_isa; unsigned short *probe; unsigned short *ignore; /* Forget it if we can't probe using SMBUS_QUICK */ if ((!is_isa) && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) return -1; /* Use default "empty" list if the adapter doesn't specify any */ normal_i2c = probe = ignore = empty; normal_isa = empty_isa; if (address_data->normal_i2c) normal_i2c = address_data->normal_i2c; if (address_data->normal_isa) normal_isa = address_data->normal_isa; if (address_data->probe) probe = address_data->probe; if (address_data->ignore) ignore = address_data->ignore; for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) { if (!is_isa && i2c_check_addr(adapter, addr)) continue; /* If it is in one of the force entries, we don't do any detection at all */ found = 0; for (i = 0; !found && (this_force = address_data->forces + i, this_force->force); i++) { for (j = 0; !found && (this_force->force[j] != I2C_CLIENT_END); j += 2) { if ( ((adapter_id == this_force->force[j]) || ((this_force->force[j] == ANY_I2C_BUS) && !is_isa)) && (addr == this_force->force[j + 1]) ) { dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n", adapter_id, addr); if ((err = found_proc(adapter, addr, this_force->kind))) return err; found = 1; } } } if (found) continue; /* If this address is in one of the ignores, we can forget about it right now */ for (i = 0; !found && (ignore[i] != I2C_CLIENT_END); i += 2) { if ( ((adapter_id == ignore[i]) || ((ignore[i] == ANY_I2C_BUS) && !is_isa)) && (addr == ignore[i + 1])) { dev_dbg(&adapter->dev, "found ignore parameter for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } if (found) continue; /* Now, we will do a detection, but only if it is in the normal or probe entries */ if (is_isa) { for (i = 0; !found && (normal_isa[i] != I2C_CLIENT_ISA_END); i += 1) { if (addr == normal_isa[i]) { dev_dbg(&adapter->dev, "found normal isa entry for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } } else { for (i = 0; !found && (normal_i2c[i] != I2C_CLIENT_END); i += 1) { if (addr == normal_i2c[i]) { found = 1; dev_dbg(&adapter->dev, "found normal i2c entry for adapter %d, addr %02x\n", adapter_id, addr); } } } for (i = 0; !found && (probe[i] != I2C_CLIENT_END); i += 2) { if (((adapter_id == probe[i]) || ((probe[i] == ANY_I2C_BUS) && !is_isa)) && (addr == probe[i + 1])) { dev_dbg(&adapter->dev, "found probe parameter for adapter %d, addr %04x\n", adapter_id, addr); found = 1; } } if (!found) continue; /* OK, so we really should examine this address. First check whether there is some client here at all! */ if (is_isa || (i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0)) if ((err = found_proc(adapter, addr, -1))) return err; } return 0; }