How to reliably read register positions from an MCP23017 over I2C?
The accepted answer is great, but has an error. For the read sequence, step 4 (Send Stop) should not be issued. The highlighted diagram (red rectangles) actually shows no stop sent after address (ADDR) and before a restart (SR). Transmitting a stop at this point signals other masters that the bus is free and they are open to taking control of the bus. This could result in an arbitration error being generated when the start at point 5 in this example is issued.
The actual steps for a read are:

Start (S)
Transmit OP | W ((OP &lt;&lt; 1) | 0)
Transmit register (ADDR)
Transmit restart (SR) [A restart is just a start without a previous stop)
Transmit OP | R ((OP &lt;&lt; 1) | 1)
Wait for received byte (one or more bytes) - ACK tells slave expecting more bytes
Once all bytes have been received the master needs to signal a NAK to the slave device
Transmit stop (P)