@samitouri / QOSamiQemu / commits / c7300dca45

tests/qtest: adc128d818: test voltage and temperature conversion

Cover single-ended voltage conversion across all channels, voltage and temperature boundary and clamping cases, and scaling against an external voltage reference. Signed-off-by: Emmanuel Blot <emmanuel.blot@free.fr> Link: https://lore.kernel.org/qemu-devel/20260707091609.97759-4-emmanuel.blot@free.fr Signed-off-by: Cédric Le Goater <clg@redhat.com>

Emmanuel Blot committed Jul 7, 2026 at 11:15 UTC c7300dca454f266a5cc52ea08775db50489cc755
1 file changed +189
tests/qtest/adc128d818-test.c
+189
@@ -150,6 +150,186 @@ static void test_ain_property(void *obj, void *data, QGuestAllocator *alloc)
150 g_assert_cmpint(value, ==, 37500);
151 }
152
153 +/* Voltage conversion */
154 +static void test_voltage_conversion(void *obj, void *data,
155 + QGuestAllocator *alloc)
156 +{
157 + QI2CDevice *dev = (QI2CDevice *)obj;
158 + uint16_t reading;
159 +
160 + qmp_adc128d818_set("ain0", 1280);
161 + g_test_message("Injected ain0 = 1280 mV");
162 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
163 +
164 + reading = i2c_get16(dev, REG_CH_READING_BASE);
165 + g_test_message("Read ch0: raw 0x%04x -> %u mV", reading,
166 + (reading >> 4u) * INTERNAL_VREF_MV / 4096u);
167 + g_assert_cmphex(reading, ==, 0x8000);
168 +
169 + qmp_adc128d818_set("ain1", 2560);
170 + g_test_message("Injected ain1 = 2560 mV");
171 + reading = i2c_get16(dev, REG_CH_READING_BASE + 1u);
172 + g_test_message("Read ch1: raw 0x%04x -> %u mV", reading,
173 + (reading >> 4u) * INTERNAL_VREF_MV / 4096u);
174 + g_assert_cmphex(reading, ==, 0xFFF0);
175 +
176 + qmp_adc128d818_set("ain2", 0);
177 + g_test_message("Injected ain2 = 0 mV");
178 + reading = i2c_get16(dev, REG_CH_READING_BASE + 2u);
179 + g_test_message("Read ch2: raw 0x%04x -> %u mV", reading,
180 + (reading >> 4u) * INTERNAL_VREF_MV / 4096u);
181 + g_assert_cmphex(reading, ==, 0x0000);
182 +}
183 +
184 +/* Temperature conversion (mode 0, channel 7 = temperature) */
185 +static void
186 +test_temperature_conversion(void *obj, void *data, QGuestAllocator *alloc)
187 +{
188 + QI2CDevice *dev = (QI2CDevice *)obj;
189 + uint16_t reading;
190 +
191 + qmp_adc128d818_set("temperature", 25000);
192 + g_test_message("Injected temperature = 25000 mC (25.0 deg C)");
193 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
194 +
195 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
196 + g_test_message("Read ch7: raw 0x%04x -> %d mC", reading,
197 + (int16_t)(reading & 0xFF80u) * 500 / 128);
198 + g_assert_cmphex(reading, ==, 0x1900);
199 +}
200 +
201 +/* Channels with distinct voltages */
202 +static void test_all_channels(void *obj, void *data, QGuestAllocator *alloc)
203 +{
204 + QI2CDevice *dev = (QI2CDevice *)obj;
205 + static const uint16_t ain_mv[NUM_CHANNELS] = {
206 + 0, 320, 640, 960, 1280, 1920, 2240, 2560
207 + };
208 + static const uint16_t expect[NUM_CHANNELS] = {
209 + 0x0000, 0x2000, 0x4000, 0x6000, 0x8000, 0xC000, 0xE000, 0xFFF0
210 + };
211 + uint16_t reading;
212 + unsigned ch;
213 +
214 + i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
215 + i2c_set8(dev, REG_ADV_CONFIG, ADV_CONFIG_MODE_1);
216 +
217 + for (ch = 0u; ch < NUM_CHANNELS; ch++) {
218 + char name[8];
219 + snprintf(name, sizeof(name), "ain%u", ch);
220 + qmp_adc128d818_set(name, ain_mv[ch]);
221 + }
222 +
223 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
224 +
225 + for (ch = 0u; ch < NUM_CHANNELS; ch++) {
226 + reading = i2c_get16(dev, REG_CH_READING_BASE + ch);
227 + g_test_message("ch%u: ain %u mV -> raw 0x%04x (expect 0x%04x)",
228 + ch, ain_mv[ch], reading, expect[ch]);
229 + g_assert_cmphex(reading, ==, expect[ch]);
230 + }
231 +}
232 +
233 +/* Voltage conversion edge cases */
234 +static void test_voltage_edges(void *obj, void *data, QGuestAllocator *alloc)
235 +{
236 + QI2CDevice *dev = (QI2CDevice *)obj;
237 + uint16_t reading;
238 +
239 + i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
240 + i2c_set8(dev, REG_ADV_CONFIG, ADV_CONFIG_MODE_1);
241 +
242 + qmp_adc128d818_set("ain0", 3000);
243 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
244 +
245 + reading = i2c_get16(dev, REG_CH_READING_BASE);
246 + g_test_message("Over-range 3000 mV: raw 0x%04x (expect 0xFFF0)", reading);
247 + g_assert_cmphex(reading, ==, 0xFFF0);
248 +
249 + qmp_adc128d818_set("ain1", 1);
250 + reading = i2c_get16(dev, REG_CH_READING_BASE + 1u);
251 + g_test_message("1 mV: raw 0x%04x (expect 0x0010)", reading);
252 + g_assert_cmphex(reading, ==, 0x0010);
253 +
254 + qmp_adc128d818_set("ain2", 640);
255 + reading = i2c_get16(dev, REG_CH_READING_BASE + 2u);
256 + g_test_message("640 mV (quarter): raw 0x%04x (expect 0x4000)", reading);
257 + g_assert_cmphex(reading, ==, 0x4000);
258 +
259 + qmp_adc128d818_set("ain3", 1920);
260 + reading = i2c_get16(dev, REG_CH_READING_BASE + 3u);
261 + g_test_message("1920 mV (3/4): raw 0x%04x (expect 0xC000)", reading);
262 + g_assert_cmphex(reading, ==, 0xC000);
263 +}
264 +
265 +/* Temperature conversion edge cases */
266 +static void test_temperature_edges(void *obj, void *data,
267 + QGuestAllocator *alloc)
268 +{
269 + QI2CDevice *dev = (QI2CDevice *)obj;
270 + uint16_t reading;
271 +
272 + i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
273 +
274 + qmp_adc128d818_set("temperature", 0);
275 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
276 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
277 + g_test_message("0 C: raw 0x%04x (expect 0x0000)", reading);
278 + g_assert_cmphex(reading, ==, 0x0000);
279 +
280 + qmp_adc128d818_set("temperature", -25000);
281 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
282 + g_test_message("-25 C: raw 0x%04x (expect 0xE700)", reading);
283 + g_assert_cmphex(reading, ==, 0xE700);
284 +
285 + qmp_adc128d818_set("temperature", 127500);
286 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
287 + g_test_message("+127.5 C: raw 0x%04x (expect 0x7F80)", reading);
288 + g_assert_cmphex(reading, ==, 0x7F80);
289 +
290 + qmp_adc128d818_set("temperature", -128000);
291 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
292 + g_test_message("-128 C: raw 0x%04x (expect 0x8000)", reading);
293 + g_assert_cmphex(reading, ==, 0x8000);
294 +
295 + qmp_adc128d818_set("temperature", 200000);
296 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
297 + g_test_message("200 C (clamped): raw 0x%04x (expect 0x7F80)", reading);
298 + g_assert_cmphex(reading, ==, 0x7F80);
299 +
300 + qmp_adc128d818_set("temperature", -200000);
301 + reading = i2c_get16(dev, REG_CH_READING_BASE + 7u);
302 + g_test_message("-200 C (clamped): raw 0x%04x (expect 0x8000)", reading);
303 + g_assert_cmphex(reading, ==, 0x8000);
304 +}
305 +
306 +/* External voltage reference */
307 +static void test_ext_vref(void *obj, void *data, QGuestAllocator *alloc)
308 +{
309 + QI2CDevice *dev = (QI2CDevice *)obj;
310 + uint16_t reading;
311 +
312 + i2c_set8(dev, REG_CONFIG, CONFIG_INITIALIZATION);
313 + i2c_set8(dev, REG_ADV_CONFIG, ADV_CONFIG_MODE_1);
314 +
315 + qmp_adc128d818_set("ext-vref-mv", 4096);
316 + i2c_set8(dev, REG_ADV_CONFIG, ADV_CONFIG_EXT_REF_EN | ADV_CONFIG_MODE_1);
317 +
318 + qmp_adc128d818_set("ain0", 1000);
319 + i2c_set8(dev, REG_CONFIG, CONFIG_START);
320 +
321 + reading = i2c_get16(dev, REG_CH_READING_BASE);
322 + g_test_message("1000 mV / 4096 mV VREF: raw 0x%04x (expect 0x3E80)",
323 + reading);
324 + g_assert_cmphex(reading, ==, 0x3E80);
325 +
326 + qmp_adc128d818_set("ain1", 2048);
327 + reading = i2c_get16(dev, REG_CH_READING_BASE + 1u);
328 + g_test_message("2048 mV / 4096 mV VREF: raw 0x%04x (expect 0x8000)",
329 + reading);
330 + g_assert_cmphex(reading, ==, 0x8000);
331 +}
332 +
333 static void adc128d818_register_nodes(void)
334 {
335 QOSGraphEdgeOptions opts = {
@@ -165,5 +345,14 @@ static void adc128d818_register_nodes(void)
345 qos_add_test("defaults", "adc128d818", test_defaults, NULL);
346 qos_add_test("soft-reset", "adc128d818", test_soft_reset, NULL);
347 qos_add_test("ain-property", "adc128d818", test_ain_property, NULL);
348 + qos_add_test("voltage-conversion", "adc128d818", test_voltage_conversion,
349 + NULL);
350 + qos_add_test("temperature-conversion", "adc128d818",
351 + test_temperature_conversion, NULL);
352 + qos_add_test("all-channels", "adc128d818", test_all_channels, NULL);
353 + qos_add_test("voltage-edges", "adc128d818", test_voltage_edges, NULL);
354 + qos_add_test("temperature-edges", "adc128d818", test_temperature_edges,
355 + NULL);
356 + qos_add_test("ext-vref", "adc128d818", test_ext_vref, NULL);
357 }
358 libqos_init(adc128d818_register_nodes);