]> Zhao Yanbai Git Server - minix.git/commitdiff
libi2cdriver: add functions for IC register access 26/826/4
authorThomas Cort <tcort@minix3.org>
Mon, 16 Sep 2013 17:33:00 +0000 (13:33 -0400)
committerThomas Cort <tcort@minix3.org>
Wed, 18 Sep 2013 12:10:26 +0000 (08:10 -0400)
Many i2c device drivers used similar code to access registers on
the ICs they drive. This commit implements that functionality in
libi2cdriver and updates the drivers to use the library instead of
their own register access functions. The net result is 375+ fewer
lines of code and less work for people developing new drivers.

The two exceptions were cat24c256 and parts of tda19988. They access
the bus in uncommon ways. It doesn't make sense at this time to
move their read/write functions into libi2cdriver.

Change-Id: Id8280b71af33b710a49944d7f20a7262be9f5988

drivers/bmp085/bmp085.c
drivers/sht21/sht21.c
drivers/tda19988/tda19988.c
drivers/tps65217/tps65217.c
drivers/tps65950/rtc.c
drivers/tps65950/tps65950.c
drivers/tps65950/tps65950.h
drivers/tsl2550/tsl2550.c
include/minix/i2cdriver.h
lib/libi2cdriver/i2cdriver.c

index 7765580719529422d04636c4b31702d14a8f4df3..a7dddb244b2850fe3325f70461f96084b7bf1d26 100644 (file)
@@ -157,12 +157,6 @@ static int bmp085_transfer(endpoint_t endpt, int opcode, u64_t position,
     unsigned int UNUSED(flags));
 static int bmp085_other(message * m);
 
-/* i2c bus access */
-static int reg_read(uint8_t reg, uint8_t * val);
-static int reg_read16(uint8_t reg, uint16_t * val);
-static int reg_read24(uint8_t reg, uint32_t * val);
-static int reg_write(uint8_t reg, uint8_t val);
-
 /* SEF Function */
 static int sef_cb_lu_state_save(int);
 static int lu_state_restore(void);
@@ -188,159 +182,6 @@ static struct device bmp085_device = {
        .dv_size = 0
 };
 
-static int
-reg_read(uint8_t reg, uint8_t * val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (val == NULL) {
-               log_warn(&log, "reg_read() called with NULL pointer\n");
-               return -1;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 1 byte */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       *val = ioctl_exec.iie_buf[0];
-
-       log_trace(&log, "Read 0x%x from reg 0x%x\n", *val, reg);
-
-       return OK;
-}
-
-static int
-reg_read16(uint8_t reg, uint16_t * val)
-{
-       int r;
-       uint8_t msb, lsb;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (val == NULL) {
-               log_warn(&log, "reg_read16() called with NULL pointer\n");
-               return -1;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 2 bytes */
-       ioctl_exec.iie_buflen = 2;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read16() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       msb = ioctl_exec.iie_buf[0];
-       lsb = ioctl_exec.iie_buf[1];
-
-       *val = ((msb << 8) | lsb);
-
-       log_trace(&log, "Read 0x%x from reg 0x%x\n", *val, reg);
-
-       return OK;
-
-}
-
-static int
-reg_read24(uint8_t reg, uint32_t * val)
-{
-       int r;
-       uint8_t msb, lsb, xlsb;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (val == NULL) {
-               log_warn(&log, "reg_read24() called with NULL pointer\n");
-               return -1;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 3 bytes */
-       ioctl_exec.iie_buflen = 3;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read24() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       msb = ioctl_exec.iie_buf[0];
-       lsb = ioctl_exec.iie_buf[1];
-       xlsb = ioctl_exec.iie_buf[2];
-
-       *val = ((msb << 16) | (lsb << 8) | xlsb);
-
-       log_trace(&log, "Read 0x%x from reg 0x%x\n", *val, reg);
-
-       return OK;
-
-}
-
-static int
-reg_write(uint8_t reg, uint8_t val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* no commands here */
-       ioctl_exec.iie_cmdlen = 0;
-
-       /* write register and value */
-       ioctl_exec.iie_buf[0] = reg;
-       ioctl_exec.iie_buf[1] = val;
-       ioctl_exec.iie_buflen = 2;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_write() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       log_trace(&log, "Wrote 0x%x to reg 0x%x\n", val, reg);
-
-       return OK;
-}
-
 /*
  * Initialize the driver. Checks the CHIPID against a known value and
  * reads the calibration coefficients.
@@ -373,7 +214,7 @@ version_check(void)
        int r;
        uint8_t chipid;
 
-       r = reg_read(CHIPID_REG, &chipid);
+       r = i2creg_read8(bus_endpoint, address, CHIPID_REG, &chipid);
        if (r != OK) {
                log_warn(&log, "Couldn't read CHIPID\n");
                return -1;
@@ -400,67 +241,67 @@ read_cal_coef(void)
        int r;
 
        /* Populate the calibration struct with values */
-       r = reg_read16(AC1_MSB_REG, &cal.ac1);
+       r = i2creg_read16(bus_endpoint, address, AC1_MSB_REG, &cal.ac1);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac1 = %d\n", cal.ac1);
 
-       r = reg_read16(AC2_MSB_REG, &cal.ac2);
+       r = i2creg_read16(bus_endpoint, address, AC2_MSB_REG, &cal.ac2);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac2 = %d\n", cal.ac2);
 
-       r = reg_read16(AC3_MSB_REG, &cal.ac3);
+       r = i2creg_read16(bus_endpoint, address, AC3_MSB_REG, &cal.ac3);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac3 = %d\n", cal.ac3);
 
-       r = reg_read16(AC4_MSB_REG, &cal.ac4);
+       r = i2creg_read16(bus_endpoint, address, AC4_MSB_REG, &cal.ac4);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac4 = %u\n", cal.ac4);
 
-       r = reg_read16(AC5_MSB_REG, &cal.ac5);
+       r = i2creg_read16(bus_endpoint, address, AC5_MSB_REG, &cal.ac5);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac5 = %u\n", cal.ac5);
 
-       r = reg_read16(AC6_MSB_REG, &cal.ac6);
+       r = i2creg_read16(bus_endpoint, address, AC6_MSB_REG, &cal.ac6);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.ac6 = %u\n", cal.ac6);
 
-       r = reg_read16(B1_MSB_REG, &cal.b1);
+       r = i2creg_read16(bus_endpoint, address, B1_MSB_REG, &cal.b1);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.b1 = %d\n", cal.b1);
 
-       r = reg_read16(B2_MSB_REG, &cal.b2);
+       r = i2creg_read16(bus_endpoint, address, B2_MSB_REG, &cal.b2);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.b2 = %d\n", cal.b2);
 
-       r = reg_read16(MB_MSB_REG, &cal.mb);
+       r = i2creg_read16(bus_endpoint, address, MB_MSB_REG, &cal.mb);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.mb = %d\n", cal.mb);
 
-       r = reg_read16(MC_MSB_REG, &cal.mc);
+       r = i2creg_read16(bus_endpoint, address, MC_MSB_REG, &cal.mc);
        if (r != OK) {
                return -1;
        }
        log_debug(&log, "cal.mc = %d\n", cal.mc);
 
-       r = reg_read16(MD_MSB_REG, &cal.md);
+       r = i2creg_read16(bus_endpoint, address, MD_MSB_REG, &cal.md);
        if (r != OK) {
                return -1;
        }
@@ -516,7 +357,7 @@ measure(int32_t * temperature, int32_t * pressure)
        log_debug(&log, "Triggering Temp Reading...\n");
 
        /* trigger temperature reading */
-       r = reg_write(CTRL_REG, CMD_TRIG_T);
+       r = i2creg_write8(bus_endpoint, address, CTRL_REG, CMD_TRIG_T);
        if (r != OK) {
                log_warn(&log, "Failed to trigger temperature reading.\n");
                return -1;
@@ -526,7 +367,7 @@ measure(int32_t * temperature, int32_t * pressure)
        micro_delay(UDELAY_T);
 
        /* read the uncompensated temperature */
-       r = reg_read16(SENSOR_VAL_MSB_REG, &ut);
+       r = i2creg_read16(bus_endpoint, address, SENSOR_VAL_MSB_REG, &ut);
        if (r != OK) {
                log_warn(&log, "Failed to read temperature.\n");
                return -1;
@@ -537,7 +378,7 @@ measure(int32_t * temperature, int32_t * pressure)
        log_debug(&log, "Triggering Pressure Reading...\n");
 
        /* trigger pressure reading */
-       r = reg_write(CTRL_REG, p_cmd->cmd);
+       r = i2creg_write8(bus_endpoint, address, CTRL_REG, p_cmd->cmd);
        if (r != OK) {
                log_warn(&log, "Failed to trigger pressure reading.\n");
                return -1;
@@ -547,7 +388,7 @@ measure(int32_t * temperature, int32_t * pressure)
        micro_delay(p_cmd->udelay);
 
        /* read the uncompensated pressure */
-       r = reg_read24(SENSOR_VAL_MSB_REG, &up);
+       r = i2creg_read24(bus_endpoint, address, SENSOR_VAL_MSB_REG, &up);
        if (r != OK) {
                log_warn(&log, "Failed to read pressure.\n");
                return -1;
index cb9f327d27e4ce7cdeb05b3379d49a97cf8e4379..4f96f6bfadd95f2cee145dd67bfc2dae0b332e40 100644 (file)
@@ -106,8 +106,6 @@ static int32_t cached_rh = 0.0;
 
 /* main driver functions */
 static int sht21_init(void);
-static int soft_reset(void);
-static int usr_reg_read(uint8_t * usr_reg_val);
 static int sensor_read(enum sht21_sensors sensor, int32_t * measurement);
 static int measure(void);
 
@@ -148,30 +146,18 @@ static struct device sht21_device = {
 };
 
 /*
- * Sends the chip a soft reset command and waits 15 ms for the chip to reset.
+ * Performs a soft reset and reads the contents of the user register to ensure
+ * that the chip is in a good state and working properly.
  */
 static int
-soft_reset(void)
+sht21_init(void)
 {
        int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to chip */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* No command bytes for writing to this chip */
-       ioctl_exec.iie_cmdlen = 0;
-
-       /* Set the byte to write */
-       ioctl_exec.iie_buf[0] = CMD_SOFT_RESET;
-       ioctl_exec.iie_buflen = 1;
+       uint8_t usr_reg_val;
 
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
+       /* Perform a soft-reset */
+       r = i2creg_raw_write8(bus_endpoint, address, CMD_SOFT_RESET);
        if (r != OK) {
-               log_warn(&log, "soft_reset() failed (r=%d)\n", r);
                return -1;
        }
 
@@ -180,65 +166,7 @@ soft_reset(void)
 
        log_debug(&log, "Soft Reset Complete\n");
 
-       return OK;
-}
-
-/*
- * Obtain the contents of the usr register and store it in usr_reg_val.
- */
-static int
-usr_reg_read(uint8_t * usr_reg_val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (usr_reg_val == NULL) {
-               log_warn(&log, "usr_reg_read() called with NULL pointer\n");
-               return -1;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* Send the read from user register command */
-       ioctl_exec.iie_cmd[0] = CMD_RD_USR_REG;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* Read the register contents into iie_buf */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "usr_reg_read() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       *usr_reg_val = ioctl_exec.iie_buf[0];
-
-       log_trace(&log, "Read 0x%x from USR_REG\n", *usr_reg_val);
-
-       return OK;
-}
-
-/*
- * Performs a soft reset and reads the contents of the user register to ensure
- * that the chip is in a good state and working properly.
- */
-static int
-sht21_init(void)
-{
-       int r;
-       uint8_t usr_reg_val;
-
-       r = soft_reset();
-       if (r != OK) {
-               return -1;
-       }
-
-       r = usr_reg_read(&usr_reg_val);
+       r = i2creg_read8(bus_endpoint, address, CMD_RD_USR_REG, &usr_reg_val);
        if (r != OK) {
                return -1;
        }
@@ -270,10 +198,10 @@ sensor_read(enum sht21_sensors sensor, int32_t * measurement)
 {
        int r;
        uint8_t cmd;
-       uint8_t val_hi, val_lo;
        uint16_t val;
+       uint8_t bytes[2];
+       uint32_t val32;
        uint8_t expected_crc;
-       minix_i2c_ioctl_exec_t ioctl_exec;
 
        switch (sensor) {
        case SHT21_T:
@@ -292,36 +220,23 @@ sensor_read(enum sht21_sensors sensor, int32_t * measurement)
                return -1;
        }
 
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* Send the trigger command */
-       ioctl_exec.iie_cmd[0] = cmd;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* Read the results */
-       ioctl_exec.iie_buflen = 3;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
+       r = i2creg_read24(bus_endpoint, address, cmd, &val32);
        if (r != OK) {
                log_warn(&log, "sensor_read() failed (r=%d)\n", r);
                return -1;
        }
 
-       expected_crc = ioctl_exec.iie_buf[2];
+       expected_crc = val32 & 0xff;
+       val = (val32 >> 8) & 0xffff;
+
+       bytes[0] = (val >> 8) & 0xff;
+       bytes[1] = val & 0xff;
 
-       r = checksum(ioctl_exec.iie_buf, 2, expected_crc);
+       r = checksum(bytes, 2, expected_crc);
        if (r != OK) {
                return -1;
        }
 
-       val_hi = ioctl_exec.iie_buf[0];
-       val_lo = ioctl_exec.iie_buf[1];
-       val = ((val_hi << 8) | val_lo);
-
        val &= ~STATUS_BITS_MASK;       /* clear status bits */
 
        log_debug(&log, "Read VAL:0x%x CRC:0x%x\n", val, expected_crc);
index 81f40bcb5368352d310a94d41c60e6f90e0ba799..c8bbeff9ad7d571affd3de91179a067ac46bcd58 100644 (file)
@@ -375,28 +375,15 @@ static int
 is_display_connected(void)
 {
        int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from CEC */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = cec_address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = CEC_STATUS_REG;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 1 byte */
-       ioctl_exec.iie_buflen = 1;
+       uint8_t val;
 
-       r = i2cdriver_exec(cec_bus_endpoint, &ioctl_exec);
+       r = i2creg_read8(cec_bus_endpoint, cec_address, CEC_STATUS_REG, &val);
        if (r != OK) {
                log_warn(&log, "Reading connection status failed (r=%d)\n", r);
                return -1;
        }
 
-       if ((CEC_STATUS_CONNECTED_MASK & ioctl_exec.iie_buf[0]) == 0) {
+       if ((CEC_STATUS_CONNECTED_MASK & val) == 0) {
                log_debug(&log, "No Display Detected\n");
                return 0;
        } else {
@@ -412,20 +399,9 @@ static int
 enable_hdmi_module(void)
 {
        int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to CEC */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = cec_address;
-
-       /* write the register address and value */
-       ioctl_exec.iie_buf[0] = CEC_ENABLE_REG;
-       ioctl_exec.iie_buf[1] = CEC_ENABLE_ALL_MASK;
-       ioctl_exec.iie_buflen = 2;
 
-       r = i2cdriver_exec(cec_bus_endpoint, &ioctl_exec);
+       r = i2creg_write8(cec_bus_endpoint, cec_address, CEC_ENABLE_REG,
+           CEC_ENABLE_ALL_MASK);
        if (r != OK) {
                log_warn(&log, "Writing enable bits failed (r=%d)\n", r);
                return -1;
@@ -444,7 +420,8 @@ set_page(uint8_t page)
 
        if (page != current_page) {
 
-               r = hdmi_write(HDMI_PAGELESS, HDMI_PAGE_SELECT_REG, page);
+               r = i2creg_write8(hdmi_bus_endpoint, hdmi_address,
+                   HDMI_PAGE_SELECT_REG, page);
                if (r != OK) {
                        return r;
                }
@@ -508,7 +485,6 @@ hdmi_read(uint8_t page, uint8_t reg, uint8_t * val)
 {
 
        int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
 
        if (val == NULL) {
                log_warn(&log, "Read called with NULL pointer\n");
@@ -523,27 +499,12 @@ hdmi_read(uint8_t page, uint8_t reg, uint8_t * val)
                }
        }
 
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from HDMI */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = hdmi_address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 1 byte */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(hdmi_bus_endpoint, &ioctl_exec);
+       r = i2creg_read8(hdmi_bus_endpoint, hdmi_address, reg, val);
        if (r != OK) {
                log_warn(&log, "hdmi_read() failed (r=%d)\n", r);
                return -1;
        }
 
-       *val = ioctl_exec.iie_buf[0];
-
        log_trace(&log, "Read 0x%x from reg 0x%x in page 0x%x\n", *val, reg,
            page);
 
@@ -553,9 +514,7 @@ hdmi_read(uint8_t page, uint8_t reg, uint8_t * val)
 static int
 hdmi_write(uint8_t page, uint8_t reg, uint8_t val)
 {
-
        int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
 
        if (page != HDMI_PAGELESS) {
                r = set_page(page);
@@ -565,18 +524,7 @@ hdmi_write(uint8_t page, uint8_t reg, uint8_t val)
                }
        }
 
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to HDMI */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = hdmi_address;
-
-       /* write the register address and value */
-       ioctl_exec.iie_buf[0] = reg;
-       ioctl_exec.iie_buf[1] = val;
-       ioctl_exec.iie_buflen = 2;
-
-       r = i2cdriver_exec(hdmi_bus_endpoint, &ioctl_exec);
+       r = i2creg_write8(hdmi_bus_endpoint, hdmi_address, reg, val);
        if (r != OK) {
                log_warn(&log, "hdmi_write() failed (r=%d)\n", r);
                return -1;
index 63d943f6a25c8ea0ac1ba3679192fe58ddf2acbf..eac833ae3f16afb8bcd2ca7f33c3f818a7c844e7 100644 (file)
@@ -101,10 +101,6 @@ static struct log log = {
        .log_func = default_log
 };
 
-/* Register Access */
-static int reg_read(uint8_t reg, uint8_t * val);
-static int reg_write(uint8_t reg, uint8_t val);
-
 /* Device Specific Functions */
 static int check_revision(void);
 static int enable_pwr_off(void);
@@ -118,87 +114,13 @@ static int sef_cb_lu_state_save(int);
 static int lu_state_restore(void);
 static int sef_cb_init(int type, sef_init_info_t * info);
 
-static int
-reg_read(uint8_t reg, uint8_t * val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (val == NULL) {
-               log_warn(&log, "Read called with NULL pointer\n");
-               return EINVAL;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 1 byte */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       *val = ioctl_exec.iie_buf[0];
-
-       log_trace(&log, "Read 0x%x from reg 0x%x", *val, reg);
-
-       return OK;
-}
-
-static int
-reg_write(uint8_t reg, uint8_t val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (reg >= 0x0d) {
-               /* TODO: writes to password protected registers hasn't
-                * been implemented since nothing in this driver needs to
-                * write to them. When needed, it should be implemented.
-                */
-               log_warn(&log, "Cannot write to protected registers.");
-               return -1;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to chip */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* write the register address and value */
-       ioctl_exec.iie_buf[0] = reg;
-       ioctl_exec.iie_buf[1] = val;
-       ioctl_exec.iie_buflen = 2;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_write() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       log_trace(&log, "Successfully wrote 0x%x to reg 0x%x\n", val, reg);
-
-       return OK;
-}
-
 static int
 check_revision(void)
 {
        int r;
        uint8_t chipid;
 
-       r = reg_read(CHIPID_REG, &chipid);
+       r = i2creg_read8(bus_endpoint, address, CHIPID_REG, &chipid);
        if (r != OK) {
                log_warn(&log, "Failed to read CHIPID\n");
                return -1;
@@ -235,7 +157,7 @@ enable_pwr_off(void)
         * system is ready to be powered off. Should be called during startup
         * so that shutdown(8) can do power-off with reboot(RBT_POWEROFF).
         */
-       r = reg_write(STATUS_REG, PWR_OFF_MASK);
+       r = i2creg_write8(bus_endpoint, address, STATUS_REG, PWR_OFF_MASK);
        if (r != OK) {
                log_warn(&log, "Cannot set power off mask.");
                return -1;
@@ -274,14 +196,14 @@ intr_enable(void)
        }
 
        /* Enable/Disable interrupts in the TPS65217 */
-       r = reg_write(INT_REG, DEFAULT_INT_MASK);
+       r = i2creg_write8(bus_endpoint, address, INT_REG, DEFAULT_INT_MASK);
        if (r != OK) {
                log_warn(&log, "Failed to set interrupt mask.\n");
                return -1;
        }
 
        /* Read from the interrupt register to clear any pending interrupts */
-       r = reg_read(INT_REG, &val);
+       r = i2creg_read8(bus_endpoint, address, INT_REG, &val);
        if (r != OK) {
                log_warn(&log, "Failed to read interrupt register.\n");
                return -1;
@@ -298,7 +220,7 @@ intr_handler(void)
        struct tm t;
 
        /* read interrupt register to get interrupt that fired and clear it */
-       r = reg_read(INT_REG, &val);
+       r = i2creg_read8(bus_endpoint, address, INT_REG, &val);
        if (r != OK) {
                log_warn(&log, "Failed to read interrupt register.\n");
                return -1;
index c3a13f0d2b84c1bb4fb7cb4caab0f913d6af1b7c..9a683556a9f82143d8548c747de01ce136a7a8f4 100644 (file)
@@ -26,13 +26,14 @@ rtc_init(void)
        uint8_t val;
        struct tm t;
 
-       r = reg_set(ID4, RTC_CTRL_REG, (1 << STOP_RTC_BIT));
+       r = i2creg_set_bits8(bus_endpoint, addresses[ID4], RTC_CTRL_REG,
+           (1 << STOP_RTC_BIT));
        if (r != OK) {
                log_warn(&log, "Failed to start RTC\n");
                return -1;
        }
 
-       r = reg_read(ID4, RTC_STATUS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], RTC_STATUS_REG, &val);
        if (r != OK) {
                log_warn(&log, "Failed to read RTC_STATUS_REG\n");
                return -1;
@@ -59,7 +60,8 @@ rtc_get_time(struct tm *t, int flags)
        /* Write GET_TIME_BIT to RTC_CTRL_REG to latch the RTC values into
         * the RTC registers. This is required before each read.
         */
-       r = reg_set(ID4, RTC_CTRL_REG, (1 << GET_TIME_BIT));
+       r = i2creg_set_bits8(bus_endpoint, addresses[ID4], RTC_CTRL_REG,
+           (1 << GET_TIME_BIT));
        if (r != OK) {
                return -1;
        }
@@ -67,42 +69,42 @@ rtc_get_time(struct tm *t, int flags)
        /* Read and Convert BCD to binary (default RTC mode). */
 
        /* Seconds - 0 to 59 */
-       r = reg_read(ID4, SECONDS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], SECONDS_REG, &val);
        if (r != OK) {
                return -1;
        }
        t->tm_sec = bcd_to_dec(val & 0x7f);
 
        /* Minutes - 0 to 59 */
-       r = reg_read(ID4, MINUTES_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], MINUTES_REG, &val);
        if (r != OK) {
                return -1;
        }
        t->tm_min = bcd_to_dec(val & 0x7f);
 
        /* Hours - 0 to 23 */
-       r = reg_read(ID4, HOURS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], HOURS_REG, &val);
        if (r != OK) {
                return -1;
        }
        t->tm_hour = bcd_to_dec(val & 0x3f);
 
        /* Days - 1 to 31 */
-       r = reg_read(ID4, DAYS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], DAYS_REG, &val);
        if (r != OK) {
                return -1;
        }
        t->tm_mday = bcd_to_dec(val & 0x3f);
 
        /* Months - Jan=1 to Dec=12 */
-       r = reg_read(ID4, MONTHS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], MONTHS_REG, &val);
        if (r != OK) {
                return -1;
        }
        t->tm_mon = bcd_to_dec(val & 0x1f) - 1;
 
        /* Years - last 2 digits of year */
-       r = reg_read(ID4, YEARS_REG, &val);
+       r = i2creg_read8(bus_endpoint, addresses[ID4], YEARS_REG, &val);
        if (r != OK) {
                return -1;
        }
@@ -129,32 +131,38 @@ rtc_set_time(struct tm *t, int flags)
        int r;
 
        /* Write the date/time to the RTC registers. */
-       r = reg_write(ID4, SECONDS_REG, (dec_to_bcd(t->tm_sec) & 0x7f));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], SECONDS_REG,
+           (dec_to_bcd(t->tm_sec) & 0x7f));
        if (r != OK) {
                return -1;
        }
 
-       r = reg_write(ID4, MINUTES_REG, (dec_to_bcd(t->tm_min) & 0x7f));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], MINUTES_REG,
+           (dec_to_bcd(t->tm_min) & 0x7f));
        if (r != OK) {
                return -1;
        }
 
-       r = reg_write(ID4, HOURS_REG, (dec_to_bcd(t->tm_hour) & 0x3f));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], HOURS_REG,
+           (dec_to_bcd(t->tm_hour) & 0x3f));
        if (r != OK) {
                return -1;
        }
 
-       r = reg_write(ID4, DAYS_REG, (dec_to_bcd(t->tm_mday) & 0x3f));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], DAYS_REG,
+           (dec_to_bcd(t->tm_mday) & 0x3f));
        if (r != OK) {
                return -1;
        }
 
-       r = reg_write(ID4, MONTHS_REG, (dec_to_bcd(t->tm_mon + 1) & 0x1f));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], MONTHS_REG,
+           (dec_to_bcd(t->tm_mon + 1) & 0x1f));
        if (r != OK) {
                return -1;
        }
 
-       r = reg_write(ID4, YEARS_REG, (dec_to_bcd(t->tm_year % 100) & 0xff));
+       r = i2creg_write8(bus_endpoint, addresses[ID4], YEARS_REG,
+           (dec_to_bcd(t->tm_year % 100) & 0xff));
        if (r != OK) {
                return -1;
        }
index 2f139e073f2771c7f8e16c302b3f835c713efa4a..b6167c067bfe99e05198f4fe0862b6439df3119e 100644 (file)
@@ -28,11 +28,10 @@ static i2c_addr_t valid_addrs[2] = {
 static uint32_t bus;
 
 /* endpoint for the driver for the bus itself. */
-static endpoint_t bus_endpoint;
+endpoint_t bus_endpoint;
 
 /* slave addresses of the device */
-#define NADDRESSES 4
-static i2c_addr_t addresses[NADDRESSES] = {
+i2c_addr_t addresses[NADDRESSES] = {
        0x48, 0x49, 0x4a, 0x4b
 };
 
@@ -49,123 +48,6 @@ static int sef_cb_init(int type, sef_init_info_t * info);
 static int fetch_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t);
 static int store_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t);
 
-int
-reg_read(uint8_t id, uint8_t reg, uint8_t * val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (id < 0 || id >= NADDRESSES) {
-               log_warn(&log, "id parameter out of range.\n");
-               return EINVAL;
-       }
-
-       if (val == NULL) {
-               log_warn(&log, "Read called with NULL pointer\n");
-               return EINVAL;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = addresses[id];
-
-       /* write the register address */
-       ioctl_exec.iie_cmd[0] = reg;
-       ioctl_exec.iie_cmdlen = 1;
-
-       /* read 1 byte */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       *val = ioctl_exec.iie_buf[0];
-
-       log_trace(&log, "Read 0x%x from reg 0x%x", *val, reg);
-
-       return OK;
-}
-
-int
-reg_write(uint8_t id, uint8_t reg, uint8_t val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (id < 0 || id >= NADDRESSES) {
-               log_warn(&log, "id parameter out of range.\n");
-               return EINVAL;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to chip */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = addresses[id];
-
-       /* write the register address and value */
-       ioctl_exec.iie_buf[0] = reg;
-       ioctl_exec.iie_buf[1] = val;
-       ioctl_exec.iie_buflen = 2;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_write() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       log_trace(&log, "Successfully wrote 0x%x to reg 0x%x\n", val, reg);
-
-       return OK;
-}
-
-int
-reg_set(uint8_t id, uint8_t reg, uint8_t mask)
-{
-       int r;
-       uint8_t val;
-
-       r = reg_read(id, reg, &val);
-       if (r != OK) {
-               return -1;
-       }
-
-       val |= mask;
-
-       r = reg_write(id, reg, val);
-       if (r != OK) {
-               return -1;
-       }
-
-       return OK;
-}
-
-int
-reg_clear(uint8_t id, uint8_t reg, uint8_t mask)
-{
-       int r;
-       uint8_t val;
-
-       r = reg_read(id, reg, &val);
-       if (r != OK) {
-               return -1;
-       }
-
-       val &= ~mask;
-
-       r = reg_write(id, reg, val);
-       if (r != OK) {
-               return -1;
-       }
-
-       return OK;
-}
-
 static int
 fetch_t(endpoint_t ep, cp_grant_id_t gid, struct tm *t)
 {
@@ -204,7 +86,8 @@ check_revision(void)
        uint8_t idcode_7_0, idcode_15_8, idcode_23_16, idcode_31_24;
 
        /* need to write a special code to unlock read protect on IDCODE */
-       r = reg_write(ID2, UNLOCK_TEST_REG, UNLOCK_TEST_CODE);
+       r = i2creg_write8(bus_endpoint, addresses[ID2], UNLOCK_TEST_REG,
+           UNLOCK_TEST_CODE);
        if (r != OK) {
                log_warn(&log, "Failed to write unlock code to UNLOCK_TEST\n");
                return -1;
@@ -213,22 +96,26 @@ check_revision(void)
        /*
         * read each part of the IDCODE
         */
-       r = reg_read(ID2, IDCODE_7_0_REG, &idcode_7_0);
+       r = i2creg_read8(bus_endpoint, addresses[ID2], IDCODE_7_0_REG,
+           &idcode_7_0);
        if (r != OK) {
                log_warn(&log, "Failed to read IDCODE part 1\n");
        }
 
-       r = reg_read(ID2, IDCODE_15_8_REG, &idcode_15_8);
+       r = i2creg_read8(bus_endpoint, addresses[ID2], IDCODE_15_8_REG,
+           &idcode_15_8);
        if (r != OK) {
                log_warn(&log, "Failed to read IDCODE part 2\n");
        }
 
-       r = reg_read(ID2, IDCODE_23_16_REG, &idcode_23_16);
+       r = i2creg_read8(bus_endpoint, addresses[ID2], IDCODE_23_16_REG,
+           &idcode_23_16);
        if (r != OK) {
                log_warn(&log, "Failed to read IDCODE part 3\n");
        }
 
-       r = reg_read(ID2, IDCODE_31_24_REG, &idcode_31_24);
+       r = i2creg_read8(bus_endpoint, addresses[ID2], IDCODE_31_24_REG,
+           &idcode_31_24);
        if (r != OK) {
                log_warn(&log, "Failed to read IDCODE part 4\n");
        }
index 1508f898a1b0fb63351b0d5b71d428285a341668..d410873efe84b3852bc4f3b04e750c2b00a8916d 100644 (file)
 #define RTC_STATUS_REG 0x0000002A
 #define RUN_BIT 1
 
+#define NADDRESSES 4
 
-int reg_read(uint8_t id, uint8_t reg, uint8_t * val);
-int reg_write(uint8_t id, uint8_t reg, uint8_t val);
-int reg_set(uint8_t id, uint8_t reg, uint8_t mask);
-int reg_clear(uint8_t id, uint8_t reg, uint8_t mask);
+extern endpoint_t bus_endpoint;
+extern i2c_addr_t addresses[NADDRESSES];
 
 #endif /* __TPS65950_H */
index 06cc31d7ca8db7bbb46cfdc1e9c4a16c72155acb..f2ba424d12ac6e21ae0c509399c04d2eebfe8cef 100644 (file)
@@ -59,10 +59,6 @@ static i2c_addr_t address;
 /* endpoint for the driver for the bus itself. */
 static endpoint_t bus_endpoint;
 
-/* register access functions */
-static int reg_read(uint8_t * val);
-static int reg_write(uint8_t val);
-
 /* main driver functions */
 static int tsl2550_init(void);
 static int adc_read(int adc, uint8_t * val);
@@ -216,7 +212,7 @@ adc_read(int adc, uint8_t * val)
        *val = (adc == 0) ? CMD_READ_ADC0 : CMD_READ_ADC1;
 
        /* Select the ADC to read from */
-       r = reg_write(*val);
+       r = i2creg_raw_write8(bus_endpoint, address, *val);
        if (r != OK) {
                log_warn(&log, "Failed to write ADC read command.\n");
                return -1;
@@ -230,7 +226,7 @@ adc_read(int adc, uint8_t * val)
         */
        spin_init(&spin, 400000);
        do {
-               r = reg_read(val);
+               r = i2creg_raw_read8(bus_endpoint, address, val);
                if (r != OK) {
                        log_warn(&log, "Failed to read ADC%d value.\n", adc);
                        return -1;
@@ -247,7 +243,7 @@ adc_read(int adc, uint8_t * val)
         * before 400 ms) and left the loop. To ensure there is a final read
         * at or after the 400 ms mark, we try one last time here.
         */
-       r = reg_read(val);
+       r = i2creg_raw_read8(bus_endpoint, address, val);
        if (r != OK) {
                log_warn(&log, "Failed to read ADC%d value.\n", adc);
                return -1;
@@ -261,87 +257,6 @@ adc_read(int adc, uint8_t * val)
        }
 }
 
-static int
-reg_read(uint8_t * val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       if (val == NULL) {
-               log_warn(&log, "Read called with a NULL pointer.\n");
-               return EINVAL;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Read from chip */
-       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* No register address to write */
-       ioctl_exec.iie_cmdlen = 0;
-
-       /* Read one byte */
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_read() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       *val = ioctl_exec.iie_buf[0];
-
-       log_trace(&log, "Read 0x%x from reg\n", *val);
-
-       return OK;
-}
-
-static int
-reg_write(uint8_t val)
-{
-       int r;
-       minix_i2c_ioctl_exec_t ioctl_exec;
-
-       switch (val) {
-       case CMD_PWR_DOWN:
-       case CMD_PWR_UP:
-       case CMD_EXT_RANGE:
-       case CMD_NORM_RANGE:
-       case CMD_READ_ADC0:
-       case CMD_READ_ADC1:
-               /* Command is valid */
-               break;
-       default:
-               log_warn(&log,
-                   "reg_write() called with invalid command 0x%x\n", val);
-               return EINVAL;
-       }
-
-       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
-
-       /* Write to chip */
-       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
-       ioctl_exec.iie_addr = address;
-
-       /* No command bytes for writing to this chip */
-       ioctl_exec.iie_cmdlen = 0;
-
-       /* Set the byte to write */
-       ioctl_exec.iie_buf[0] = val;
-       ioctl_exec.iie_buflen = 1;
-
-       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
-       if (r != OK) {
-               log_warn(&log, "reg_write() failed (r=%d)\n", r);
-               return -1;
-       }
-
-       log_trace(&log, "Wrote 0x%x to reg\n", val);
-
-       return OK;
-}
-
 static int
 tsl2550_init(void)
 {
@@ -349,14 +264,14 @@ tsl2550_init(void)
        uint8_t val;
 
        /* Power on the device */
-       r = reg_write(CMD_PWR_UP);
+       r = i2creg_raw_write8(bus_endpoint, address, CMD_PWR_UP);
        if (r != OK) {
                log_warn(&log, "Power-up command failed.\n");
                return -1;
        }
 
        /* Read power on test value */
-       r = reg_read(&val);
+       r = i2creg_raw_read8(bus_endpoint, address, &val);
        if (r != OK) {
                log_warn(&log, "Failed to read power on test value.\n");
                return -1;
@@ -370,7 +285,7 @@ tsl2550_init(void)
        }
 
        /* Set range to normal */
-       r = reg_write(CMD_NORM_RANGE);
+       r = i2creg_raw_write8(bus_endpoint, address, CMD_NORM_RANGE);
        if (r != OK) {
                log_warn(&log, "Normal range command failed.\n");
                return -1;
index 3dd902cd7545f5ad61588d6313118a504fbe8dd6..778513fe233f91141a053e23d1763f4e104e1528 100644 (file)
@@ -18,4 +18,15 @@ void i2cdriver_handle_bus_update(endpoint_t * bus_endpoint, uint32_t bus,
 int i2cdriver_reserve_device(endpoint_t bus_endpoint, i2c_addr_t address);
 int i2cdriver_exec(endpoint_t bus_endpoint, minix_i2c_ioctl_exec_t *ioctl_exec);
 
+int i2creg_raw_read8(endpoint_t bus, i2c_addr_t addr, uint8_t * val);
+int i2creg_read8(endpoint_t bus, i2c_addr_t addr, uint8_t reg, uint8_t * val);
+int i2creg_read16(endpoint_t bus, i2c_addr_t addr, uint8_t reg, uint16_t * val);
+int i2creg_read24(endpoint_t bus, i2c_addr_t addr, uint8_t reg, uint32_t * val);
+int i2creg_raw_write8(endpoint_t bus, i2c_addr_t addr, uint8_t val);
+int i2creg_write8(endpoint_t bus, i2c_addr_t addr, uint8_t reg, uint8_t val);
+int i2creg_set_bits8(endpoint_t bus, i2c_addr_t addr, uint8_t reg,
+                                                               uint8_t bits);
+int i2creg_clear_bits8(endpoint_t bus, i2c_addr_t addr, uint8_t reg,
+                                                               uint8_t bits);
+
 #endif /* _MINIX_I2CDRIVER_H */
index 755bd8a1fe195a1269fd9e4c34a138c4afbd522a..1a73ba7ed6994690de14be73fae7fa2fa754da92 100644 (file)
@@ -1,5 +1,6 @@
 /* This file contains device independent i2c device driver helpers. */
 
+#include <assert.h>
 #include <minix/drivers.h>
 #include <minix/endpoint.h>
 #include <minix/i2c.h>
@@ -193,3 +194,174 @@ i2cdriver_exec(endpoint_t bus_endpoint, minix_i2c_ioctl_exec_t * ioctl_exec)
 
        return m.REP_STATUS;
 }
+
+static int
+__i2creg_read(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t raw,
+    uint8_t reg, uint32_t * val, size_t vallen)
+{
+       int r, i;
+       minix_i2c_ioctl_exec_t ioctl_exec;
+
+       assert(val != NULL);
+       assert(vallen >= 1 && vallen <= 4);
+
+       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
+
+       /* Read from chip */
+       ioctl_exec.iie_op = I2C_OP_READ_WITH_STOP;
+       ioctl_exec.iie_addr = address;
+
+       if (!raw) {
+               /* write the register address */
+               ioctl_exec.iie_cmd[0] = reg;
+               ioctl_exec.iie_cmdlen = 1;
+       }
+
+       /* read vallen bytes */
+       ioctl_exec.iie_buflen = vallen;
+
+       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
+       if (r != OK) {
+               return -1;
+       }
+
+       for (*val = 0, i = 0; i < vallen; i++) {
+               *val = ((*val) << 8) | ioctl_exec.iie_buf[i];
+       }
+
+       return OK;
+}
+
+int
+i2creg_raw_read8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t * val)
+{
+       int r;
+       uint32_t val32;
+
+       r = __i2creg_read(bus_endpoint, address, 1, 0, &val32, 1);
+       *val = val32 & 0xff;
+
+       return r;
+}
+
+int
+i2creg_read8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint8_t * val)
+{
+       int r;
+       uint32_t val32;
+
+       r = __i2creg_read(bus_endpoint, address, 0, reg, &val32, 1);
+       *val = val32 & 0xff;
+
+       return r;
+}
+
+int
+i2creg_read16(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint16_t * val)
+{
+       int r;
+       uint32_t val32;
+
+       r = __i2creg_read(bus_endpoint, address, 0, reg, &val32, 2);
+       *val = val32 & 0xffff;
+
+       return r;
+}
+
+int
+i2creg_read24(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint32_t * val)
+{
+       return __i2creg_read(bus_endpoint, address, 0, reg, val, 3);
+}
+
+static int
+__i2creg_write(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t raw,
+    uint8_t reg, uint8_t val)
+{
+       int r;
+       minix_i2c_ioctl_exec_t ioctl_exec;
+
+       memset(&ioctl_exec, '\0', sizeof(minix_i2c_ioctl_exec_t));
+
+       /* Write to chip */
+       ioctl_exec.iie_op = I2C_OP_WRITE_WITH_STOP;
+       ioctl_exec.iie_addr = address;
+
+       if (raw) {
+               /* write just the value */
+               ioctl_exec.iie_buf[0] = val;
+               ioctl_exec.iie_buflen = 1;
+       } else {
+               /* write the register address and value */
+               ioctl_exec.iie_buf[0] = reg;
+               ioctl_exec.iie_buf[1] = val;
+               ioctl_exec.iie_buflen = 2;
+       }
+
+       r = i2cdriver_exec(bus_endpoint, &ioctl_exec);
+       if (r != OK) {
+               return -1;
+       }
+
+       return OK;
+}
+
+int
+i2creg_write8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint8_t val)
+{
+       return __i2creg_write(bus_endpoint, address, 0, reg, val);
+}
+
+int
+i2creg_raw_write8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t val)
+{
+       return __i2creg_write(bus_endpoint, address, 1, 0, val);
+}
+
+int
+i2creg_set_bits8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint8_t bits)
+{
+       int r;
+       uint8_t val;
+
+       r = i2creg_read8(bus_endpoint, address, reg, &val);
+       if (r != OK) {
+               return -1;
+       }
+
+       val |= bits;
+
+       r = i2creg_write8(bus_endpoint, address, reg, val);
+       if (r != OK) {
+               return -1;
+       }
+
+       return OK;
+}
+
+int
+i2creg_clear_bits8(endpoint_t bus_endpoint, i2c_addr_t address, uint8_t reg,
+    uint8_t bits)
+{
+       int r;
+       uint8_t val;
+
+       r = i2creg_read8(bus_endpoint, address, reg, &val);
+       if (r != OK) {
+               return -1;
+       }
+
+       val &= ~bits;
+
+       r = i2creg_write8(bus_endpoint, address, reg, val);
+       if (r != OK) {
+               return -1;
+       }
+
+       return OK;
+}