1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Unit tests for IIO multiply functions 3 * 4 * Copyright (c) 2025 Hans de Goede <hans@hansg.org> 5 * Based on iio-test-format.c which is: 6 * Copyright (c) 2020 Lars-Peter Clausen <lars@metafoo.de> 7 */ 8 9 #include <kunit/test.h> 10 #include <linux/iio/consumer.h> 11 #include <linux/math64.h> 12 #include <linux/types.h> 13 14 static void __iio_test_iio_multiply_value_integer(struct kunit *test, s64 multiplier) 15 { 16 int ret, result, val; 17 18 val = 42; 19 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); 20 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 21 KUNIT_EXPECT_EQ(test, result, multiplier * val); 22 23 val = -23; 24 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); 25 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 26 KUNIT_EXPECT_EQ(test, result, multiplier * val); 27 28 val = 0; 29 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); 30 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 31 KUNIT_EXPECT_EQ(test, result, multiplier * val); 32 } 33 34 static void iio_test_iio_multiply_value_integer(struct kunit *test) 35 { 36 __iio_test_iio_multiply_value_integer(test, 20); 37 __iio_test_iio_multiply_value_integer(test, -20); 38 } 39 40 static void __iio_test_iio_multiply_value_fixedpoint(struct kunit *test, s64 multiplier) 41 { 42 int ret, result, val, val2; 43 44 /* positive >= 1 (1.5) */ 45 val = 1; 46 val2 = 500000; 47 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); 48 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 49 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 15, 10)); 50 51 val = 1; 52 val2 = 500000000; 53 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); 54 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 55 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 15, 10)); 56 57 /* positive < 1 (0.5) */ 58 val = 0; 59 val2 = 500000; 60 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); 61 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 62 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 5, 10)); 63 64 val = 0; 65 val2 = 500000000; 66 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); 67 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 68 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 5, 10)); 69 70 /* negative <= -1 (-1.5) */ 71 val = -1; 72 val2 = 500000; 73 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); 74 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 75 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -15, 10)); 76 77 val = -1; 78 val2 = 500000000; 79 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); 80 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 81 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -15, 10)); 82 83 /* negative > -1 (-0.5) */ 84 val = 0; 85 val2 = -500000; 86 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); 87 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 88 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -5, 10)); 89 90 val = 0; 91 val2 = -500000000; 92 ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); 93 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 94 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -5, 10)); 95 } 96 97 static void iio_test_iio_multiply_value_fixedpoint(struct kunit *test) 98 { 99 __iio_test_iio_multiply_value_fixedpoint(test, 20); 100 __iio_test_iio_multiply_value_fixedpoint(test, -20); 101 } 102 103 static void __iio_test_iio_multiply_value_fractional(struct kunit *test, s64 multiplier) 104 { 105 int ret, result, val, val2; 106 107 /* positive < 1 (1/10)*/ 108 val = 1; 109 val2 = 10; 110 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); 111 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 112 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); 113 114 /* positive >= 1 (100/3)*/ 115 val = 100; 116 val2 = 3; 117 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); 118 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 119 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); 120 121 /* negative > -1 (-1/10) */ 122 val = -1; 123 val2 = 10; 124 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); 125 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 126 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); 127 128 /* negative <= -1 (-200/3)*/ 129 val = -200; 130 val2 = 3; 131 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); 132 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 133 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); 134 135 /* Zero (0/-10) */ 136 val = 0; 137 val2 = -10; 138 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); 139 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 140 KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); 141 } 142 143 static void iio_test_iio_multiply_value_fractional(struct kunit *test) 144 { 145 __iio_test_iio_multiply_value_fractional(test, 20); 146 __iio_test_iio_multiply_value_fractional(test, -20); 147 } 148 149 static void __iio_test_iio_multiply_value_fractional_log2(struct kunit *test, s64 multiplier) 150 { 151 int ret, result, val, val2; 152 153 /* positive < 1 (123/1024) */ 154 val = 123; 155 val2 = 10; 156 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); 157 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 158 KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); 159 160 /* positive >= 1 (1234567/1024) */ 161 val = 1234567; 162 val2 = 10; 163 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); 164 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 165 KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); 166 167 /* negative > -1 (-123/1024) */ 168 val = -123; 169 val2 = 10; 170 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); 171 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 172 KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); 173 174 /* negative <= -1 (-1234567/1024) */ 175 val = -1234567; 176 val2 = 10; 177 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); 178 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 179 KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); 180 181 /* Zero (0/1024) */ 182 val = 0; 183 val2 = 10; 184 ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); 185 KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); 186 KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); 187 } 188 189 static void iio_test_iio_multiply_value_fractional_log2(struct kunit *test) 190 { 191 __iio_test_iio_multiply_value_fractional_log2(test, 20); 192 __iio_test_iio_multiply_value_fractional_log2(test, -20); 193 } 194 195 static struct kunit_case iio_multiply_test_cases[] = { 196 KUNIT_CASE(iio_test_iio_multiply_value_integer), 197 KUNIT_CASE(iio_test_iio_multiply_value_fixedpoint), 198 KUNIT_CASE(iio_test_iio_multiply_value_fractional), 199 KUNIT_CASE(iio_test_iio_multiply_value_fractional_log2), 200 { } 201 }; 202 203 static struct kunit_suite iio_multiply_test_suite = { 204 .name = "iio-multiply", 205 .test_cases = iio_multiply_test_cases, 206 }; 207 kunit_test_suite(iio_multiply_test_suite); 208 209 MODULE_AUTHOR("Hans de Goede <hans@hansg.org>"); 210 MODULE_DESCRIPTION("Test IIO multiply functions"); 211 MODULE_LICENSE("GPL"); 212 MODULE_IMPORT_NS("IIO_UNIT_TEST"); 213