tools/llvm: Do not build with symbols
[minix3.git] / minix / usr.bin / eepromread / eepromread.c
blob3c1f807da400b43cd2a9ebfcaa69005314011412
1 #include <minix/i2c.h>
2 #include <minix/com.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
7 #include <ctype.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
15 #include "eepromread.h"
17 static int __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr,
18 void *buf, size_t buflen, int flags, enum device_types device_type);
19 static int eeprom_dump(int fd, i2c_addr_t addr, int flags,
20 enum device_types device_type);
22 #define DEFAULT_I2C_DEVICE "/dev/i2c-1"
23 #define DEFAULT_I2C_ADDRESS 0x50
26 * The /dev interface only supports 128 byte reads/writes and the EEPROM is
27 * larger, so to read the whole EEPROM, the task is broken down into 128 byte
28 * chunks in eeprom_read(). __eeprom_read128() does the actual ioctl() to do
29 * the read.
32 static int
33 __eeprom_read128(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
34 size_t buflen, int flags, enum device_types device_type)
36 int r;
37 minix_i2c_ioctl_exec_t ioctl_exec;
39 if (buflen > I2C_EXEC_MAX_BUFLEN || buf == NULL
40 || ((memaddr + buflen) < memaddr)) {
41 errno = EINVAL;
42 return -1;
45 /* if /dev/eeprom, then use read() */
46 if (device_type == EEPROM_DEVICE) {
48 off_t offset;
50 offset = lseek(fd, memaddr, SEEK_SET);
51 if (offset != memaddr) {
52 return -1;
55 return read(fd, buf, buflen);
58 /* else /dev/i2c, use i2c_ioctl_exec_t interface */
59 memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
61 ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
62 ioctl_exec.iie_addr = addr;
64 /* set the address to read from */
65 if ((BDEV_NOPAGE & flags) == BDEV_NOPAGE) {
66 /* reading within the current page */
67 ioctl_exec.iie_cmd[0] = (memaddr & 0xff);
68 ioctl_exec.iie_cmdlen = 1;
69 } else {
70 /* reading from device with multiple pages */
71 ioctl_exec.iie_cmd[0] = ((memaddr >> 8) & 0xff);
72 ioctl_exec.iie_cmd[1] = (memaddr & 0xff);
73 ioctl_exec.iie_cmdlen = 2;
75 ioctl_exec.iie_buflen = buflen;
77 r = ioctl(fd, MINIX_I2C_IOCTL_EXEC, &ioctl_exec);
78 if (r == -1) {
79 return -1;
82 /* call was good, copy results to caller's buffer */
83 memcpy(buf, ioctl_exec.iie_buf, buflen);
85 return 0;
88 int
89 eeprom_read(int fd, i2c_addr_t addr, uint16_t memaddr, void *buf,
90 size_t buflen, int flags, enum device_types device_type)
92 int r;
93 uint16_t i;
95 if (buf == NULL || ((memaddr + buflen) < memaddr)) {
96 errno = EINVAL;
97 return -1;
100 for (i = 0; i < buflen; i += 128) {
102 r = __eeprom_read128(fd, addr, memaddr + i, buf + i,
103 ((buflen - i) < 128) ? (buflen - i) : 128, flags,
104 device_type);
105 if (r == -1) {
106 return -1;
110 return 0;
114 * Read 256 bytes and print it to the screen in HEX and ASCII.
116 static int
117 eeprom_dump(int fd, i2c_addr_t addr, int flags, enum device_types device_type)
119 int i, j, r;
120 uint8_t buf[256];
122 memset(buf, '\0', 256);
124 r = eeprom_read(fd, addr, 0x0000, buf, 256, flags, device_type);
125 if (r == -1) {
126 return r;
129 /* print table header */
130 for (i = 0; i < 2; i++) {
131 printf(" ");
132 for (j = 0x0; j <= 0xf; j++) {
133 if (i == 0) {
134 printf(" ");
136 printf("%x", j);
139 printf("\n");
141 /* print table data */
142 for (i = 0x00; i < 0xff; i += 0x10) {
144 /* row label */
145 printf("%02x:", i);
147 /* row data (in hex) */
148 for (j = 0x0; j <= 0xf; j++) {
149 printf(" %02x", buf[i + j]);
152 printf(" ");
154 /* row data (in ASCII) */
155 for (j = 0x0; j <= 0xf; j++) {
156 if (isprint(buf[i + j])) {
157 printf("%c", buf[i + j]);
158 } else {
159 printf(".");
163 printf("\n");
166 return 0;
170 main(int argc, char *argv[])
172 int r, fd;
173 int ch, iflag = 0, read_flags = 0;
174 char *device = DEFAULT_I2C_DEVICE;
175 i2c_addr_t address = DEFAULT_I2C_ADDRESS;
176 enum device_types device_type = DEFAULT_DEVICE;
178 setprogname(*argv);
180 while ((ch = getopt(argc, argv, "a:f:in")) != -1) {
181 switch (ch) {
182 case 'a':
183 address = strtol(optarg, NULL, 0x10);
184 break;
185 case 'f':
186 device = optarg;
187 break;
188 case 'i':
189 iflag = 1;
190 break;
191 case 'n':
192 read_flags |= BDEV_NOPAGE;
193 break;
194 default:
195 break;
199 /* determine whether to use /dev/i2c or /dev/eeprom interface */
200 device_type =
201 strstr(device, "i2c") == NULL ? EEPROM_DEVICE : I2C_DEVICE;
203 fd = open(device, O_RDWR);
204 if (fd == -1) {
205 fprintf(stderr, "open(): %s\n", strerror(errno));
206 return 1;
209 if (iflag == 1) {
210 r = board_info(fd, address, read_flags, device_type);
211 if (r == -1) {
212 fprintf(stderr, "board_info(): %s\n", strerror(errno));
213 return 1;
215 } else {
216 r = eeprom_dump(fd, address, read_flags, device_type);
217 if (r == -1) {
218 fprintf(stderr, "eeprom_dump(): %s\n",
219 strerror(errno));
220 return 1;
224 r = close(fd);
225 if (r == -1) {
226 fprintf(stderr, "close(): %s\n", strerror(errno));
227 return 1;
230 return 0;