Here is my (perhaps obvious) solution for I2C communication between the Pi and 5 V powered chips: Since the Pi has its own internal pull-ups on the I2C data lines you can simply remove the pull-ups on your breakout board.
- removed_pullups.jpg (187.96 KiB) Viewed 867 times
Here I have removed the two 10k pull-up resistors on an Adafruit HT16K33 breakout, which is pretty easy to do. I find it rather annoying to need so many level shifters every time I build something with a Pi; this is a convenient way to eliminate one of them. Nota bene: this may not work well on long I2C lines - though the Pi's pull-ups are fairly hard at just 1.8k, which should be enough to carry over any reasonable distance. It's also worth noting that 3.3 V I2C comms works reliably despite
the HT16K33 datasheet
specifying a minimum "high" voltage on the SDA/SCL lines of 0.7 x VDD, or 3.5 V:
- Screenshot_2020-07-17_12-50-50.png (80.57 KiB) Viewed 867 times
Obviously there's some margin there. Other chips may
require higher voltages, in which case a 5 V I2C bus may
be required. Yet other chips may
have internal pull-ups which cannot be removed. Personally I don't recall encountering either. YMMV.