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