Index: head/usr.sbin/i2c/i2c.8 =================================================================== --- head/usr.sbin/i2c/i2c.8 +++ head/usr.sbin/i2c/i2c.8 @@ -83,6 +83,10 @@ used. .It Fl o Ar offset offset within the device for data transfer (hex). +The default is zero. +Use +.Dq -w 0 +to disable writing of the offset to the slave. .It Fl r reset the controller. .It Fl s @@ -91,6 +95,12 @@ be verbose. .It Fl w Ar 0|8|16 device addressing width (in bits). +This is used to determine how to pass +.Ar offset +specified with +.Fl o +to the slave. +Zero means that the offset is ignored and not passed to the slave at all. .El .Sh WARNINGS Great care must be taken when manipulating slave I2C devices with the Index: head/usr.sbin/i2c/i2c.c =================================================================== --- head/usr.sbin/i2c/i2c.c +++ head/usr.sbin/i2c/i2c.c @@ -212,15 +212,14 @@ use_read_xfer = 1; goto start_over; } - cmd.slave = i << 1; - cmd.last = 1; - ioctl(fd, I2CSTOP, &cmd); + ioctl(fd, I2CSTOP); } if (error == 0) { ++num_found; printf("%02x ", i); } } + /* * If we found nothing, maybe START is not supported and returns a * generic error code such as EIO or ENXIO, so try again using reads. @@ -355,7 +354,7 @@ } } - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "ioctl: error sending stop condition"; goto err2; @@ -439,8 +438,7 @@ } break; } - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "ioctl: error sending stop condition"; goto err2; @@ -450,8 +448,7 @@ return (0); err1: - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) fprintf(stderr, "error sending stop condition\n"); err2: @@ -466,7 +463,7 @@ i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) { struct iiccmd cmd; - int i, fd, error, bufsize; + int fd, error, bufsize; char *err_msg, data = 0, *buf; fd = open(dev, O_RDWR); @@ -503,23 +500,22 @@ } if (i2c_opt.mode == I2C_MODE_STOP_START) { - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) { err_msg = "error sending stop condition"; goto err2; } } } - cmd.slave = i2c_opt.addr; + cmd.slave = i2c_opt.addr | 1; cmd.count = 1; cmd.last = 0; cmd.buf = &data; - if (i2c_opt.mode == I2C_MODE_STOP_START) { + if (i2c_opt.mode == I2C_MODE_STOP_START || i2c_opt.width == 0) { error = ioctl(fd, I2CSTART, &cmd); if (error == -1) { err_msg = "ioctl: error sending start condition"; - goto err1; + goto err2; } } else if (i2c_opt.mode == I2C_MODE_REPEATED_START) { error = ioctl(fd, I2CRPTSTART, &cmd); @@ -529,26 +525,27 @@ goto err1; } } - error = ioctl(fd, I2CSTOP, &cmd); + + cmd.count = i2c_opt.count; + cmd.buf = i2c_buf; + cmd.last = 1; + error = ioctl(fd, I2CREAD, &cmd); if (error == -1) { - err_msg = "error sending stop condition"; - goto err2; + err_msg = "ioctl: error while reading"; + goto err1; } - for (i = 0; i < i2c_opt.count; i++) { - error = read(fd, &i2c_buf[i], 1); - if (error == -1) { - err_msg = "ioctl: error while reading"; - goto err1; - } + error = ioctl(fd, I2CSTOP); + if (error == -1) { + err_msg = "error sending stop condtion\n"; + goto err2; } close(fd); return (0); err1: - cmd.slave = i2c_opt.addr; - error = ioctl(fd, I2CSTOP, &cmd); + error = ioctl(fd, I2CSTOP); if (error == -1) fprintf(stderr, "error sending stop condition\n"); err2: