| // SPDX-License-Identifier: GPL-2.0-only |
| /* Unit tests for IIO multiply functions |
| * |
| * Copyright (c) 2025 Hans de Goede <hans@hansg.org> |
| * Based on iio-test-format.c which is: |
| * Copyright (c) 2020 Lars-Peter Clausen <lars@metafoo.de> |
| */ |
| |
| #include <kunit/test.h> |
| #include <linux/iio/consumer.h> |
| #include <linux/math64.h> |
| #include <linux/types.h> |
| |
| static void __iio_test_iio_multiply_value_integer(struct kunit *test, s64 multiplier) |
| { |
| int ret, result, val; |
| |
| val = 42; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, multiplier * val); |
| |
| val = -23; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, multiplier * val); |
| |
| val = 0; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT, val, 0); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, multiplier * val); |
| } |
| |
| static void iio_test_iio_multiply_value_integer(struct kunit *test) |
| { |
| __iio_test_iio_multiply_value_integer(test, 20); |
| __iio_test_iio_multiply_value_integer(test, -20); |
| } |
| |
| static void __iio_test_iio_multiply_value_fixedpoint(struct kunit *test, s64 multiplier) |
| { |
| int ret, result, val, val2; |
| |
| /* positive >= 1 (1.5) */ |
| val = 1; |
| val2 = 500000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 15, 10)); |
| |
| val = 1; |
| val2 = 500000000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 15, 10)); |
| |
| /* positive < 1 (0.5) */ |
| val = 0; |
| val2 = 500000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 5, 10)); |
| |
| val = 0; |
| val2 = 500000000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * 5, 10)); |
| |
| /* negative <= -1 (-1.5) */ |
| val = -1; |
| val2 = 500000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -15, 10)); |
| |
| val = -1; |
| val2 = 500000000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -15, 10)); |
| |
| /* negative > -1 (-0.5) */ |
| val = 0; |
| val2 = -500000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_MICRO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -5, 10)); |
| |
| val = 0; |
| val2 = -500000000; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_INT_PLUS_NANO, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * -5, 10)); |
| } |
| |
| static void iio_test_iio_multiply_value_fixedpoint(struct kunit *test) |
| { |
| __iio_test_iio_multiply_value_fixedpoint(test, 20); |
| __iio_test_iio_multiply_value_fixedpoint(test, -20); |
| } |
| |
| static void __iio_test_iio_multiply_value_fractional(struct kunit *test, s64 multiplier) |
| { |
| int ret, result, val, val2; |
| |
| /* positive < 1 (1/10)*/ |
| val = 1; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); |
| |
| /* positive >= 1 (100/3)*/ |
| val = 100; |
| val2 = 3; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); |
| |
| /* negative > -1 (-1/10) */ |
| val = -1; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); |
| |
| /* negative <= -1 (-200/3)*/ |
| val = -200; |
| val2 = 3; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); |
| |
| /* Zero (0/-10) */ |
| val = 0; |
| val2 = -10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, div_s64(multiplier * val, val2)); |
| } |
| |
| static void iio_test_iio_multiply_value_fractional(struct kunit *test) |
| { |
| __iio_test_iio_multiply_value_fractional(test, 20); |
| __iio_test_iio_multiply_value_fractional(test, -20); |
| } |
| |
| static void __iio_test_iio_multiply_value_fractional_log2(struct kunit *test, s64 multiplier) |
| { |
| int ret, result, val, val2; |
| |
| /* positive < 1 (123/1024) */ |
| val = 123; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); |
| |
| /* positive >= 1 (1234567/1024) */ |
| val = 1234567; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); |
| |
| /* negative > -1 (-123/1024) */ |
| val = -123; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); |
| |
| /* negative <= -1 (-1234567/1024) */ |
| val = -1234567; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); |
| |
| /* Zero (0/1024) */ |
| val = 0; |
| val2 = 10; |
| ret = iio_multiply_value(&result, multiplier, IIO_VAL_FRACTIONAL_LOG2, val, val2); |
| KUNIT_EXPECT_EQ(test, ret, IIO_VAL_INT); |
| KUNIT_EXPECT_EQ(test, result, (multiplier * val) >> val2); |
| } |
| |
| static void iio_test_iio_multiply_value_fractional_log2(struct kunit *test) |
| { |
| __iio_test_iio_multiply_value_fractional_log2(test, 20); |
| __iio_test_iio_multiply_value_fractional_log2(test, -20); |
| } |
| |
| static struct kunit_case iio_multiply_test_cases[] = { |
| KUNIT_CASE(iio_test_iio_multiply_value_integer), |
| KUNIT_CASE(iio_test_iio_multiply_value_fixedpoint), |
| KUNIT_CASE(iio_test_iio_multiply_value_fractional), |
| KUNIT_CASE(iio_test_iio_multiply_value_fractional_log2), |
| { } |
| }; |
| |
| static struct kunit_suite iio_multiply_test_suite = { |
| .name = "iio-multiply", |
| .test_cases = iio_multiply_test_cases, |
| }; |
| kunit_test_suite(iio_multiply_test_suite); |
| |
| MODULE_AUTHOR("Hans de Goede <hans@hansg.org>"); |
| MODULE_DESCRIPTION("Test IIO multiply functions"); |
| MODULE_LICENSE("GPL"); |
| MODULE_IMPORT_NS("IIO_UNIT_TEST"); |