brintos

brintos / linux-shallow public Read only

0
0
Text · 7.3 KiB · d752f43 Raw
236 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3================================4Linux I2C slave testunit backend5================================6 7by Wolfram Sang <wsa@sang-engineering.com> in 20208 9This backend can be used to trigger test cases for I2C bus masters which10require a remote device with certain capabilities (and which are usually not so11easy to obtain). Examples include multi-master testing, and SMBus Host Notify12testing. For some tests, the I2C slave controller must be able to switch13between master and slave mode because it needs to send data, too.14 15Note that this is a device for testing and debugging. It should not be enabled16in a production build. And while there is some versioning and we try hard to17keep backward compatibility, there is no stable ABI guaranteed!18 19Instantiating the device is regular. Example for bus 0, address 0x30::20 21  # echo "slave-testunit 0x1030" > /sys/bus/i2c/devices/i2c-0/new_device22 23Or using firmware nodes. Here is a devicetree example (note this is only a24debug device, so there are no official DT bindings)::25 26  &i2c0	{27        ...28 29	testunit@30 {30		compatible = "slave-testunit";31		reg = <(0x30 | I2C_OWN_SLAVE_ADDRESS)>;32	};33  };34 35After that, you will have the device listening. Reading will return a single36byte. Its value is 0 if the testunit is idle, otherwise the command number of37the currently running command.38 39When writing, the device consists of 4 8-bit registers and, except for some40"partial" commands, all registers must be written to start a testcase, i.e. you41usually write 4 bytes to the device. The registers are:42 43.. csv-table::44  :header: "Offset", "Name", "Description"45 46  0x00, CMD, which test to trigger47  0x01, DATAL, configuration byte 1 for the test48  0x02, DATAH, configuration byte 2 for the test49  0x03, DELAY, delay in n * 10ms until test is started50 51Using 'i2cset' from the i2c-tools package, the generic command looks like::52 53  # i2cset -y <bus_num> <testunit_address> <CMD> <DATAL> <DATAH> <DELAY> i54 55DELAY is a generic parameter which will delay the execution of the test in CMD.56While a command is running (including the delay), new commands will not be57acknowledged. You need to wait until the old one is completed.58 59The commands are described in the following section. An invalid command will60result in the transfer not being acknowledged.61 62Commands63--------64 650x00 NOOP66~~~~~~~~~67 68Reserved for future use.69 700x01 READ_BYTES71~~~~~~~~~~~~~~~72 73.. list-table::74  :header-rows: 175 76  * - CMD77    - DATAL78    - DATAH79    - DELAY80 81  * - 0x0182    - address to read data from (lower 7 bits, highest bit currently unused)83    - number of bytes to read84    - n * 10ms85 86Also needs master mode. This is useful to test if your bus master driver is87handling multi-master correctly. You can trigger the testunit to read bytes88from another device on the bus. If the bus master under test also wants to89access the bus at the same time, the bus will be busy. Example to read 12890bytes from device 0x50 after 50ms of delay::91 92  # i2cset -y 0 0x30 1 0x50 0x80 5 i93 940x02 SMBUS_HOST_NOTIFY95~~~~~~~~~~~~~~~~~~~~~~96 97.. list-table::98  :header-rows: 199 100  * - CMD101    - DATAL102    - DATAH103    - DELAY104 105  * - 0x02106    - low byte of the status word to send107    - high byte of the status word to send108    - n * 10ms109 110Also needs master mode. This test will send an SMBUS_HOST_NOTIFY message to the111host. Note that the status word is currently ignored in the Linux Kernel.112Example to send a notification with status word 0x6442 after 10ms::113 114  # i2cset -y 0 0x30 2 0x42 0x64 1 i115 116If the host controller supports HostNotify, this message with debug level117should appear (Linux 6.11 and later)::118 119  Detected HostNotify from address 0x30120 1210x03 SMBUS_BLOCK_PROC_CALL122~~~~~~~~~~~~~~~~~~~~~~~~~~123 124.. list-table::125  :header-rows: 1126 127  * - CMD128    - DATAL129    - DATAH130    - DELAY131 132  * - 0x03133    - 0x01 (i.e. one further byte will be written)134    - number of bytes to be sent back135    - leave out, partial command!136 137Partial command. This test will respond to a block process call as defined by138the SMBus specification. The one data byte written specifies how many bytes139will be sent back in the following read transfer. Note that in this read140transfer, the testunit will prefix the length of the bytes to follow. So, if141your host bus driver emulates SMBus calls like the majority does, it needs to142support the I2C_M_RECV_LEN flag of an i2c_msg. This is a good testcase for it.143The returned data consists of the length first, and then of an array of bytes144from length-1 to 0. Here is an example which emulates145i2c_smbus_block_process_call() using i2ctransfer (you need i2c-tools v4.2 or146later)::147 148  # i2ctransfer -y 0 w3@0x30 3 1 0x10 r?149  0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09 0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01 0x00150 1510x04 GET_VERSION_WITH_REP_START152~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~153 154.. list-table::155  :header-rows: 1156 157  * - CMD158    - DATAL159    - DATAH160    - DELAY161 162  * - 0x04163    - currently unused164    - currently unused165    - leave out, partial command!166 167Partial command. After sending this command, the testunit will reply to a read168message with a NUL terminated version string based on UTS_RELEASE. The first169character is always a 'v' and the length of the version string is at maximum170128 bytes. However, it will only respond if the read message is connected to171the write message via repeated start. If your controller driver handles172repeated start correctly, this will work::173 174  # i2ctransfer -y 0 w3@0x30 4 0 0 r128175  0x76 0x36 0x2e 0x31 0x31 0x2e 0x30 0x2d 0x72 0x63 0x31 0x2d 0x30 0x30 0x30 0x30 ...176 177If you have i2c-tools 4.4 or later, you can print out the data right away::178 179  # i2ctransfer -y -b 0 w3@0x30 4 0 0 r128180  v6.11.0-rc1-00009-gd37a1b4d3fd0181 182STOP/START combinations between the two messages will *not* work because they183are not equivalent to a REPEATED START. As an example, this returns just the184default response::185 186  # i2cset -y 0 0x30 4 0 0 i; i2cget -y 0 0x30187  0x00188 1890x05 SMBUS_ALERT_REQUEST190~~~~~~~~~~~~~~~~~~~~~~~~191 192.. list-table::193  :header-rows: 1194 195  * - CMD196    - DATAL197    - DATAH198    - DELAY199 200  * - 0x05201    - response value (7 MSBs interpreted as I2C address)202    - currently unused203    - n * 10ms204 205This test raises an interrupt via the SMBAlert pin which the host controller206must handle. The pin must be connected to the testunit as a GPIO. GPIO access207is not allowed to sleep. Currently, this can only be described using firmware208nodes. So, for devicetree, you would add something like this to the testunit209node::210 211  gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;212 213The following command will trigger the alert with a response of 0xc9 after 1214second of delay::215 216  # i2cset -y 0 0x30 5 0xc9 0x00 100 i217 218If the host controller supports SMBusAlert, this message with debug level219should appear::220 221  smbus_alert 0-000c: SMBALERT# from dev 0x64, flag 1222 223This message may appear more than once because the testunit is software not224hardware and, thus, may not be able to react to the response of the host fast225enough. The interrupt count should increase only by one, though::226 227  # cat /proc/interrupts | grep smbus_alert228   93:          1  gpio-rcar  26 Edge      smbus_alert229 230If the host does not respond to the alert within 1 second, the test will be231aborted and the testunit will report an error.232 233For this test, the testunit will shortly drop its assigned address and listen234on the SMBus Alert Response Address (0x0c). It will reassign its original235address afterwards.236