[PATCH 7/8] hw/sensor: adm1266: expose vout_mode over QMP

Titus Rwantare <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
The vout_mode registers can now be adjusted to allow a wider value range
in read_vout.
vout_mode is per pmbus page, therefore vout_mode[n] will affect
read_vout[n].

Signed-off-by: Titus Rwantare <[email protected]>
---
 hw/sensor/adm1266.c        |  8 ++++++++
 tests/qtest/adm1266-test.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/hw/sensor/adm1266.c b/hw/sensor/adm1266.c
index 80960dc1c4..1464307971 100644
--- a/hw/sensor/adm1266.c
+++ b/hw/sensor/adm1266.c
@@ -271,6 +271,8 @@ static void adm1266_get(Object *obj, Visitor *v, const char *name, void *opaque,
         sscanf(name, "vout[%u]", &index);
         mode = (PMBusVoutMode *)&pmdev->pages[index].vout_mode;
         value = pmbus_linear_mode2milliunits(*(uint16_t *)opaque, mode->exp);
+    } else if (strncmp(name, "vout_mode", 9) == 0) {
+        value = *(uint8_t *)opaque;
     } else {
         value = *(uint16_t *)opaque;
     }
@@ -293,6 +295,8 @@ static void adm1266_set(Object *obj, Visitor *v, const char *name, void *opaque,
         sscanf(name, "vout[%u]", &index);
         mode = (PMBusVoutMode *)&pmdev->pages[index].vout_mode;
         *internal = pmbus_milliunits2linear_mode(value, mode->exp);
+    } else if (strncmp(name, "vout_mode", 9) == 0) {
+        *(uint8_t *)opaque = value;
     } else {
         *internal = value;
     }
@@ -321,6 +325,10 @@ static void adm1266_init(Object *obj)
         object_property_add(obj, "vout[*]", "uint32",
                             adm1266_get,
                             adm1266_set, NULL, &pmdev->pages[i].read_vout);
+
+        object_property_add(obj, "vout_mode[*]", "uint32",
+                            adm1266_get,
+                            adm1266_set, NULL, &pmdev->pages[i].vout_mode);
     }
 }
 
diff --git a/tests/qtest/adm1266-test.c b/tests/qtest/adm1266-test.c
index fd3d8079b6..9cdd206c3f 100644
--- a/tests/qtest/adm1266-test.c
+++ b/tests/qtest/adm1266-test.c
@@ -186,6 +186,40 @@ static void test_vout_mode_exponent(void *obj, void *data,
     }
 }
 
+static void test_vout_mode_qmp(void *obj, void *data,
+                                    QGuestAllocator *alloc)
+{
+    uint16_t i2c_value, value, expected;
+    QI2CDevice *i2cdev = (QI2CDevice *)obj;
+    ADM1266VoutMode m;
+    char *path;
+
+    /* set a different exponent per page and a different value */
+    for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
+        expected = 1000 * (i * 2);
+        m.mode.exp = i - 14;
+        path = g_strdup_printf("vout_mode[%d]", i);
+        qmp_adm1266_set(TEST_ID, path, m.raw);
+        path = g_strdup_printf("vout[%d]", i);
+        qmp_adm1266_set(TEST_ID, path, expected);
+    }
+
+    for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
+        i2c_set8(i2cdev, PMBUS_PAGE, i);
+        expected = 1000 * (i * 2);
+        /* check correct value from i2c*/
+        m.raw = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
+        i2c_value = bswap16(i2c_get16(i2cdev, PMBUS_READ_VOUT));
+        i2c_value = adm1266_linear_mode2milliunits(i2c_value, m.mode.exp);
+        g_assert_cmpuint(i2c_value, ==, expected);
+
+        /* check correct value from qmp*/
+        path = g_strdup_printf("vout[%d]", i);
+        value = qmp_adm1266_get(TEST_ID, path);
+        g_assert_cmpuint(value, ==, expected);
+    }
+}
+
 static void test_vout_clamp_to_max(void *obj, void *data,
                                    QGuestAllocator *alloc)
 {
@@ -278,6 +312,7 @@ static void adm1266_register_nodes(void)
                     test_vout_mode_exponent, NULL);
     qos_add_test("test_vout_clamp_to_max", "adm1266",
                     test_vout_clamp_to_max, NULL);
+    qos_add_test("test_vout_mode_qmp", "adm1266", test_vout_mode_qmp, NULL);
 }
 
 libqos_init(adm1266_register_nodes);
-- 
2.55.0.508.g3f0d502094-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.