int drv_generic_i2c_open(const char *section, const char *driver) { int dev; char *bus, *device; udelay_init(); Section = (char *) section; Driver = (char *) driver; bus = cfg_get(Section, "Port", NULL); device = cfg_get(Section, "Device", NULL); dev = atoi(device); info("%s: initializing I2C bus %s", Driver, bus); if ((i2c_device = open(bus, O_WRONLY)) < 0) { error("%s: I2C bus %s open failed !\n", Driver, bus); goto exit_error; } info("%s: selecting slave device 0x%x", Driver, dev); if (ioctl(i2c_device, I2C_SLAVE, dev) < 0) { error("%s: error selecting slave device 0x%x\n", Driver, dev); goto exit_error; } info("%s: initializing I2C slave device 0x%x", Driver, dev); if (i2c_smbus_write_quick(i2c_device, I2C_SMBUS_WRITE) < 0) { error("%s: error initializing device 0x%x\n", Driver, dev); close(i2c_device); } return 0; exit_error: free(bus); free(device); close(i2c_device); return -1; }
static int smbus_write_op(struct smbus_op_params *params, const struct smbus_op *op) { int result; /* FIXME: Why is this needed if the open_i2c_slave performs the ioctl * with I2C_SLAVE? */ /* Double cast the last argument for compat with klibc. */ if (ioctl(params->fd, I2C_SLAVE_FORCE, (void *)(intptr_t)params->address) < 0) { fprintf(stderr, "can't set address 0x%02X, %s\n", params->address, strerror(errno)); return -1; } switch (op->size) { case SMBUS_SIZE_8: result = i2c_smbus_write_byte_data(params->fd, params->reg, params->data.fixed.u8); break; case SMBUS_SIZE_16: result = i2c_smbus_write_word_data(params->fd, params->reg, params->data.fixed.u16); break; case SMBUS_SIZE_BLOCK: result = i2c_smbus_write_block_data(params->fd, params->reg, params->len, params->data.array); break; case SMBUS_SIZE_BYTE: result = i2c_smbus_write_byte(params->fd, params->data.fixed.u8); break; case SMBUS_QUICK: result = i2c_smbus_write_quick(params->fd, params->data.fixed.u8); break; default: fprintf(stderr, "Illegal SMBus size for write operation.\n"); return -1; } if (result < 0) { if (op->size != SMBUS_SIZE_BYTE && op->size != SMBUS_QUICK) { fprintf(stderr, "can't write register 0x%02X, %s\n", params->reg, strerror(errno)); } else { fprintf(stderr, "can't write to device 0x%02X, %s\n", params->address, strerror(errno)); } return -1; } return 0; }
static PyObject * SMBus_write_quick(SMBus *self, PyObject *args) { int addr; __s32 result; if (!PyArg_ParseTuple(args, "i:write_quick", &addr)) return NULL; SMBus_SET_ADDR(self, addr); if ((result = i2c_smbus_write_quick(self->fd, I2C_SMBUS_WRITE))) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } Py_INCREF(Py_None); return Py_None; }
int scan_i2c_bus(int file, const int mode, const int first, const int last) { int i, j; int res; printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); for (i = 0; i < 128; i += 16) { printf("%02x: ", i); for(j = 0; j < 16; j++) { /* Skip unwanted addresses */ if (i+j < first || i+j > last) { printf(" "); continue; } /* Set slave address */ if (ioctl(file, I2C_SLAVE, i+j) < 0) { if (errno == EBUSY) { printf("UU "); continue; } else { fprintf(stderr, "Error: Could not set " "address to 0x%02x: %s\n", i+j, strerror(errno)); return -1; } } /* Probe this address */ switch (mode) { case MODE_QUICK: /* This is known to corrupt the Atmel AT24RF08 EEPROM */ res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); break; case MODE_READ: /* This is known to lock SMBus on various write-only chips (mainly clock chips) */ res = i2c_smbus_read_byte(file); break; default: if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) res = i2c_smbus_read_byte(file); else res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); } if (res < 0) printf("XX "); else printf("%02x ", i+j); } printf("\n"); } return 0; }
/* This function is called by i2c_detect */ int icspll_detect(struct i2c_adapter *adapter, int address, unsigned short flags, int kind) { int err, i; struct i2c_client *new_client; struct icspll_data *data; err = 0; /* Make sure we aren't probing the ISA bus!! */ if (i2c_is_isa_adapter(adapter)) return 0; if (address != ADDRESS) return 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { printk("icspll.o: Adapter does not support SMBus writes and Block reads\n"); goto ERROR0; } /* Allocate space for a new client structure */ if (!(new_client = kmalloc(sizeof(struct i2c_client) + sizeof(struct icspll_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } /* Fill the new client structure with data */ data = (struct icspll_data *) (new_client + 1); new_client->data = data; new_client->id = icspll_id++; new_client->addr = address; new_client->adapter = adapter; new_client->driver = &icspll_driver; new_client->flags = 0; strcpy(new_client->name, "Clock chip"); data->valid = 0; init_MUTEX(&data->update_lock); /* use write-quick for detection */ if (i2c_smbus_write_quick(new_client, 0x00) < 0) { printk("icspll.o: No device found at 0x%X\n", address); goto ERROR1; } /* fill data structure so unknown registers are 0xFF */ data->data[0] = ICSPLL_SIZE; for (i = 1; i <= ICSPLL_SIZE; i++) data->data[i] = 0xFF; /* 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 = i2c_register_entry(new_client, "icspll", icspll_dir_table_template, THIS_MODULE)) < 0) goto ERROR3; data->sysctl_id = err; err = 0; ERROR3: i2c_detach_client(new_client); ERROR2: ERROR1: kfree(new_client); ERROR0: return err; }
static int scan_i2c_bus(int file, int mode, unsigned long funcs, int first, int last) { int i, j; int cmd, res; printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); for (i = 0; i < 128; i += 16) { printf("%02x: ", i); for(j = 0; j < 16; j++) { fflush(stdout); /* Select detection command for this address */ switch (mode) { default: cmd = mode; break; case MODE_AUTO: if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) cmd = MODE_READ; else cmd = MODE_QUICK; break; } /* Skip unwanted addresses */ if (i+j < first || i+j > last || (cmd == MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) || (cmd == MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) { printf(" "); continue; } /* Set slave address */ if (ioctl(file, I2C_SLAVE, i+j) < 0) { if (errno == EBUSY) { printf("UU "); continue; } else { fprintf(stderr, "Error: Could not set " "address to 0x%02x: %s\n", i+j, strerror(errno)); return -1; } } /* Probe this address */ switch (cmd) { default: /* MODE_QUICK */ /* This is known to corrupt the Atmel AT24RF08 EEPROM */ res = i2c_smbus_write_quick(file, I2C_SMBUS_WRITE); break; case MODE_READ: /* This is known to lock SMBus on various write-only chips (mainly clock chips) */ res = i2c_smbus_read_byte(file); break; } if (res < 0) printf("-- "); else printf("%02x ", i+j); } printf("\n"); } return 0; }