162306a36Sopenharmony_ci============================================ 262306a36Sopenharmony_ciImplementing I2C device drivers in userspace 362306a36Sopenharmony_ci============================================ 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciUsually, I2C devices are controlled by a kernel driver. But it is also 662306a36Sopenharmony_cipossible to access all devices on an adapter from userspace, through 762306a36Sopenharmony_cithe /dev interface. You need to load module i2c-dev for this. 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciEach registered I2C adapter gets a number, counting from 0. You can 1062306a36Sopenharmony_ciexamine /sys/class/i2c-dev/ to see what number corresponds to which adapter. 1162306a36Sopenharmony_ciAlternatively, you can run "i2cdetect -l" to obtain a formatted list of all 1262306a36Sopenharmony_ciI2C adapters present on your system at a given time. i2cdetect is part of 1362306a36Sopenharmony_cithe i2c-tools package. 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciI2C device files are character device files with major device number 89 1662306a36Sopenharmony_ciand a minor device number corresponding to the number assigned as 1762306a36Sopenharmony_ciexplained above. They should be called "i2c-%d" (i2c-0, i2c-1, ..., 1862306a36Sopenharmony_cii2c-10, ...). All 256 minor device numbers are reserved for I2C. 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciC example 2262306a36Sopenharmony_ci========= 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciSo let's say you want to access an I2C adapter from a C program. 2562306a36Sopenharmony_ciFirst, you need to include these two headers:: 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci #include <linux/i2c-dev.h> 2862306a36Sopenharmony_ci #include <i2c/smbus.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ciNow, you have to decide which adapter you want to access. You should 3162306a36Sopenharmony_ciinspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this. 3262306a36Sopenharmony_ciAdapter numbers are assigned somewhat dynamically, so you can not 3362306a36Sopenharmony_ciassume much about them. They can even change from one boot to the next. 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciNext thing, open the device file, as follows:: 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci int file; 3862306a36Sopenharmony_ci int adapter_nr = 2; /* probably dynamically determined */ 3962306a36Sopenharmony_ci char filename[20]; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci snprintf(filename, 19, "/dev/i2c-%d", adapter_nr); 4262306a36Sopenharmony_ci file = open(filename, O_RDWR); 4362306a36Sopenharmony_ci if (file < 0) { 4462306a36Sopenharmony_ci /* ERROR HANDLING; you can check errno to see what went wrong */ 4562306a36Sopenharmony_ci exit(1); 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ciWhen you have opened the device, you must specify with what device 4962306a36Sopenharmony_ciaddress you want to communicate:: 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci int addr = 0x40; /* The I2C address */ 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci if (ioctl(file, I2C_SLAVE, addr) < 0) { 5462306a36Sopenharmony_ci /* ERROR HANDLING; you can check errno to see what went wrong */ 5562306a36Sopenharmony_ci exit(1); 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ciWell, you are all set up now. You can now use SMBus commands or plain 5962306a36Sopenharmony_ciI2C to communicate with your device. SMBus commands are preferred if 6062306a36Sopenharmony_cithe device supports them. Both are illustrated below:: 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci __u8 reg = 0x10; /* Device register to access */ 6362306a36Sopenharmony_ci __s32 res; 6462306a36Sopenharmony_ci char buf[10]; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* Using SMBus commands */ 6762306a36Sopenharmony_ci res = i2c_smbus_read_word_data(file, reg); 6862306a36Sopenharmony_ci if (res < 0) { 6962306a36Sopenharmony_ci /* ERROR HANDLING: I2C transaction failed */ 7062306a36Sopenharmony_ci } else { 7162306a36Sopenharmony_ci /* res contains the read word */ 7262306a36Sopenharmony_ci } 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* 7562306a36Sopenharmony_ci * Using I2C Write, equivalent of 7662306a36Sopenharmony_ci * i2c_smbus_write_word_data(file, reg, 0x6543) 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_ci buf[0] = reg; 7962306a36Sopenharmony_ci buf[1] = 0x43; 8062306a36Sopenharmony_ci buf[2] = 0x65; 8162306a36Sopenharmony_ci if (write(file, buf, 3) != 3) { 8262306a36Sopenharmony_ci /* ERROR HANDLING: I2C transaction failed */ 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */ 8662306a36Sopenharmony_ci if (read(file, buf, 1) != 1) { 8762306a36Sopenharmony_ci /* ERROR HANDLING: I2C transaction failed */ 8862306a36Sopenharmony_ci } else { 8962306a36Sopenharmony_ci /* buf[0] contains the read byte */ 9062306a36Sopenharmony_ci } 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ciNote that only a subset of the I2C and SMBus protocols can be achieved by 9362306a36Sopenharmony_cithe means of read() and write() calls. In particular, so-called combined 9462306a36Sopenharmony_citransactions (mixing read and write messages in the same transaction) 9562306a36Sopenharmony_ciaren't supported. For this reason, this interface is almost never used by 9662306a36Sopenharmony_ciuser-space programs. 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ciIMPORTANT: because of the use of inline functions, you *have* to use 9962306a36Sopenharmony_ci'-O' or some variation when you compile your program! 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ciFull interface description 10362306a36Sopenharmony_ci========================== 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ciThe following IOCTLs are defined: 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci``ioctl(file, I2C_SLAVE, long addr)`` 10862306a36Sopenharmony_ci Change slave address. The address is passed in the 7 lower bits of the 10962306a36Sopenharmony_ci argument (except for 10 bit addresses, passed in the 10 lower bits in this 11062306a36Sopenharmony_ci case). 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci``ioctl(file, I2C_TENBIT, long select)`` 11362306a36Sopenharmony_ci Selects ten bit addresses if select not equals 0, selects normal 7 bit 11462306a36Sopenharmony_ci addresses if select equals 0. Default 0. This request is only valid 11562306a36Sopenharmony_ci if the adapter has I2C_FUNC_10BIT_ADDR. 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci``ioctl(file, I2C_PEC, long select)`` 11862306a36Sopenharmony_ci Selects SMBus PEC (packet error checking) generation and verification 11962306a36Sopenharmony_ci if select not equals 0, disables if select equals 0. Default 0. 12062306a36Sopenharmony_ci Used only for SMBus transactions. This request only has an effect if the 12162306a36Sopenharmony_ci the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just 12262306a36Sopenharmony_ci doesn't have any effect. 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci``ioctl(file, I2C_FUNCS, unsigned long *funcs)`` 12562306a36Sopenharmony_ci Gets the adapter functionality and puts it in ``*funcs``. 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci``ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)`` 12862306a36Sopenharmony_ci Do combined read/write transaction without stop in between. 12962306a36Sopenharmony_ci Only valid if the adapter has I2C_FUNC_I2C. The argument is 13062306a36Sopenharmony_ci a pointer to a:: 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci struct i2c_rdwr_ioctl_data { 13362306a36Sopenharmony_ci struct i2c_msg *msgs; /* ptr to array of simple messages */ 13462306a36Sopenharmony_ci int nmsgs; /* number of messages to exchange */ 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci The msgs[] themselves contain further pointers into data buffers. 13862306a36Sopenharmony_ci The function will write or read data to or from that buffers depending 13962306a36Sopenharmony_ci on whether the I2C_M_RD flag is set in a particular message or not. 14062306a36Sopenharmony_ci The slave address and whether to use ten bit address mode has to be 14162306a36Sopenharmony_ci set in each message, overriding the values set with the above ioctl's. 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci``ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)`` 14462306a36Sopenharmony_ci If possible, use the provided ``i2c_smbus_*`` methods described below instead 14562306a36Sopenharmony_ci of issuing direct ioctls. 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ciYou can do plain I2C transactions by using read(2) and write(2) calls. 14862306a36Sopenharmony_ciYou do not need to pass the address byte; instead, set it through 14962306a36Sopenharmony_ciioctl I2C_SLAVE before you try to access the device. 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ciYou can do SMBus level transactions (see documentation file smbus-protocol.rst 15262306a36Sopenharmony_cifor details) through the following functions:: 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci __s32 i2c_smbus_write_quick(int file, __u8 value); 15562306a36Sopenharmony_ci __s32 i2c_smbus_read_byte(int file); 15662306a36Sopenharmony_ci __s32 i2c_smbus_write_byte(int file, __u8 value); 15762306a36Sopenharmony_ci __s32 i2c_smbus_read_byte_data(int file, __u8 command); 15862306a36Sopenharmony_ci __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value); 15962306a36Sopenharmony_ci __s32 i2c_smbus_read_word_data(int file, __u8 command); 16062306a36Sopenharmony_ci __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value); 16162306a36Sopenharmony_ci __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value); 16262306a36Sopenharmony_ci __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length, 16362306a36Sopenharmony_ci __u8 *values); 16462306a36Sopenharmony_ci __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values); 16562306a36Sopenharmony_ci __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 16662306a36Sopenharmony_ci __u8 *values); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ciAll these transactions return -1 on failure; you can read errno to see 16962306a36Sopenharmony_ciwhat happened. The 'write' transactions return 0 on success; the 17062306a36Sopenharmony_ci'read' transactions return the read value, except for read_block, which 17162306a36Sopenharmony_cireturns the number of values read. The block buffers need not be longer 17262306a36Sopenharmony_cithan 32 bytes. 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciThe above functions are made available by linking against the libi2c library, 17562306a36Sopenharmony_ciwhich is provided by the i2c-tools project. See: 17662306a36Sopenharmony_cihttps://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/. 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciImplementation details 18062306a36Sopenharmony_ci====================== 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ciFor the interested, here's the code flow which happens inside the kernel 18362306a36Sopenharmony_ciwhen you use the /dev interface to I2C: 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci1) Your program opens /dev/i2c-N and calls ioctl() on it, as described in 18662306a36Sopenharmony_ci section "C example" above. 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci2) These open() and ioctl() calls are handled by the i2c-dev kernel 18962306a36Sopenharmony_ci driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(), 19062306a36Sopenharmony_ci respectively. You can think of i2c-dev as a generic I2C chip driver 19162306a36Sopenharmony_ci that can be programmed from user-space. 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci3) Some ioctl() calls are for administrative tasks and are handled by 19462306a36Sopenharmony_ci i2c-dev directly. Examples include I2C_SLAVE (set the address of the 19562306a36Sopenharmony_ci device you want to access) and I2C_PEC (enable or disable SMBus error 19662306a36Sopenharmony_ci checking on future transactions.) 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci4) Other ioctl() calls are converted to in-kernel function calls by 19962306a36Sopenharmony_ci i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter 20062306a36Sopenharmony_ci functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which 20162306a36Sopenharmony_ci performs an SMBus transaction using i2c-core-smbus.c:i2c_smbus_xfer(). 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci The i2c-dev driver is responsible for checking all the parameters that 20462306a36Sopenharmony_ci come from user-space for validity. After this point, there is no 20562306a36Sopenharmony_ci difference between these calls that came from user-space through i2c-dev 20662306a36Sopenharmony_ci and calls that would have been performed by kernel I2C chip drivers 20762306a36Sopenharmony_ci directly. This means that I2C bus drivers don't need to implement 20862306a36Sopenharmony_ci anything special to support access from user-space. 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci5) These i2c.h functions are wrappers to the actual implementation of 21162306a36Sopenharmony_ci your I2C bus driver. Each adapter must declare callback functions 21262306a36Sopenharmony_ci implementing these standard calls. i2c.h:i2c_get_functionality() calls 21362306a36Sopenharmony_ci i2c_adapter.algo->functionality(), while 21462306a36Sopenharmony_ci i2c-core-smbus.c:i2c_smbus_xfer() calls either 21562306a36Sopenharmony_ci adapter.algo->smbus_xfer() if it is implemented, or if not, 21662306a36Sopenharmony_ci i2c-core-smbus.c:i2c_smbus_xfer_emulated() which in turn calls 21762306a36Sopenharmony_ci i2c_adapter.algo->master_xfer(). 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ciAfter your I2C bus driver has processed these requests, execution runs 22062306a36Sopenharmony_ciup the call chain, with almost no processing done, except by i2c-dev to 22162306a36Sopenharmony_cipackage the returned data, if any, in suitable format for the ioctl. 222