Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ================================
0004 Linux I2C slave testunit backend
0005 ================================
0006 
0007 by Wolfram Sang <wsa@sang-engineering.com> in 2020
0008 
0009 This backend can be used to trigger test cases for I2C bus masters which
0010 require a remote device with certain capabilities (and which are usually not so
0011 easy to obtain). Examples include multi-master testing, and SMBus Host Notify
0012 testing. For some tests, the I2C slave controller must be able to switch
0013 between master and slave mode because it needs to send data, too.
0014 
0015 Note that this is a device for testing and debugging. It should not be enabled
0016 in a production build. And while there is some versioning and we try hard to
0017 keep backward compatibility, there is no stable ABI guaranteed!
0018 
0019 Instantiating the device is regular. Example for bus 0, address 0x30:
0020 
0021 # echo "slave-testunit 0x1030" > /sys/bus/i2c/devices/i2c-0/new_device
0022 
0023 After that, you will have a write-only device listening. Reads will just return
0024 an 8-bit version number of the testunit. When writing, the device consists of 4
0025 8-bit registers and, except for some "partial" commands, all registers must be
0026 written to start a testcase, i.e. you usually write 4 bytes to the device. The
0027 registers are:
0028 
0029 0x00 CMD   - which test to trigger
0030 0x01 DATAL - configuration byte 1 for the test
0031 0x02 DATAH - configuration byte 2 for the test
0032 0x03 DELAY - delay in n * 10ms until test is started
0033 
0034 Using 'i2cset' from the i2c-tools package, the generic command looks like:
0035 
0036 # i2cset -y <bus_num> <testunit_address> <CMD> <DATAL> <DATAH> <DELAY> i
0037 
0038 DELAY is a generic parameter which will delay the execution of the test in CMD.
0039 While a command is running (including the delay), new commands will not be
0040 acknowledged. You need to wait until the old one is completed.
0041 
0042 The commands are described in the following section. An invalid command will
0043 result in the transfer not being acknowledged.
0044 
0045 Commands
0046 --------
0047 
0048 0x00 NOOP (reserved for future use)
0049 
0050 0x01 READ_BYTES (also needs master mode)
0051    DATAL - address to read data from (lower 7 bits, highest bit currently unused)
0052    DATAH - number of bytes to read
0053 
0054 This is useful to test if your bus master driver is handling multi-master
0055 correctly. You can trigger the testunit to read bytes from another device on
0056 the bus. If the bus master under test also wants to access the bus at the same
0057 time, the bus will be busy. Example to read 128 bytes from device 0x50 after
0058 50ms of delay:
0059 
0060 # i2cset -y 0 0x30 0x01 0x50 0x80 0x05 i
0061 
0062 0x02 SMBUS_HOST_NOTIFY (also needs master mode)
0063    DATAL - low byte of the status word to send
0064    DATAH - high byte of the status word to send
0065 
0066 This test will send an SMBUS_HOST_NOTIFY message to the host. Note that the
0067 status word is currently ignored in the Linux Kernel. Example to send a
0068 notification after 10ms:
0069 
0070 # i2cset -y 0 0x30 0x02 0x42 0x64 0x01 i
0071 
0072 0x03 SMBUS_BLOCK_PROC_CALL (partial command)
0073    DATAL - must be '1', i.e. one further byte will be written
0074    DATAH - number of bytes to be sent back
0075    DELAY - not applicable, partial command!
0076 
0077 This test will respond to a block process call as defined by the SMBus
0078 specification. The one data byte written specifies how many bytes will be sent
0079 back in the following read transfer. Note that in this read transfer, the
0080 testunit will prefix the length of the bytes to follow. So, if your host bus
0081 driver emulates SMBus calls like the majority does, it needs to support the
0082 I2C_M_RECV_LEN flag of an i2c_msg. This is a good testcase for it. The returned
0083 data consists of the length first, and then of an array of bytes from length-1
0084 to 0. Here is an example which emulates i2c_smbus_block_process_call() using
0085 i2ctransfer (you need i2c-tools v4.2 or later):
0086 
0087 # i2ctransfer -y 0 w3@0x30 0x03 0x01 0x10 r?
0088 0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00