* In the future, this could be expanded to support cape EEPROMs.
*/
-static int board_info_beaglebone(int fd, i2c_addr_t address);
+static int board_info_beaglebone(int fd, i2c_addr_t address, int flags);
/* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
typedef struct beaglebone_info
} beaglebone_info_t;
static int
-board_info_beaglebone(int fd, i2c_addr_t address)
+board_info_beaglebone(int fd, i2c_addr_t address, int flags)
{
int r;
int i, j;
beaglebone_info_t boneinfo;
r = eeprom_read(fd, address, 0x0000, &boneinfo,
- sizeof(beaglebone_info_t));
+ sizeof(beaglebone_info_t), flags);
if (r == -1) {
fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
return -1;
}
int
-board_info(int fd, i2c_addr_t address)
+board_info(int fd, i2c_addr_t address, int flags)
{
int r;
uint8_t magic_number[4];
- r = eeprom_read(fd, address, 0x0000, &magic_number, 4);
+ r = eeprom_read(fd, address, 0x0000, &magic_number, 4, flags);
if (r == -1) {
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
return 0;
if (magic_number[0] == 0xaa && magic_number[1] == 0x55 &&
magic_number[2] == 0x33 && magic_number[3] == 0xee) {
- board_info_beaglebone(fd, address);
+ board_info_beaglebone(fd, address, flags);
} else {
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
}
eepromread \- read data from an EEPROM
.SH SYNOPSIS
\fBeepromread\fR [\fB\-i\fR] [\fB\-f\fR \fIdev\fR] [\fB\-a\fR \fIslave_addr\fR]
+[\fB\-n\fR]
.br
.de FL
.TP
.TP 5
.B \-a
# Use \fIslave_address\fR instead of \fI0x50\fR.
+.TP 5
+.B \-n
+# Do not send the page number when addressing the memory on the EEPROM. Some
+smaller EEPROM chips aren't organized into pages and get confused if a page
+number is sent with the memory address. Use this when reading EDID.
.SH EXAMPLES
.TP 20
.B eepromread -i
.TP 20
.B eepromread -f /dev/i2c-3 -a 0x54
# display the first 256 bytes of the EEPROM on I2C bus 3, slave address 0x54.
+.TP 20
+.B eepromread -f /dev/i2c-3 -n
+# read the EDID info from the display on I2C bus 3 on the BeagleBoard-xM.
.SH DESCRIPTION
.PP
\fIeepromread\fR is a simple tool for viewing the contents of an EEPROM.
#include <minix/i2c.h>
+#include <minix/com.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "eepromread.h"
-static int __eeprom_read32(int fd, i2c_addr_t addr, uint16_t memaddr,
- void *buf, size_t buflen);
-static int eeprom_dump(int fd, i2c_addr_t addr);
+static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr,
+ void *buf, size_t buflen, int flags);
+static int eeprom_dump(int fd, i2c_addr_t addr, int flags);
#define DEFAULT_I2C_DEVICE "/dev/i2c-1"
#define DEFAULT_I2C_ADDRESS 0x50
/*
- * The /dev interface only supports 32 byte reads/writes and the EEPROM is
- * larger, so to read the whole EEPROM, the task is broken down into 32 byte
- * chunks in eeprom_read(). __eeprom_read32() does the actual ioctl() to do
+ * 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.
*
* A future enhancement might be to add support for the /dev/eeprom interface
*/
static int
-__eeprom_read32(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
- size_t buflen)
+__eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
+ size_t buflen, int flags)
{
int r;
minix_i2c_ioctl_exec_t ioctl_exec;
ioctl_exec.iie_addr = addr;
/* set the address to read from */
- ioctl_exec.iie_cmd[0] = ((memaddr >> 8) & 0xff);
- ioctl_exec.iie_cmd[1] = (memaddr & 0xff);
- ioctl_exec.iie_cmdlen = 2;
-
+ 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);
int
eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
- size_t buflen)
+ size_t buflen, int flags)
{
int r;
uint16_t i;
return -1;
}
- for (i = 0; i < buflen; i += 32) {
- r = __eeprom_read32(fd, addr, memaddr + i, buf + i,
- ((buflen - i) < 32) ? (buflen - i) : 32);
+ for (i = 0; i < buflen; i += 128) {
+
+ r = __eeprom_read128(fd, addr, memaddr + i, buf + i,
+ ((buflen - i) < 128) ? (buflen - i) : 128, flags);
if (r == -1) {
return -1;
}
* Read 256 bytes and print it to the screen in HEX and ASCII.
*/
static int
-eeprom_dump(int fd, i2c_addr_t addr)
+eeprom_dump(int fd, i2c_addr_t addr, int flags)
{
int i, j, r;
uint8_t buf[256];
memset(buf, '\0', 256);
- r = eeprom_read(fd, addr, 0x0000, buf, 256);
+ r = eeprom_read(fd, addr, 0x0000, buf, 256, flags);
if (r == -1) {
return r;
}
main(int argc, char *argv[])
{
int r, fd;
- int ch, iflag = 0;
+ int ch, iflag = 0, read_flags = 0;
char *device = DEFAULT_I2C_DEVICE;
i2c_addr_t address = DEFAULT_I2C_ADDRESS;
setprogname(*argv);
- while ((ch = getopt(argc, argv, "a:f:i")) != -1) {
+ while ((ch = getopt(argc, argv, "a:f:in")) != -1) {
switch (ch) {
case 'a':
address = strtol(optarg, NULL, 0x10);
case 'i':
iflag = 1;
break;
+ case 'n':
+ read_flags |= BDEV_NOPAGE;
+ break;
default:
break;
}
}
if (iflag == 1) {
- r = board_info(fd, address);
+ r = board_info(fd, address, read_flags);
if (r == -1) {
fprintf(stderr, "board_info(): %s\n", strerror(errno));
return 1;
}
} else {
- r = eeprom_dump(fd, address);
+ r = eeprom_dump(fd, address, read_flags);
if (r == -1) {
fprintf(stderr, "eeprom_dump(): %s\n", strerror(errno));
return 1;
#define __EEPROMREAD_H
int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
- size_t buflen);
-int board_info(int fd, i2c_addr_t address);
+ size_t buflen, int flags);
+int board_info(int fd, i2c_addr_t address, int flags);
#endif /* __EEPROMREAD_H */
#include <minix/blockdriver.h>
+#include <minix/com.h>
#include <minix/drivers.h>
#include <minix/ds.h>
#include <minix/i2c.h>
.bdr_device = NULL /* 1 insance per bus, threads not needed */
};
-static int cat24c256_read32(uint16_t memaddr, void *buf, size_t buflen);
-static int cat24c256_read(uint16_t memaddr, void *buf, size_t buflen);
-static int cat24c256_write16(uint16_t memaddr, void *buf, size_t buflen);
-static int cat24c256_write(uint16_t memaddr, void *buf, size_t buflen);
+static int cat24c256_read128(uint16_t memaddr, void *buf, size_t buflen, int flags);
+static int cat24c256_read(uint16_t memaddr, void *buf, size_t buflen, int flags);
+static int cat24c256_write16(uint16_t memaddr, void *buf, size_t buflen, int flags);
+static int cat24c256_write(uint16_t memaddr, void *buf, size_t buflen, int flags);
/* globals */
return EINVAL;
}
- r = cat24c256_write(position, copybuf, count);
+ r = cat24c256_write(position, copybuf, count, flags);
if (r != OK) {
log_warn(&log, "write failed (r=%d)\n", r);
return r;
}
} else {
- r = cat24c256_read(position, copybuf, count);
+ r = cat24c256_read(position, copybuf, count, flags);
if (r != OK) {
log_warn(&log, "read failed (r=%d)\n", r);
return r;
return r;
}
-/* The lower level i2c interface can only read/write 32 bytes at a time.
+/* The lower level i2c interface can only read/write 128 bytes at a time.
* One might want to do more I/O than that at once w/EEPROM, so there is
- * cat24c256_read() and cat24c256_read32(). cat24c256_read32() does the
- * actual reading in chunks up to 32 bytes. cat24c256_read() splits
- * the request up into chunks and repeatedly calls cat24c256_read32()
+ * cat24c256_read() and cat24c256_read128(). cat24c256_read128() does the
+ * actual reading in chunks up to 128 bytes. cat24c256_read() splits
+ * the request up into chunks and repeatedly calls cat24c256_read128()
* until all of the requested EEPROM locations have been read.
*/
static int
-cat24c256_read32(uint16_t memaddr, void *buf, size_t buflen)
+cat24c256_read128(uint16_t memaddr, void *buf, size_t buflen, int flags)
{
int r;
minix_i2c_ioctl_exec_t ioctl_exec;
ioctl_exec.iie_addr = address;
/* set the memory address to read from */
- ioctl_exec.iie_cmd[0] = ((memaddr >> 8) & 0xff);
- ioctl_exec.iie_cmd[1] = (memaddr & 0xff);
- ioctl_exec.iie_cmdlen = 2;
+ if ((BDEV_NOPAGE & flags) == BDEV_NOPAGE) {
+ /* reading within the current page */
+ ioctl_exec.iie_cmd[0] = (memaddr & 0xff);
+ ioctl_exec.iie_cmdlen = 1;
+ } else {
+ 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;
}
int
-cat24c256_read(uint16_t memaddr, void *buf, size_t buflen)
+cat24c256_read(uint16_t memaddr, void *buf, size_t buflen, int flags)
{
int r;
uint16_t i;
return -1;
}
- for (i = 0; i < buflen; i += 32) {
+ for (i = 0; i < buflen; i += 128) {
- r = cat24c256_read32(memaddr + i, buf + i,
- ((buflen - i) < 32) ? (buflen - i) : 32);
+ r = cat24c256_read128(memaddr + i, buf + i,
+ ((buflen - i) < 128) ? (buflen - i) : 128, flags);
if (r != OK) {
return r;
}
log_trace(&log, "read %d bytes starting at 0x%x\n",
- ((buflen - i) < 32) ? (buflen - i) : 32, memaddr + i);
+ ((buflen - i) < 128) ? (buflen - i) : 128, memaddr + i);
}
return OK;
}
static int
-cat24c256_write16(uint16_t memaddr, void *buf, size_t buflen)
+cat24c256_write16(uint16_t memaddr, void *buf, size_t buflen, int flags)
{
int r;
+ int addrlen;
minix_i2c_ioctl_exec_t ioctl_exec;
if (buflen > (I2C_EXEC_MAX_BUFLEN - 2) || buf == NULL
ioctl_exec.iie_cmdlen = 0;
/* set the memory address to write to */
- ioctl_exec.iie_buf[0] = ((memaddr >> 8) & 0xff);
- ioctl_exec.iie_buf[1] = (memaddr & 0xff);
-
- memcpy(ioctl_exec.iie_buf + 2, buf, buflen);
- ioctl_exec.iie_buflen = buflen + 2;
+ if ((BDEV_NOPAGE & flags) == BDEV_NOPAGE) {
+ /* writing within the current page */
+ ioctl_exec.iie_buf[0] = (memaddr & 0xff); /* address */
+ addrlen = 1;
+ } else {
+ ioctl_exec.iie_buf[0] = ((memaddr >> 8) & 0xff);/* page */
+ ioctl_exec.iie_buf[1] = (memaddr & 0xff); /* address */
+ addrlen = 2;
+ }
+ memcpy(ioctl_exec.iie_buf + addrlen, buf, buflen);
+ ioctl_exec.iie_buflen = buflen + addrlen;
r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
if (r != OK) {
}
int
-cat24c256_write(uint16_t memaddr, void *buf, size_t buflen)
+cat24c256_write(uint16_t memaddr, void *buf, size_t buflen, int flags)
{
int r;
uint16_t i;
for (i = 0; i < buflen; i += 16) {
r = cat24c256_write16(memaddr + i, buf + i,
- ((buflen - i) < 16) ? (buflen - i) : 16);
+ ((buflen - i) < 16) ? (buflen - i) : 16, flags);
if (r != OK) {
return r;
}
/* Bits in 'BDEV_FLAGS' field of block device transfer requests. */
# define BDEV_NOFLAGS 0x00 /* no flags are set */
# define BDEV_FORCEWRITE 0x01 /* force write to disk immediately */
+# define BDEV_NOPAGE 0x02 /* eeprom: don't send page address */
/* Field names for GETRUSAGE related calls */
#define RU_ENDPT m1_i1 /* indicates a process for sys_getrusage */
void *iie_buf; /* pointer to data buffer */
size_t iie_buflen; /* length of data buffer */
} i2c_ioctl_exec_t;
-#define I2C_EXEC_MAX_CMDLEN 32
-#define I2C_EXEC_MAX_BUFLEN 32
+#define I2C_EXEC_MAX_CMDLEN 128
+#define I2C_EXEC_MAX_BUFLEN 128
#define I2C_IOCTL_EXEC _IOW('I', 0, i2c_ioctl_exec_t)