@samitouri / QOSamiQemu / commits / f9bf753b58

tests/qtest: pca9554: test absence of command auto-increment

The PCA9554 selects one of its four registers with a single command byte and does not auto-increment the register pointer, so a multi-byte I2C transfer keeps addressing the register chosen by the command byte instead of walking through the register map. Add a test covering this: a two-byte read returns the addressed register twice, and a two-byte write updates only that register, leaving its neighbour untouched. Signed-off-by: Emmanuel Blot <emmanuel.blot@free.fr> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260709-catalina-upgrade-v1-22-82a63fead90c@free.fr Signed-off-by: Cédric Le Goater <clg@redhat.com>

Emmanuel Blot committed Jul 9, 2026 at 17:23 UTC f9bf753b58c83d689f535f6b1ab217f4a46aa35f
1 file changed +28
tests/qtest/pca9554-test.c
+28
@@ -102,6 +102,33 @@ static void test_polarity_with_output(void *obj, void *data,
102 g_assert_cmphex(i2c_get8(dev, PCA9554_OUTPUT), ==, 0xA5);
103 }
104
105 +/*
106 + * The PCA9554 has no auto-increment: the command pointer never advances, so
107 + * multi-byte reads and writes all target the addressed register.
108 + */
109 +static void test_no_autoincrement(void *obj, void *data,
110 + QGuestAllocator *alloc)
111 +{
112 + QI2CDevice *dev = (QI2CDevice *)obj;
113 + uint8_t buf[2];
114 +
115 + /* Distinct values in adjacent registers. */
116 + i2c_set8(dev, PCA9554_OUTPUT, 0xAA);
117 + i2c_set8(dev, PCA9554_POLARITY, 0x33);
118 +
119 + /* Two reads from OUTPUT return OUTPUT twice, not OUTPUT then POLARITY. */
120 + i2c_read_block(dev, PCA9554_OUTPUT, buf, 2);
121 + g_assert_cmphex(buf[0], ==, 0xAA);
122 + g_assert_cmphex(buf[1], ==, 0xAA);
123 +
124 + /* The second written byte overwrites OUTPUT; POLARITY is untouched. */
125 + buf[0] = 0x12;
126 + buf[1] = 0x34;
127 + i2c_write_block(dev, PCA9554_OUTPUT, buf, 2);
128 + g_assert_cmphex(i2c_get8(dev, PCA9554_OUTPUT), ==, 0x34);
129 + g_assert_cmphex(i2c_get8(dev, PCA9554_POLARITY), ==, 0x33);
130 +}
131 +
132 static void pca9554_register_nodes(void)
133 {
134 QOSGraphEdgeOptions opts = {
@@ -120,6 +147,7 @@ static void pca9554_register_nodes(void)
147 NULL);
148 qos_add_test("polarity-with-output", "pca9554", test_polarity_with_output,
149 NULL);
150 + qos_add_test("no-autoincrement", "pca9554", test_no_autoincrement, NULL);
151 }
152
153 libqos_init(pca9554_register_nodes);