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