Lines 121-129
Link Here
|
121 |
static int |
121 |
static int |
122 |
scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr) |
122 |
scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr) |
123 |
{ |
123 |
{ |
|
|
124 |
struct iic_rdwr_data msg; |
124 |
struct skip_range addr_range = { 0, 0 }; |
125 |
struct skip_range addr_range = { 0, 0 }; |
125 |
int *tokens, fd, error, i, index, j; |
126 |
int *tokens, fd, error, i, index, j; |
126 |
int len = 0, do_skip = 0, no_range = 1; |
127 |
int len = 0, do_skip = 0, no_range = 1; |
|
|
128 |
char buf = 0; |
127 |
|
129 |
|
128 |
fd = open(dev, O_RDWR); |
130 |
fd = open(dev, O_RDWR); |
129 |
if (fd == -1) { |
131 |
if (fd == -1) { |
Lines 157-162
Link Here
|
157 |
} |
159 |
} |
158 |
|
160 |
|
159 |
printf("Scanning I2C devices on %s: ", dev); |
161 |
printf("Scanning I2C devices on %s: ", dev); |
|
|
162 |
|
163 |
msg.nmsgs = 1; |
164 |
msg.msgs = calloc(1, sizeof(struct iic_msg)); |
165 |
msg.msgs->buf = &buf; |
166 |
msg.msgs->len = 1; |
167 |
msg.msgs->flags = IIC_M_RD; |
168 |
|
160 |
for (i = 1; i < 127; i++) { |
169 |
for (i = 1; i < 127; i++) { |
161 |
|
170 |
|
162 |
if (skip && ( addr_range.start < addr_range.end)) { |
171 |
if (skip && ( addr_range.start < addr_range.end)) { |
Lines 176-211
Link Here
|
176 |
continue; |
185 |
continue; |
177 |
} |
186 |
} |
178 |
|
187 |
|
179 |
cmd.slave = i << 1; |
188 |
msg.msgs->slave = i << 1; |
180 |
cmd.last = 1; |
189 |
error = ioctl(fd, I2CRDWR, &msg); |
181 |
cmd.count = 0; |
190 |
if (error != -1) |
182 |
error = ioctl(fd, I2CRSTCARD, &cmd); |
191 |
printf("0x%x ", i); |
183 |
if (error) |
|
|
184 |
goto out; |
185 |
|
186 |
cmd.slave = i << 1; |
187 |
cmd.last = 1; |
188 |
error = ioctl(fd, I2CSTART, &cmd); |
189 |
if (!error) |
190 |
printf("%x ", i); |
191 |
cmd.slave = i << 1; |
192 |
cmd.last = 1; |
193 |
error = ioctl(fd, I2CSTOP, &cmd); |
194 |
} |
192 |
} |
195 |
printf("\n"); |
193 |
printf("\n"); |
196 |
|
194 |
|
197 |
error = ioctl(fd, I2CRSTCARD, &cmd); |
|
|
198 |
out: |
195 |
out: |
199 |
close(fd); |
196 |
close(fd); |
200 |
if (skip && no_range) |
197 |
if (skip && no_range) |
201 |
free(tokens); |
198 |
free(tokens); |
202 |
|
199 |
|
203 |
if (error) { |
200 |
return (EX_OK); |
204 |
fprintf(stderr, "Error scanning I2C controller (%s): %s\n", |
|
|
205 |
dev, strerror(errno)); |
206 |
return (EX_NOINPUT); |
207 |
} else |
208 |
return (EX_OK); |
209 |
} |
201 |
} |
210 |
|
202 |
|
211 |
static int |
203 |
static int |
Lines 253-463
Link Here
|
253 |
} |
245 |
} |
254 |
|
246 |
|
255 |
static int |
247 |
static int |
256 |
i2c_write(char *dev, struct options i2c_opt, char *i2c_buf) |
248 |
i2c_read_write(char *dev, struct options i2c_opt, char *i2c_buf) |
257 |
{ |
249 |
{ |
258 |
struct iiccmd cmd; |
250 |
struct iic_rdwr_data msgs; |
259 |
int ch, i, error, fd, bufsize; |
251 |
int fd, error, i; |
260 |
char *err_msg, *buf; |
252 |
char *err_msg, ch; |
261 |
|
253 |
|
262 |
/* |
254 |
if (i2c_opt.dir == 'w') { |
263 |
* Read data to be written to the chip from stdin |
255 |
if (i2c_opt.verbose && !i2c_opt.binary) |
264 |
*/ |
256 |
fprintf(stderr, "Enter %u bytes of data: ", i2c_opt.count); |
265 |
if (i2c_opt.verbose && !i2c_opt.binary) |
|
|
266 |
fprintf(stderr, "Enter %u bytes of data: ", i2c_opt.count); |
267 |
|
257 |
|
268 |
for (i = 0; i < i2c_opt.count; i++) { |
258 |
for (i = 0; i < i2c_opt.count; i++) { |
269 |
ch = getchar(); |
259 |
ch = getchar(); |
270 |
if (ch == EOF) { |
260 |
if (ch == EOF) { |
271 |
free(i2c_buf); |
261 |
free(i2c_buf); |
272 |
err(1, "not enough data, exiting\n"); |
262 |
err(1, "not enough data, exiting\n"); |
|
|
263 |
} |
264 |
i2c_buf[i] = ch; |
273 |
} |
265 |
} |
274 |
i2c_buf[i] = ch; |
|
|
275 |
} |
266 |
} |
276 |
|
267 |
|
277 |
fd = open(dev, O_RDWR); |
268 |
fd = open(dev, O_RDWR); |
278 |
if (fd == -1) { |
269 |
if (fd == -1) |
279 |
free(i2c_buf); |
|
|
280 |
err(1, "open failed"); |
270 |
err(1, "open failed"); |
281 |
} |
|
|
282 |
|
271 |
|
283 |
/* |
272 |
msgs.nmsgs = 1; |
284 |
* Write offset where the data will go |
|
|
285 |
*/ |
286 |
cmd.slave = i2c_opt.addr; |
287 |
error = ioctl(fd, I2CSTART, &cmd); |
288 |
if (error == -1) { |
289 |
err_msg = "ioctl: error sending start condition"; |
290 |
goto err1; |
291 |
} |
292 |
|
293 |
if (i2c_opt.width) { |
273 |
if (i2c_opt.width) { |
294 |
bufsize = i2c_opt.width / 8; |
274 |
msgs.nmsgs = 2; |
295 |
buf = prepare_buf(bufsize, i2c_opt.off); |
275 |
msgs.msgs = calloc(2, sizeof(struct iic_msg)); |
296 |
if (buf == NULL) { |
276 |
msgs.msgs[0].slave = i2c_opt.addr; |
297 |
err_msg = "error: offset malloc"; |
277 |
msgs.msgs[0].len = i2c_opt.width / 8; |
298 |
goto err1; |
|
|
299 |
} |
300 |
|
278 |
|
301 |
cmd.count = bufsize; |
279 |
if ((msgs.msgs[0].buf = calloc(msgs.msgs[0].len, sizeof(uint8_t))) == NULL) { |
302 |
cmd.buf = buf; |
280 |
err_msg = "can't malloc\n"; |
303 |
error = ioctl(fd, I2CWRITE, &cmd); |
281 |
goto err; |
304 |
free(buf); |
|
|
305 |
if (error == -1) { |
306 |
err_msg = "ioctl: error when write offset"; |
307 |
goto err1; |
308 |
} |
282 |
} |
309 |
} |
283 |
if (msgs.msgs[0].len == 1) |
310 |
|
284 |
msgs.msgs[0].buf[0] = i2c_opt.off & 0xff; |
311 |
/* Mode - stop start */ |
285 |
else if (msgs.msgs[0].len == 2) { |
312 |
if (i2c_opt.mode == I2C_MODE_STOP_START) { |
286 |
msgs.msgs[0].buf[0] = (i2c_opt.off >> 8) & 0xff; |
313 |
cmd.slave = i2c_opt.addr; |
287 |
msgs.msgs[0].buf[1] = i2c_opt.off & 0xff; |
314 |
error = ioctl(fd, I2CSTOP, &cmd); |
|
|
315 |
if (error == -1) { |
316 |
err_msg = "ioctl: error sending stop condition"; |
317 |
goto err2; |
318 |
} |
288 |
} |
319 |
cmd.slave = i2c_opt.addr; |
289 |
if (msgs.msgs[0].buf == NULL) { |
320 |
error = ioctl(fd, I2CSTART, &cmd); |
290 |
err_msg = "error: offset malloc"; |
321 |
if (error == -1) { |
291 |
goto err; |
322 |
err_msg = "ioctl: error sending start condition"; |
|
|
323 |
goto err1; |
324 |
} |
292 |
} |
325 |
} |
|
|
326 |
/* Mode - repeated start */ |
327 |
if (i2c_opt.mode == I2C_MODE_REPEATED_START) { |
328 |
cmd.slave = i2c_opt.addr; |
329 |
error = ioctl(fd, I2CRPTSTART, &cmd); |
330 |
if (error == -1) { |
331 |
err_msg = "ioctl: error sending repeated start " |
332 |
"condition"; |
333 |
goto err1; |
334 |
} |
335 |
} |
336 |
|
293 |
|
337 |
/* |
294 |
msgs.msgs[0].flags = IIC_M_WR; |
338 |
* Write the data |
295 |
if (i2c_opt.mode == I2C_MODE_REPEATED_START || i2c_opt.mode == I2C_MODE_NONE) |
339 |
*/ |
296 |
msgs.msgs[0].flags |= IIC_M_NOSTOP; |
340 |
cmd.count = i2c_opt.count; |
|
|
341 |
cmd.buf = i2c_buf; |
342 |
cmd.last = 0; |
343 |
error = ioctl(fd, I2CWRITE, &cmd); |
344 |
if (error == -1) { |
345 |
err_msg = "ioctl: error when write"; |
346 |
goto err1; |
347 |
} |
297 |
} |
348 |
cmd.slave = i2c_opt.addr; |
|
|
349 |
error = ioctl(fd, I2CSTOP, &cmd); |
350 |
if (error == -1) { |
351 |
err_msg = "ioctl: error sending stop condition"; |
352 |
goto err2; |
353 |
} |
354 |
|
298 |
|
355 |
close(fd); |
299 |
msgs.msgs[msgs.nmsgs - 1].slave = i2c_opt.addr; |
356 |
return (0); |
300 |
msgs.msgs[msgs.nmsgs - 1].len = i2c_opt.count; |
|
|
301 |
msgs.msgs[msgs.nmsgs - 1].buf = i2c_buf; |
357 |
|
302 |
|
358 |
err1: |
303 |
if (i2c_opt.dir == 'r') |
359 |
cmd.slave = i2c_opt.addr; |
304 |
msgs.msgs[msgs.nmsgs - 1].flags = IIC_M_RD; |
360 |
error = ioctl(fd, I2CSTOP, &cmd); |
305 |
else |
361 |
if (error == -1) |
306 |
msgs.msgs[msgs.nmsgs - 1].flags = IIC_M_WR; |
362 |
fprintf(stderr, "error sending stop condtion\n"); |
|
|
363 |
err2: |
364 |
if (err_msg) |
365 |
fprintf(stderr, "%s", err_msg); |
366 |
|
307 |
|
367 |
close(fd); |
308 |
if (i2c_opt.mode == I2C_MODE_NONE) |
368 |
return (1); |
309 |
msgs.msgs[msgs.nmsgs - 1].flags |= IIC_M_NOSTART; |
369 |
} |
|
|
370 |
|
310 |
|
371 |
static int |
311 |
error = ioctl(fd, I2CRDWR, &msgs); |
372 |
i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) |
|
|
373 |
{ |
374 |
struct iiccmd cmd; |
375 |
int i, fd, error, bufsize; |
376 |
char *err_msg, data = 0, *buf; |
377 |
|
378 |
fd = open(dev, O_RDWR); |
379 |
if (fd == -1) |
380 |
err(1, "open failed"); |
381 |
|
382 |
bzero(&cmd, sizeof(cmd)); |
383 |
|
384 |
if (i2c_opt.width) { |
385 |
cmd.slave = i2c_opt.addr; |
386 |
cmd.count = 1; |
387 |
cmd.last = 0; |
388 |
cmd.buf = &data; |
389 |
error = ioctl(fd, I2CSTART, &cmd); |
390 |
if (error == -1) { |
391 |
err_msg = "ioctl: error sending start condition"; |
392 |
goto err1; |
393 |
} |
394 |
bufsize = i2c_opt.width / 8; |
395 |
buf = prepare_buf(bufsize, i2c_opt.off); |
396 |
if (buf == NULL) { |
397 |
err_msg = "error: offset malloc"; |
398 |
goto err1; |
399 |
} |
400 |
|
401 |
cmd.count = bufsize; |
402 |
cmd.buf = buf; |
403 |
cmd.last = 0; |
404 |
error = ioctl(fd, I2CWRITE, &cmd); |
405 |
free(buf); |
406 |
if (error == -1) { |
407 |
err_msg = "ioctl: error when write offset"; |
408 |
goto err1; |
409 |
} |
410 |
|
411 |
if (i2c_opt.mode == I2C_MODE_STOP_START) { |
412 |
cmd.slave = i2c_opt.addr; |
413 |
error = ioctl(fd, I2CSTOP, &cmd); |
414 |
if (error == -1) { |
415 |
err_msg = "error sending stop condtion\n"; |
416 |
goto err2; |
417 |
} |
418 |
} |
419 |
} |
420 |
cmd.slave = i2c_opt.addr; |
421 |
cmd.count = 1; |
422 |
cmd.last = 0; |
423 |
cmd.buf = &data; |
424 |
if (i2c_opt.mode == I2C_MODE_STOP_START) { |
425 |
error = ioctl(fd, I2CSTART, &cmd); |
426 |
if (error == -1) { |
427 |
err_msg = "ioctl: error sending start condition"; |
428 |
goto err1; |
429 |
} |
430 |
} else if (i2c_opt.mode == I2C_MODE_REPEATED_START) { |
431 |
error = ioctl(fd, I2CRPTSTART, &cmd); |
432 |
if (error == -1) { |
433 |
err_msg = "ioctl: error sending repeated start " |
434 |
"condition"; |
435 |
goto err1; |
436 |
} |
437 |
} |
438 |
error = ioctl(fd, I2CSTOP, &cmd); |
439 |
if (error == -1) { |
312 |
if (error == -1) { |
440 |
err_msg = "error sending stop condtion\n"; |
313 |
err_msg = "error sending i2c frame\n"; |
441 |
goto err2; |
314 |
goto err; |
442 |
} |
315 |
} |
443 |
|
316 |
|
444 |
for (i = 0; i < i2c_opt.count; i++) { |
|
|
445 |
error = read(fd, &i2c_buf[i], 1); |
446 |
if (error == -1) { |
447 |
err_msg = "ioctl: error while reading"; |
448 |
goto err1; |
449 |
} |
450 |
} |
451 |
|
452 |
close(fd); |
317 |
close(fd); |
453 |
return (0); |
318 |
return (0); |
454 |
|
319 |
|
455 |
err1: |
320 |
err: |
456 |
cmd.slave = i2c_opt.addr; |
|
|
457 |
error = ioctl(fd, I2CSTOP, &cmd); |
458 |
if (error == -1) |
459 |
fprintf(stderr, "error sending stop condtion\n"); |
460 |
err2: |
461 |
if (err_msg) |
321 |
if (err_msg) |
462 |
fprintf(stderr, "%s", err_msg); |
322 |
fprintf(stderr, "%s", err_msg); |
463 |
|
323 |
|
Lines 594-613
Link Here
|
594 |
if (i2c_buf == NULL) |
454 |
if (i2c_buf == NULL) |
595 |
err(1, "data malloc"); |
455 |
err(1, "data malloc"); |
596 |
|
456 |
|
597 |
if (i2c_opt.dir == 'w') { |
457 |
error = i2c_read_write(dev, i2c_opt, i2c_buf); |
598 |
error = i2c_write(dev, i2c_opt, i2c_buf); |
458 |
if (error) { |
599 |
if (error) { |
459 |
free(i2c_buf); |
600 |
free(i2c_buf); |
460 |
return (1); |
601 |
return (1); |
|
|
602 |
} |
603 |
} |
461 |
} |
604 |
if (i2c_opt.dir == 'r') { |
|
|
605 |
error = i2c_read(dev, i2c_opt, i2c_buf); |
606 |
if (error) { |
607 |
free(i2c_buf); |
608 |
return (1); |
609 |
} |
610 |
} |
611 |
|
462 |
|
612 |
if (i2c_opt.verbose) |
463 |
if (i2c_opt.verbose) |
613 |
fprintf(stderr, "\nData %s (hex):\n", i2c_opt.dir == 'r' ? |
464 |
fprintf(stderr, "\nData %s (hex):\n", i2c_opt.dir == 'r' ? |