18c2ecf20Sopenharmony_ci============================================
28c2ecf20Sopenharmony_ciImplementing I2C device drivers in userspace
38c2ecf20Sopenharmony_ci============================================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciUsually, I2C devices are controlled by a kernel driver. But it is also
68c2ecf20Sopenharmony_cipossible to access all devices on an adapter from userspace, through
78c2ecf20Sopenharmony_cithe /dev interface. You need to load module i2c-dev for this.
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ciEach registered I2C adapter gets a number, counting from 0. You can
108c2ecf20Sopenharmony_ciexamine /sys/class/i2c-dev/ to see what number corresponds to which adapter.
118c2ecf20Sopenharmony_ciAlternatively, you can run "i2cdetect -l" to obtain a formatted list of all
128c2ecf20Sopenharmony_ciI2C adapters present on your system at a given time. i2cdetect is part of
138c2ecf20Sopenharmony_cithe i2c-tools package.
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciI2C device files are character device files with major device number 89
168c2ecf20Sopenharmony_ciand a minor device number corresponding to the number assigned as
178c2ecf20Sopenharmony_ciexplained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
188c2ecf20Sopenharmony_cii2c-10, ...). All 256 minor device numbers are reserved for I2C.
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ciC example
228c2ecf20Sopenharmony_ci=========
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciSo let's say you want to access an I2C adapter from a C program.
258c2ecf20Sopenharmony_ciFirst, you need to include these two headers::
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci  #include <linux/i2c-dev.h>
288c2ecf20Sopenharmony_ci  #include <i2c/smbus.h>
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciNow, you have to decide which adapter you want to access. You should
318c2ecf20Sopenharmony_ciinspect /sys/class/i2c-dev/ or run "i2cdetect -l" to decide this.
328c2ecf20Sopenharmony_ciAdapter numbers are assigned somewhat dynamically, so you can not
338c2ecf20Sopenharmony_ciassume much about them. They can even change from one boot to the next.
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ciNext thing, open the device file, as follows::
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci  int file;
388c2ecf20Sopenharmony_ci  int adapter_nr = 2; /* probably dynamically determined */
398c2ecf20Sopenharmony_ci  char filename[20];
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci  snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
428c2ecf20Sopenharmony_ci  file = open(filename, O_RDWR);
438c2ecf20Sopenharmony_ci  if (file < 0) {
448c2ecf20Sopenharmony_ci    /* ERROR HANDLING; you can check errno to see what went wrong */
458c2ecf20Sopenharmony_ci    exit(1);
468c2ecf20Sopenharmony_ci  }
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ciWhen you have opened the device, you must specify with what device
498c2ecf20Sopenharmony_ciaddress you want to communicate::
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci  int addr = 0x40; /* The I2C address */
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci  if (ioctl(file, I2C_SLAVE, addr) < 0) {
548c2ecf20Sopenharmony_ci    /* ERROR HANDLING; you can check errno to see what went wrong */
558c2ecf20Sopenharmony_ci    exit(1);
568c2ecf20Sopenharmony_ci  }
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciWell, you are all set up now. You can now use SMBus commands or plain
598c2ecf20Sopenharmony_ciI2C to communicate with your device. SMBus commands are preferred if
608c2ecf20Sopenharmony_cithe device supports them. Both are illustrated below::
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci  __u8 reg = 0x10; /* Device register to access */
638c2ecf20Sopenharmony_ci  __s32 res;
648c2ecf20Sopenharmony_ci  char buf[10];
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci  /* Using SMBus commands */
678c2ecf20Sopenharmony_ci  res = i2c_smbus_read_word_data(file, reg);
688c2ecf20Sopenharmony_ci  if (res < 0) {
698c2ecf20Sopenharmony_ci    /* ERROR HANDLING: I2C transaction failed */
708c2ecf20Sopenharmony_ci  } else {
718c2ecf20Sopenharmony_ci    /* res contains the read word */
728c2ecf20Sopenharmony_ci  }
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci  /*
758c2ecf20Sopenharmony_ci   * Using I2C Write, equivalent of
768c2ecf20Sopenharmony_ci   * i2c_smbus_write_word_data(file, reg, 0x6543)
778c2ecf20Sopenharmony_ci   */
788c2ecf20Sopenharmony_ci  buf[0] = reg;
798c2ecf20Sopenharmony_ci  buf[1] = 0x43;
808c2ecf20Sopenharmony_ci  buf[2] = 0x65;
818c2ecf20Sopenharmony_ci  if (write(file, buf, 3) != 3) {
828c2ecf20Sopenharmony_ci    /* ERROR HANDLING: I2C transaction failed */
838c2ecf20Sopenharmony_ci  }
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci  /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */
868c2ecf20Sopenharmony_ci  if (read(file, buf, 1) != 1) {
878c2ecf20Sopenharmony_ci    /* ERROR HANDLING: I2C transaction failed */
888c2ecf20Sopenharmony_ci  } else {
898c2ecf20Sopenharmony_ci    /* buf[0] contains the read byte */
908c2ecf20Sopenharmony_ci  }
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciNote that only a subset of the I2C and SMBus protocols can be achieved by
938c2ecf20Sopenharmony_cithe means of read() and write() calls. In particular, so-called combined
948c2ecf20Sopenharmony_citransactions (mixing read and write messages in the same transaction)
958c2ecf20Sopenharmony_ciaren't supported. For this reason, this interface is almost never used by
968c2ecf20Sopenharmony_ciuser-space programs.
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciIMPORTANT: because of the use of inline functions, you *have* to use
998c2ecf20Sopenharmony_ci'-O' or some variation when you compile your program!
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciFull interface description
1038c2ecf20Sopenharmony_ci==========================
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciThe following IOCTLs are defined:
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci``ioctl(file, I2C_SLAVE, long addr)``
1088c2ecf20Sopenharmony_ci  Change slave address. The address is passed in the 7 lower bits of the
1098c2ecf20Sopenharmony_ci  argument (except for 10 bit addresses, passed in the 10 lower bits in this
1108c2ecf20Sopenharmony_ci  case).
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci``ioctl(file, I2C_TENBIT, long select)``
1138c2ecf20Sopenharmony_ci  Selects ten bit addresses if select not equals 0, selects normal 7 bit
1148c2ecf20Sopenharmony_ci  addresses if select equals 0. Default 0.  This request is only valid
1158c2ecf20Sopenharmony_ci  if the adapter has I2C_FUNC_10BIT_ADDR.
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci``ioctl(file, I2C_PEC, long select)``
1188c2ecf20Sopenharmony_ci  Selects SMBus PEC (packet error checking) generation and verification
1198c2ecf20Sopenharmony_ci  if select not equals 0, disables if select equals 0. Default 0.
1208c2ecf20Sopenharmony_ci  Used only for SMBus transactions.  This request only has an effect if the
1218c2ecf20Sopenharmony_ci  the adapter has I2C_FUNC_SMBUS_PEC; it is still safe if not, it just
1228c2ecf20Sopenharmony_ci  doesn't have any effect.
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci``ioctl(file, I2C_FUNCS, unsigned long *funcs)``
1258c2ecf20Sopenharmony_ci  Gets the adapter functionality and puts it in ``*funcs``.
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci``ioctl(file, I2C_RDWR, struct i2c_rdwr_ioctl_data *msgset)``
1288c2ecf20Sopenharmony_ci  Do combined read/write transaction without stop in between.
1298c2ecf20Sopenharmony_ci  Only valid if the adapter has I2C_FUNC_I2C.  The argument is
1308c2ecf20Sopenharmony_ci  a pointer to a::
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci    struct i2c_rdwr_ioctl_data {
1338c2ecf20Sopenharmony_ci      struct i2c_msg *msgs;  /* ptr to array of simple messages */
1348c2ecf20Sopenharmony_ci      int nmsgs;             /* number of messages to exchange */
1358c2ecf20Sopenharmony_ci    }
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci  The msgs[] themselves contain further pointers into data buffers.
1388c2ecf20Sopenharmony_ci  The function will write or read data to or from that buffers depending
1398c2ecf20Sopenharmony_ci  on whether the I2C_M_RD flag is set in a particular message or not.
1408c2ecf20Sopenharmony_ci  The slave address and whether to use ten bit address mode has to be
1418c2ecf20Sopenharmony_ci  set in each message, overriding the values set with the above ioctl's.
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci``ioctl(file, I2C_SMBUS, struct i2c_smbus_ioctl_data *args)``
1448c2ecf20Sopenharmony_ci  If possible, use the provided ``i2c_smbus_*`` methods described below instead
1458c2ecf20Sopenharmony_ci  of issuing direct ioctls.
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ciYou can do plain I2C transactions by using read(2) and write(2) calls.
1488c2ecf20Sopenharmony_ciYou do not need to pass the address byte; instead, set it through
1498c2ecf20Sopenharmony_ciioctl I2C_SLAVE before you try to access the device.
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ciYou can do SMBus level transactions (see documentation file smbus-protocol
1528c2ecf20Sopenharmony_cifor details) through the following functions::
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci  __s32 i2c_smbus_write_quick(int file, __u8 value);
1558c2ecf20Sopenharmony_ci  __s32 i2c_smbus_read_byte(int file);
1568c2ecf20Sopenharmony_ci  __s32 i2c_smbus_write_byte(int file, __u8 value);
1578c2ecf20Sopenharmony_ci  __s32 i2c_smbus_read_byte_data(int file, __u8 command);
1588c2ecf20Sopenharmony_ci  __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
1598c2ecf20Sopenharmony_ci  __s32 i2c_smbus_read_word_data(int file, __u8 command);
1608c2ecf20Sopenharmony_ci  __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
1618c2ecf20Sopenharmony_ci  __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
1628c2ecf20Sopenharmony_ci  __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
1638c2ecf20Sopenharmony_ci                                     __u8 *values);
1648c2ecf20Sopenharmony_ci  __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
1658c2ecf20Sopenharmony_ci  __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
1668c2ecf20Sopenharmony_ci                                   __u8 *values);
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ciAll these transactions return -1 on failure; you can read errno to see
1698c2ecf20Sopenharmony_ciwhat happened. The 'write' transactions return 0 on success; the
1708c2ecf20Sopenharmony_ci'read' transactions return the read value, except for read_block, which
1718c2ecf20Sopenharmony_cireturns the number of values read. The block buffers need not be longer
1728c2ecf20Sopenharmony_cithan 32 bytes.
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ciThe above functions are made available by linking against the libi2c library,
1758c2ecf20Sopenharmony_ciwhich is provided by the i2c-tools project.  See:
1768c2ecf20Sopenharmony_cihttps://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git/.
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ciImplementation details
1808c2ecf20Sopenharmony_ci======================
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ciFor the interested, here's the code flow which happens inside the kernel
1838c2ecf20Sopenharmony_ciwhen you use the /dev interface to I2C:
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci1) Your program opens /dev/i2c-N and calls ioctl() on it, as described in
1868c2ecf20Sopenharmony_ci   section "C example" above.
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci2) These open() and ioctl() calls are handled by the i2c-dev kernel
1898c2ecf20Sopenharmony_ci   driver: see i2c-dev.c:i2cdev_open() and i2c-dev.c:i2cdev_ioctl(),
1908c2ecf20Sopenharmony_ci   respectively. You can think of i2c-dev as a generic I2C chip driver
1918c2ecf20Sopenharmony_ci   that can be programmed from user-space.
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci3) Some ioctl() calls are for administrative tasks and are handled by
1948c2ecf20Sopenharmony_ci   i2c-dev directly. Examples include I2C_SLAVE (set the address of the
1958c2ecf20Sopenharmony_ci   device you want to access) and I2C_PEC (enable or disable SMBus error
1968c2ecf20Sopenharmony_ci   checking on future transactions.)
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci4) Other ioctl() calls are converted to in-kernel function calls by
1998c2ecf20Sopenharmony_ci   i2c-dev. Examples include I2C_FUNCS, which queries the I2C adapter
2008c2ecf20Sopenharmony_ci   functionality using i2c.h:i2c_get_functionality(), and I2C_SMBUS, which
2018c2ecf20Sopenharmony_ci   performs an SMBus transaction using i2c-core-smbus.c:i2c_smbus_xfer().
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci   The i2c-dev driver is responsible for checking all the parameters that
2048c2ecf20Sopenharmony_ci   come from user-space for validity. After this point, there is no
2058c2ecf20Sopenharmony_ci   difference between these calls that came from user-space through i2c-dev
2068c2ecf20Sopenharmony_ci   and calls that would have been performed by kernel I2C chip drivers
2078c2ecf20Sopenharmony_ci   directly. This means that I2C bus drivers don't need to implement
2088c2ecf20Sopenharmony_ci   anything special to support access from user-space.
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci5) These i2c.h functions are wrappers to the actual implementation of
2118c2ecf20Sopenharmony_ci   your I2C bus driver. Each adapter must declare callback functions
2128c2ecf20Sopenharmony_ci   implementing these standard calls. i2c.h:i2c_get_functionality() calls
2138c2ecf20Sopenharmony_ci   i2c_adapter.algo->functionality(), while
2148c2ecf20Sopenharmony_ci   i2c-core-smbus.c:i2c_smbus_xfer() calls either
2158c2ecf20Sopenharmony_ci   adapter.algo->smbus_xfer() if it is implemented, or if not,
2168c2ecf20Sopenharmony_ci   i2c-core-smbus.c:i2c_smbus_xfer_emulated() which in turn calls
2178c2ecf20Sopenharmony_ci   i2c_adapter.algo->master_xfer().
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ciAfter your I2C bus driver has processed these requests, execution runs
2208c2ecf20Sopenharmony_ciup the call chain, with almost no processing done, except by i2c-dev to
2218c2ecf20Sopenharmony_cipackage the returned data, if any, in suitable format for the ioctl.
222