It is easier than I thought: The OS read function is exactly what is needed and ioctl() is NOT used for the IO as in other cases.
In summary, without error checking:
int MCP3221= open("/dev/i2c-1", O_RDWR); // open I2C1
ioctl(MCP3221, I2C_SLAVE, 0x4D); // use MCP device address
unsigned char buf;
read(MCP3221, buf, 2); // read 2 byte value
The Pi Zero has two hardware I2C buses.
Bus 0 (/dev/i2c-0) uses GPIO 0/1.
Bus 1 (/dev/i2c-1) uses GPIO 2/3.
You can probably use bus 0 as well as bus 1 on a Pi Zero.
An alternative to consider is an I2C bus multiplexor such as the TCA9548A which will allow you to have up to 8 devices sharing the same I2C address.
If the software I2C bus seems super slow that ...
I had the same problem so I made a simple Python wrapper around ecomet_i2c_raspberry_tools for Raspi CM4 IO Board.
Here's the repo: https://github.com/konsou/raspi-cm4-ioboard-fan
It's a work in progress but works on my Pi. Feel free to create issues to the repo if you want something fixed / made easier!
In the end I bitbanged the protocol for fun (not profit).
Implementation is :
Have found a working solution to the control of the fan controller.
User neg2led has created a GitHub project for the kernel driver which includes install instructions here:-
Please note that this is for 64bit kernels only. I can confirm this works with Ubuntu 21.10 on the CM4IO board.
Here's an example of a project which starts custom executables directly from a RAM disk image (/boot/initrd). It's certanly not the earliest place possible, but at least it happens before the root partition is mounted, so this code runs before anything located on the root partition. It's as early as you can get without writing kernel code.
The I2C driver can ...