1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0 2*4882a593Smuzhiyun 3*4882a593Smuzhiyun================================ 4*4882a593SmuzhiyunLinux I2C slave testunit backend 5*4882a593Smuzhiyun================================ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyunby Wolfram Sang <wsa@sang-engineering.com> in 2020 8*4882a593Smuzhiyun 9*4882a593SmuzhiyunThis backend can be used to trigger test cases for I2C bus masters which 10*4882a593Smuzhiyunrequire a remote device with certain capabilities (and which are usually not so 11*4882a593Smuzhiyuneasy to obtain). Examples include multi-master testing, and SMBus Host Notify 12*4882a593Smuzhiyuntesting. For some tests, the I2C slave controller must be able to switch 13*4882a593Smuzhiyunbetween master and slave mode because it needs to send data, too. 14*4882a593Smuzhiyun 15*4882a593SmuzhiyunNote that this is a device for testing and debugging. It should not be enabled 16*4882a593Smuzhiyunin a production build. And while there is some versioning and we try hard to 17*4882a593Smuzhiyunkeep backward compatibility, there is no stable ABI guaranteed! 18*4882a593Smuzhiyun 19*4882a593SmuzhiyunInstantiating the device is regular. Example for bus 0, address 0x30: 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun# echo "slave-testunit 0x1030" > /sys/bus/i2c/devices/i2c-0/new_device 22*4882a593Smuzhiyun 23*4882a593SmuzhiyunAfter that, you will have a write-only device listening. Reads will just return 24*4882a593Smuzhiyunan 8-bit version number of the testunit. When writing, the device consists of 4 25*4882a593Smuzhiyun8-bit registers and all must be written to start a testcase, i.e. you must 26*4882a593Smuzhiyunalways write 4 bytes to the device. The registers are: 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun0x00 CMD - which test to trigger 29*4882a593Smuzhiyun0x01 DATAL - configuration byte 1 for the test 30*4882a593Smuzhiyun0x02 DATAH - configuration byte 2 for the test 31*4882a593Smuzhiyun0x03 DELAY - delay in n * 10ms until test is started 32*4882a593Smuzhiyun 33*4882a593SmuzhiyunUsing 'i2cset' from the i2c-tools package, the generic command looks like: 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun# i2cset -y <bus_num> <testunit_address> <CMD> <DATAL> <DATAH> <DELAY> i 36*4882a593Smuzhiyun 37*4882a593SmuzhiyunDELAY is a generic parameter which will delay the execution of the test in CMD. 38*4882a593SmuzhiyunWhile a command is running (including the delay), new commands will not be 39*4882a593Smuzhiyunacknowledged. You need to wait until the old one is completed. 40*4882a593Smuzhiyun 41*4882a593SmuzhiyunThe commands are described in the following section. An invalid command will 42*4882a593Smuzhiyunresult in the transfer not being acknowledged. 43*4882a593Smuzhiyun 44*4882a593SmuzhiyunCommands 45*4882a593Smuzhiyun-------- 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun0x00 NOOP (reserved for future use) 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun0x01 READ_BYTES (also needs master mode) 50*4882a593Smuzhiyun DATAL - address to read data from (lower 7 bits, highest bit currently unused) 51*4882a593Smuzhiyun DATAH - number of bytes to read 52*4882a593Smuzhiyun 53*4882a593SmuzhiyunThis is useful to test if your bus master driver is handling multi-master 54*4882a593Smuzhiyuncorrectly. You can trigger the testunit to read bytes from another device on 55*4882a593Smuzhiyunthe bus. If the bus master under test also wants to access the bus at the same 56*4882a593Smuzhiyuntime, the bus will be busy. Example to read 128 bytes from device 0x50 after 57*4882a593Smuzhiyun50ms of delay: 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun# i2cset -y 0 0x30 0x01 0x50 0x80 0x05 i 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun0x02 SMBUS_HOST_NOTIFY (also needs master mode) 62*4882a593Smuzhiyun DATAL - low byte of the status word to send 63*4882a593Smuzhiyun DATAH - high byte of the status word to send 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunThis test will send an SMBUS_HOST_NOTIFY message to the host. Note that the 66*4882a593Smuzhiyunstatus word is currently ignored in the Linux Kernel. Example to send a 67*4882a593Smuzhiyunnotification after 10ms: 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun# i2cset -y 0 0x30 0x02 0x42 0x64 0x01 i 70