#include #include #include #include #include #include #include #include #include #include #include #include "eepromread.h" static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf, size_t buflen, int flags, enum device_types device_type); static int eeprom_dump(int fd, i2c_addr_t addr, int flags, enum device_types device_type); #define DEFAULT_I2C_DEVICE "/dev/i2c-1" #define DEFAULT_I2C_ADDRESS 0x50 /* * The /dev interface only supports 128 byte reads/writes and the EEPROM is * larger, so to read the whole EEPROM, the task is broken down into 128 byte * chunks in eeprom_read(). __eeprom_read128() does the actual ioctl() to do * the read. */ static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf, size_t buflen, int flags, enum device_types device_type) { int r; minix_i2c_ioctl_exec_t ioctl_exec; if (buflen > I2C_EXEC_MAX_BUFLEN || buf == NULL || ((memaddr + buflen) < memaddr)) { errno = EINVAL; return -1; } /* if /dev/eeprom, then use read() */ if (device_type == EEPROM_DEVICE) { off_t offset; offset = lseek(fd, memaddr, SEEK_SET); if (offset != memaddr) { return -1; } return read(fd, buf, buflen); } /* else /dev/i2c, use i2c_ioctl_exec_t interface */ memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t)); ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP; ioctl_exec.iie_addr = addr; /* set the address to read from */ if ((BDEV_NOPAGE & flags) == BDEV_NOPAGE) { /* reading within the current page */ ioctl_exec.iie_cmd[0] = (memaddr & 0xff); ioctl_exec.iie_cmdlen = 1; } else { /* reading from device with multiple pages */ ioctl_exec.iie_cmd[0] = ((memaddr >> 8) & 0xff); ioctl_exec.iie_cmd[1] = (memaddr & 0xff); ioctl_exec.iie_cmdlen = 2; } ioctl_exec.iie_buflen = buflen; r = ioctl(fd, MINIX_I2C_IOCTL_EXEC, &ioctl_exec); if (r == -1) { return -1; } /* call was good, copy results to caller's buffer */ memcpy(buf, ioctl_exec.iie_buf, buflen); return 0; } int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf, size_t buflen, int flags, enum device_types device_type) { int r; uint16_t i; if (buf == NULL || ((memaddr + buflen) < memaddr)) { errno = EINVAL; return -1; } for (i = 0; i < buflen; i += 128) { r = __eeprom_read128(fd, addr, memaddr + i, buf + i, ((buflen - i) < 128) ? (buflen - i) : 128, flags, device_type); if (r == -1) { return -1; } } return 0; } /* * Read 256 bytes and print it to the screen in HEX and ASCII. */ static int eeprom_dump(int fd, i2c_addr_t addr, int flags, enum device_types device_type) { int i, j, r; uint8_t buf[256]; memset(buf, '\0', 256); r = eeprom_read(fd, addr, 0x0000, buf, 256, flags, device_type); if (r == -1) { return r; } /* print table header */ for (i = 0; i < 2; i++) { printf(" "); for (j = 0x0; j <= 0xf; j++) { if (i == 0) { printf(" "); } printf("%x", j); } } printf("\n"); /* print table data */ for (i = 0x00; i < 0xff; i += 0x10) { /* row label */ printf("%02x:", i); /* row data (in hex) */ for (j = 0x0; j <= 0xf; j++) { printf(" %02x", buf[i + j]); } printf(" "); /* row data (in ASCII) */ for (j = 0x0; j <= 0xf; j++) { if (isprint(buf[i + j])) { printf("%c", buf[i + j]); } else { printf("."); } } printf("\n"); } return 0; } int main(int argc, char *argv[]) { int r, fd; int ch, iflag = 0, read_flags = 0; char *device = DEFAULT_I2C_DEVICE; i2c_addr_t address = DEFAULT_I2C_ADDRESS; enum device_types device_type = DEFAULT_DEVICE; setprogname(*argv); while ((ch = getopt(argc, argv, "a:f:in")) != -1) { switch (ch) { case 'a': address = strtol(optarg, NULL, 0x10); break; case 'f': device = optarg; break; case 'i': iflag = 1; break; case 'n': read_flags |= BDEV_NOPAGE; break; default: break; } } /* determine whether to use /dev/i2c or /dev/eeprom interface */ device_type = strstr(device, "i2c") == NULL ? EEPROM_DEVICE : I2C_DEVICE; fd = open(device, O_RDWR); if (fd == -1) { fprintf(stderr, "open(): %s\n", strerror(errno)); return 1; } if (iflag == 1) { r = board_info(fd, address, read_flags, device_type); if (r == -1) { fprintf(stderr, "board_info(): %s\n", strerror(errno)); return 1; } } else { r = eeprom_dump(fd, address, read_flags, device_type); if (r == -1) { fprintf(stderr, "eeprom_dump(): %s\n", strerror(errno)); return 1; } } r = close(fd); if (r == -1) { fprintf(stderr, "close(): %s\n", strerror(errno)); return 1; } return 0; }