eepromread: support for reading from /dev/eeprom
eepromread could only read EEPROMs through the /dev/i2c interface. Once the cat24c256 driver is started and claims/reserves the device, it can no longer be read through the /dev/i2c interface. This patch adds support for reading from EEPROMs through the /dev/eeprom interface. For example, to read the on-board eeprom on the BBB, one would do `eepromread -f /dev/eepromb1s50 -i`. Change-Id: If08ce37231e593982eeb109bdd6d5458ad271108
This commit is contained in:
parent
9a00643262
commit
13054fd168
@ -16,9 +16,12 @@
|
|||||||
* Attempt to read the board info from an eeprom on this board.
|
* Attempt to read the board info from an eeprom on this board.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int board_info_beaglebone(int fd, i2c_addr_t address, int flags);
|
static int board_info_beaglebone(int fd, i2c_addr_t address, int flags,
|
||||||
static int board_info_cape_a0(int fd, i2c_addr_t address, int flags);
|
enum device_types device_type);
|
||||||
static int board_info_cape_a1(int fd, i2c_addr_t address, int flags);
|
static int board_info_cape_a0(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type);
|
||||||
|
static int board_info_cape_a1(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type);
|
||||||
|
|
||||||
/* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
|
/* Memory Layout of the BeagleBone and BeagleBone Black EEPROM */
|
||||||
typedef struct beaglebone_info
|
typedef struct beaglebone_info
|
||||||
@ -68,7 +71,8 @@ typedef struct cape_info_a1
|
|||||||
} cape_info_a1_t;
|
} cape_info_a1_t;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
board_info_beaglebone(int fd, i2c_addr_t address, int flags)
|
board_info_beaglebone(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -76,7 +80,7 @@ board_info_beaglebone(int fd, i2c_addr_t address, int flags)
|
|||||||
beaglebone_info_t boneinfo;
|
beaglebone_info_t boneinfo;
|
||||||
|
|
||||||
r = eeprom_read(fd, address, 0x0000, &boneinfo,
|
r = eeprom_read(fd, address, 0x0000, &boneinfo,
|
||||||
sizeof(beaglebone_info_t), flags);
|
sizeof(beaglebone_info_t), flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
|
fprintf(stderr, "Failed to read BeagleBone info r=%d\n", r);
|
||||||
return -1;
|
return -1;
|
||||||
@ -102,7 +106,8 @@ board_info_beaglebone(int fd, i2c_addr_t address, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
board_info_cape_a0(int fd, i2c_addr_t address, int flags)
|
board_info_cape_a0(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -110,7 +115,7 @@ board_info_cape_a0(int fd, i2c_addr_t address, int flags)
|
|||||||
cape_info_a0_t capeinfo;
|
cape_info_a0_t capeinfo;
|
||||||
|
|
||||||
r = eeprom_read(fd, address, 0x0000, &capeinfo,
|
r = eeprom_read(fd, address, 0x0000, &capeinfo,
|
||||||
sizeof(cape_info_a0_t), flags);
|
sizeof(cape_info_a0_t), flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
|
fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
|
||||||
return -1;
|
return -1;
|
||||||
@ -148,7 +153,8 @@ board_info_cape_a0(int fd, i2c_addr_t address, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
board_info_cape_a1(int fd, i2c_addr_t address, int flags)
|
board_info_cape_a1(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int i, j;
|
int i, j;
|
||||||
@ -156,7 +162,7 @@ board_info_cape_a1(int fd, i2c_addr_t address, int flags)
|
|||||||
cape_info_a1_t capeinfo;
|
cape_info_a1_t capeinfo;
|
||||||
|
|
||||||
r = eeprom_read(fd, address, 0x0000, &capeinfo,
|
r = eeprom_read(fd, address, 0x0000, &capeinfo,
|
||||||
sizeof(cape_info_a1_t), flags);
|
sizeof(cape_info_a1_t), flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
|
fprintf(stderr, "failed to read cape A0 info r=%d\n", r);
|
||||||
return -1;
|
return -1;
|
||||||
@ -194,12 +200,14 @@ board_info_cape_a1(int fd, i2c_addr_t address, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
board_info(int fd, i2c_addr_t address, int flags)
|
board_info(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uint8_t magic_number[6];
|
uint8_t magic_number[6];
|
||||||
|
|
||||||
r = eeprom_read(fd, address, 0x0000, &magic_number, 6, flags);
|
r = eeprom_read(fd, address, 0x0000, &magic_number, 6, flags,
|
||||||
|
device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
|
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
|
||||||
return 0;
|
return 0;
|
||||||
@ -211,11 +219,11 @@ board_info(int fd, i2c_addr_t address, int flags)
|
|||||||
|
|
||||||
/* Check if Cape Rev A0, Cape Rev A1, or on-board EEPROM */
|
/* Check if Cape Rev A0, Cape Rev A1, or on-board EEPROM */
|
||||||
if (magic_number[4] == 'A' && magic_number[5] == '0') {
|
if (magic_number[4] == 'A' && magic_number[5] == '0') {
|
||||||
board_info_cape_a0(fd, address, flags);
|
board_info_cape_a0(fd, address, flags, device_type);
|
||||||
} else if (magic_number[4] == 'A' && magic_number[5] == '1') {
|
} else if (magic_number[4] == 'A' && magic_number[5] == '1') {
|
||||||
board_info_cape_a1(fd, address, flags);
|
board_info_cape_a1(fd, address, flags, device_type);
|
||||||
} else {
|
} else {
|
||||||
board_info_beaglebone(fd, address, flags);
|
board_info_beaglebone(fd, address, flags, device_type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
|
printf("%-16s: %s\n", "BOARD_NAME", "UNKNOWN");
|
||||||
|
@ -43,6 +43,10 @@ number is sent with the memory address. Use this when reading EDID.
|
|||||||
.TP 20
|
.TP 20
|
||||||
.B eepromread -f /dev/i2c-3 -n
|
.B eepromread -f /dev/i2c-3 -n
|
||||||
# read the EDID info from the display on I2C bus 3 on the BeagleBoard-xM.
|
# read the EDID info from the display on I2C bus 3 on the BeagleBoard-xM.
|
||||||
|
.TP 20
|
||||||
|
.B eepromread -f /dev/eepromb1s50 -i
|
||||||
|
# access the EEPROM through the /dev/eeprom interface once the
|
||||||
|
cat24c256 driver has been started.
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
\fIeepromread\fR is a simple tool for viewing the contents of an EEPROM.
|
\fIeepromread\fR is a simple tool for viewing the contents of an EEPROM.
|
||||||
@ -51,5 +55,5 @@ detect, \fIeepromread\fR can properly format each of the fields and display
|
|||||||
the information via the \fI-i\fR command line option.
|
the information via the \fI-i\fR command line option.
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
If the \fIcat24c256\fR driver has claimed the EEPROM device that this
|
If the \fIcat24c256\fR driver has claimed the EEPROM device that this
|
||||||
program is attempting to read from, then this program will fail. Once
|
program is attempting to read from, then you must access it through
|
||||||
a driver claims an I2C device, the driver has exclusive access.
|
the /dev/eeprom interface rather than the /dev/i2c interface.
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
#include "eepromread.h"
|
#include "eepromread.h"
|
||||||
|
|
||||||
static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr,
|
static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr,
|
||||||
void *buf, size_t buflen, int flags);
|
void *buf, size_t buflen, int flags, enum device_types device_type);
|
||||||
static int eeprom_dump(int fd, i2c_addr_t addr, int flags);
|
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_DEVICE "/dev/i2c-1"
|
||||||
#define DEFAULT_I2C_ADDRESS 0x50
|
#define DEFAULT_I2C_ADDRESS 0x50
|
||||||
@ -26,16 +27,11 @@ static int eeprom_dump(int fd, i2c_addr_t addr, int flags);
|
|||||||
* larger, so to read the whole EEPROM, the task is broken down into 128 byte
|
* 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
|
* chunks in eeprom_read(). __eeprom_read128() does the actual ioctl() to do
|
||||||
* the read.
|
* the read.
|
||||||
*
|
|
||||||
* A future enhancement might be to add support for the /dev/eeprom interface
|
|
||||||
* and if one way fails, fall back to the other. /dev/eeprom can fail if the
|
|
||||||
* eeprom driver isn't running and /dev/i2c can fail if the eeprom driver
|
|
||||||
* claimed the eeprom device.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
__eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
||||||
size_t buflen, int flags)
|
size_t buflen, int flags, enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
minix_i2c_ioctl_exec_t ioctl_exec;
|
minix_i2c_ioctl_exec_t ioctl_exec;
|
||||||
@ -46,6 +42,20 @@ __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
|||||||
return -1;
|
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));
|
memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
|
||||||
|
|
||||||
ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
|
ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
|
||||||
@ -77,7 +87,7 @@ __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
|||||||
|
|
||||||
int
|
int
|
||||||
eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
||||||
size_t buflen, int flags)
|
size_t buflen, int flags, enum device_types device_type)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
@ -87,11 +97,11 @@ eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < buflen; i += 128) {
|
for (i = 0; i < buflen; i += 128) {
|
||||||
|
|
||||||
r = __eeprom_read128(fd, addr, memaddr + i, buf + i,
|
r = __eeprom_read128(fd, addr, memaddr + i, buf + i,
|
||||||
((buflen - i) < 128) ? (buflen - i) : 128, flags);
|
((buflen - i) < 128) ? (buflen - i) : 128, flags,
|
||||||
|
device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -104,14 +114,14 @@ eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
|||||||
* Read 256 bytes and print it to the screen in HEX and ASCII.
|
* Read 256 bytes and print it to the screen in HEX and ASCII.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
eeprom_dump(int fd, i2c_addr_t addr, int flags)
|
eeprom_dump(int fd, i2c_addr_t addr, int flags, enum device_types device_type)
|
||||||
{
|
{
|
||||||
int i, j, r;
|
int i, j, r;
|
||||||
uint8_t buf[256];
|
uint8_t buf[256];
|
||||||
|
|
||||||
memset(buf, '\0', 256);
|
memset(buf, '\0', 256);
|
||||||
|
|
||||||
r = eeprom_read(fd, addr, 0x0000, buf, 256, flags);
|
r = eeprom_read(fd, addr, 0x0000, buf, 256, flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -163,6 +173,7 @@ main(int argc, char *argv[])
|
|||||||
int ch, iflag = 0, read_flags = 0;
|
int ch, iflag = 0, read_flags = 0;
|
||||||
char *device = DEFAULT_I2C_DEVICE;
|
char *device = DEFAULT_I2C_DEVICE;
|
||||||
i2c_addr_t address = DEFAULT_I2C_ADDRESS;
|
i2c_addr_t address = DEFAULT_I2C_ADDRESS;
|
||||||
|
enum device_types device_type = DEFAULT_DEVICE;
|
||||||
|
|
||||||
setprogname(*argv);
|
setprogname(*argv);
|
||||||
|
|
||||||
@ -185,6 +196,10 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
fd = open(device, O_RDWR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
fprintf(stderr, "open(): %s\n", strerror(errno));
|
fprintf(stderr, "open(): %s\n", strerror(errno));
|
||||||
@ -192,15 +207,16 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iflag == 1) {
|
if (iflag == 1) {
|
||||||
r = board_info(fd, address, read_flags);
|
r = board_info(fd, address, read_flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "board_info(): %s\n", strerror(errno));
|
fprintf(stderr, "board_info(): %s\n", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r = eeprom_dump(fd, address, read_flags);
|
r = eeprom_dump(fd, address, read_flags, device_type);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "eeprom_dump(): %s\n", strerror(errno));
|
fprintf(stderr, "eeprom_dump(): %s\n",
|
||||||
|
strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,4 +229,3 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
#ifndef __EEPROMREAD_H
|
#ifndef __EEPROMREAD_H
|
||||||
#define __EEPROMREAD_H
|
#define __EEPROMREAD_H
|
||||||
|
|
||||||
|
enum device_types { I2C_DEVICE, EEPROM_DEVICE };
|
||||||
|
#define DEFAULT_DEVICE I2C_DEVICE
|
||||||
|
|
||||||
int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
int eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
|
||||||
size_t buflen, int flags);
|
size_t buflen, int flags, enum device_types device_type);
|
||||||
int board_info(int fd, i2c_addr_t address, int flags);
|
|
||||||
|
int board_info(int fd, i2c_addr_t address, int flags,
|
||||||
|
enum device_types device_type);
|
||||||
|
|
||||||
#endif /* __EEPROMREAD_H */
|
#endif /* __EEPROMREAD_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user