slave-testunit-backend.rst 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. .. SPDX-License-Identifier: GPL-2.0
  2. ================================
  3. Linux I2C slave testunit backend
  4. ================================
  5. by Wolfram Sang <wsa@sang-engineering.com> in 2020
  6. This backend can be used to trigger test cases for I2C bus masters which
  7. require a remote device with certain capabilities (and which are usually not so
  8. easy to obtain). Examples include multi-master testing, and SMBus Host Notify
  9. testing. For some tests, the I2C slave controller must be able to switch
  10. between master and slave mode because it needs to send data, too.
  11. Note that this is a device for testing and debugging. It should not be enabled
  12. in a production build. And while there is some versioning and we try hard to
  13. keep backward compatibility, there is no stable ABI guaranteed!
  14. Instantiating the device is regular. Example for bus 0, address 0x30::
  15. # echo "slave-testunit 0x1030" > /sys/bus/i2c/devices/i2c-0/new_device
  16. Or using firmware nodes. Here is a devicetree example (note this is only a
  17. debug device, so there are no official DT bindings)::
  18. &i2c0 {
  19. ...
  20. testunit@30 {
  21. compatible = "slave-testunit";
  22. reg = <(0x30 | I2C_OWN_SLAVE_ADDRESS)>;
  23. };
  24. };
  25. After that, you will have the device listening. Reading will return a single
  26. byte. Its value is 0 if the testunit is idle, otherwise the command number of
  27. the currently running command.
  28. When writing, the device consists of 4 8-bit registers and, except for some
  29. "partial" commands, all registers must be written to start a testcase, i.e. you
  30. usually write 4 bytes to the device. The registers are:
  31. .. csv-table::
  32. :header: "Offset", "Name", "Description"
  33. 0x00, CMD, which test to trigger
  34. 0x01, DATAL, configuration byte 1 for the test
  35. 0x02, DATAH, configuration byte 2 for the test
  36. 0x03, DELAY, delay in n * 10ms until test is started
  37. Using 'i2cset' from the i2c-tools package, the generic command looks like::
  38. # i2cset -y <bus_num> <testunit_address> <CMD> <DATAL> <DATAH> <DELAY> i
  39. DELAY is a generic parameter which will delay the execution of the test in CMD.
  40. While a command is running (including the delay), new commands will not be
  41. acknowledged. You need to wait until the old one is completed.
  42. The commands are described in the following section. An invalid command will
  43. result in the transfer not being acknowledged.
  44. Commands
  45. --------
  46. 0x00 NOOP
  47. ~~~~~~~~~
  48. Reserved for future use.
  49. 0x01 READ_BYTES
  50. ~~~~~~~~~~~~~~~
  51. .. list-table::
  52. :header-rows: 1
  53. * - CMD
  54. - DATAL
  55. - DATAH
  56. - DELAY
  57. * - 0x01
  58. - address to read data from (lower 7 bits, highest bit currently unused)
  59. - number of bytes to read
  60. - n * 10ms
  61. Also needs master mode. This is useful to test if your bus master driver is
  62. handling multi-master correctly. You can trigger the testunit to read bytes
  63. from another device on the bus. If the bus master under test also wants to
  64. access the bus at the same time, the bus will be busy. Example to read 128
  65. bytes from device 0x50 after 50ms of delay::
  66. # i2cset -y 0 0x30 1 0x50 0x80 5 i
  67. 0x02 SMBUS_HOST_NOTIFY
  68. ~~~~~~~~~~~~~~~~~~~~~~
  69. .. list-table::
  70. :header-rows: 1
  71. * - CMD
  72. - DATAL
  73. - DATAH
  74. - DELAY
  75. * - 0x02
  76. - low byte of the status word to send
  77. - high byte of the status word to send
  78. - n * 10ms
  79. Also needs master mode. This test will send an SMBUS_HOST_NOTIFY message to the
  80. host. Note that the status word is currently ignored in the Linux Kernel.
  81. Example to send a notification with status word 0x6442 after 10ms::
  82. # i2cset -y 0 0x30 2 0x42 0x64 1 i
  83. If the host controller supports HostNotify, this message with debug level
  84. should appear (Linux 6.11 and later)::
  85. Detected HostNotify from address 0x30
  86. 0x03 SMBUS_BLOCK_PROC_CALL
  87. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  88. .. list-table::
  89. :header-rows: 1
  90. * - CMD
  91. - DATAL
  92. - DATAH
  93. - DELAY
  94. * - 0x03
  95. - 0x01 (i.e. one further byte will be written)
  96. - number of bytes to be sent back
  97. - leave out, partial command!
  98. Partial command. This test will respond to a block process call as defined by
  99. the SMBus specification. The one data byte written specifies how many bytes
  100. will be sent back in the following read transfer. Note that in this read
  101. transfer, the testunit will prefix the length of the bytes to follow. So, if
  102. your host bus driver emulates SMBus calls like the majority does, it needs to
  103. support the I2C_M_RECV_LEN flag of an i2c_msg. This is a good testcase for it.
  104. The returned data consists of the length first, and then of an array of bytes
  105. from length-1 to 0. Here is an example which emulates
  106. i2c_smbus_block_process_call() using i2ctransfer (you need i2c-tools v4.2 or
  107. later)::
  108. # i2ctransfer -y 0 w3@0x30 3 1 0x10 r?
  109. 0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00
  110. 0x04 GET_VERSION_WITH_REP_START
  111. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  112. .. list-table::
  113. :header-rows: 1
  114. * - CMD
  115. - DATAL
  116. - DATAH
  117. - DELAY
  118. * - 0x04
  119. - currently unused
  120. - currently unused
  121. - leave out, partial command!
  122. Partial command. After sending this command, the testunit will reply to a read
  123. message with a NUL terminated version string based on UTS_RELEASE. The first
  124. character is always a 'v' and the length of the version string is at maximum
  125. 128 bytes. However, it will only respond if the read message is connected to
  126. the write message via repeated start. If your controller driver handles
  127. repeated start correctly, this will work::
  128. # i2ctransfer -y 0 w3@0x30 4 0 0 r128
  129. 0x76 0x36 0x2e 0x31 0x31 0x2e 0x30 0x2d 0x72 0x63 0x31 0x2d 0x30 0x30 0x30 0x30 ...
  130. If you have i2c-tools 4.4 or later, you can print out the data right away::
  131. # i2ctransfer -y -b 0 w3@0x30 4 0 0 r128
  132. v6.11.0-rc1-00009-gd37a1b4d3fd0
  133. STOP/START combinations between the two messages will *not* work because they
  134. are not equivalent to a REPEATED START. As an example, this returns just the
  135. default response::
  136. # i2cset -y 0 0x30 4 0 0 i; i2cget -y 0 0x30
  137. 0x00
  138. 0x05 SMBUS_ALERT_REQUEST
  139. ~~~~~~~~~~~~~~~~~~~~~~~~
  140. .. list-table::
  141. :header-rows: 1
  142. * - CMD
  143. - DATAL
  144. - DATAH
  145. - DELAY
  146. * - 0x05
  147. - response value (7 MSBs interpreted as I2C address)
  148. - currently unused
  149. - n * 10ms
  150. This test raises an interrupt via the SMBAlert pin which the host controller
  151. must handle. The pin must be connected to the testunit as a GPIO. GPIO access
  152. is not allowed to sleep. Currently, this can only be described using firmware
  153. nodes. So, for devicetree, you would add something like this to the testunit
  154. node::
  155. gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
  156. The following command will trigger the alert with a response of 0xc9 after 1
  157. second of delay::
  158. # i2cset -y 0 0x30 5 0xc9 0x00 100 i
  159. If the host controller supports SMBusAlert, this message with debug level
  160. should appear::
  161. smbus_alert 0-000c: SMBALERT# from dev 0x64, flag 1
  162. This message may appear more than once because the testunit is software not
  163. hardware and, thus, may not be able to react to the response of the host fast
  164. enough. The interrupt count should increase only by one, though::
  165. # cat /proc/interrupts | grep smbus_alert
  166. 93: 1 gpio-rcar 26 Edge smbus_alert
  167. If the host does not respond to the alert within 1 second, the test will be
  168. aborted and the testunit will report an error.
  169. For this test, the testunit will shortly drop its assigned address and listen
  170. on the SMBus Alert Response Address (0x0c). It will reassign its original
  171. address afterwards.