Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Kunit tests for IIO rescale conversions
0004  *
0005  * Copyright (c) 2021 Liam Beguin <liambeguin@gmail.com>
0006  */
0007 
0008 #include <linux/gcd.h>
0009 #include <linux/overflow.h>
0010 
0011 #include <linux/iio/afe/rescale.h>
0012 #include <linux/iio/iio.h>
0013 
0014 #include <kunit/test.h>
0015 
0016 struct rescale_tc_data {
0017     const char *name;
0018 
0019     const s32 numerator;
0020     const s32 denominator;
0021     const s32 offset;
0022 
0023     const int schan_val;
0024     const int schan_val2;
0025     const int schan_off;
0026     const int schan_scale_type;
0027 
0028     const char *expected;
0029     const char *expected_off;
0030 };
0031 
0032 const struct rescale_tc_data scale_cases[] = {
0033     /*
0034      * Typical use cases
0035      */
0036     {
0037         .name = "typical IIO_VAL_INT, positive",
0038         .numerator = 1000000,
0039         .denominator = 8060,
0040         .schan_scale_type = IIO_VAL_INT,
0041         .schan_val = 42,
0042         .expected = "5210.918114143",
0043     },
0044     {
0045         .name = "typical IIO_VAL_INT, negative",
0046         .numerator = -1000000,
0047         .denominator = 8060,
0048         .schan_scale_type = IIO_VAL_INT,
0049         .schan_val = 42,
0050         .expected = "-5210.918114143",
0051     },
0052     {
0053         .name = "typical IIO_VAL_FRACTIONAL, positive",
0054         .numerator = 1000000,
0055         .denominator = 8060,
0056         .schan_scale_type = IIO_VAL_FRACTIONAL,
0057         .schan_val = 42,
0058         .schan_val2 = 20,
0059         .expected = "260.545905707",
0060     },
0061     {
0062         .name = "typical IIO_VAL_FRACTIONAL, negative",
0063         .numerator = -1000000,
0064         .denominator = 8060,
0065         .schan_scale_type = IIO_VAL_FRACTIONAL,
0066         .schan_val = 42,
0067         .schan_val2 = 20,
0068         .expected = "-260.545905707",
0069     },
0070     {
0071         .name = "typical IIO_VAL_FRACTIONAL_LOG2, positive",
0072         .numerator = 42,
0073         .denominator = 53,
0074         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0075         .schan_val = 4096,
0076         .schan_val2 = 16,
0077         .expected = "0.049528301",
0078     },
0079     {
0080         .name = "typical IIO_VAL_FRACTIONAL_LOG2, negative",
0081         .numerator = -42,
0082         .denominator = 53,
0083         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0084         .schan_val = 4096,
0085         .schan_val2 = 16,
0086         .expected = "-0.049528301",
0087     },
0088     {
0089         .name = "typical IIO_VAL_INT_PLUS_NANO, positive",
0090         .numerator = 1000000,
0091         .denominator = 8060,
0092         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0093         .schan_val = 10,
0094         .schan_val2 = 123456,
0095         .expected = "1240.710106203",
0096     },
0097     {
0098         .name = "typical IIO_VAL_INT_PLUS_NANO, negative",
0099         .numerator = -1000000,
0100         .denominator = 8060,
0101         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0102         .schan_val = 10,
0103         .schan_val2 = 123456,
0104         .expected = "-1240.710106203",
0105     },
0106     {
0107         .name = "typical IIO_VAL_INT_PLUS_MICRO, positive",
0108         .numerator = 1000000,
0109         .denominator = 8060,
0110         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0111         .schan_val = 10,
0112         .schan_val2 = 1234,
0113         .expected = "1240.84789",
0114     },
0115     {
0116         .name = "typical IIO_VAL_INT_PLUS_MICRO, negative",
0117         .numerator = -1000000,
0118         .denominator = 8060,
0119         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0120         .schan_val = 10,
0121         .schan_val2 = 1234,
0122         .expected = "-1240.84789",
0123     },
0124     /*
0125      * Use cases with small scales involving divisions
0126      */
0127     {
0128         .name = "small IIO_VAL_FRACTIONAL, 261/509 scaled by 90/1373754273",
0129         .numerator = 261,
0130         .denominator = 509,
0131         .schan_scale_type = IIO_VAL_FRACTIONAL,
0132         .schan_val = 90,
0133         .schan_val2 = 1373754273,
0134         .expected = "0.000000033594",
0135     },
0136     {
0137         .name = "small IIO_VAL_FRACTIONAL, 90/1373754273 scaled by 261/509",
0138         .numerator = 90,
0139         .denominator = 1373754273,
0140         .schan_scale_type = IIO_VAL_FRACTIONAL,
0141         .schan_val = 261,
0142         .schan_val2 = 509,
0143         .expected = "0.000000033594",
0144     },
0145     {
0146         .name = "small IIO_VAL_FRACTIONAL, 760/1373754273 scaled by 427/2727",
0147         .numerator = 760,
0148         .denominator = 1373754273,
0149         .schan_scale_type = IIO_VAL_FRACTIONAL,
0150         .schan_val = 427,
0151         .schan_val2 = 2727,
0152         .expected = "0.000000086626",
0153     },
0154     {
0155         .name = "small IIO_VAL_FRACTIONAL, 761/1373754273 scaled by 427/2727",
0156         .numerator = 761,
0157         .denominator = 1373754273,
0158         .schan_scale_type = IIO_VAL_FRACTIONAL,
0159         .schan_val = 427,
0160         .schan_val2 = 2727,
0161         .expected = "0.000000086740",
0162     },
0163     {
0164         .name = "small IIO_VAL_FRACTIONAL, 5/32768 scaled by 3/10000",
0165         .numerator = 5,
0166         .denominator = 32768,
0167         .schan_scale_type = IIO_VAL_FRACTIONAL,
0168         .schan_val = 3,
0169         .schan_val2 = 10000,
0170         .expected = "0.0000000457763671875",
0171     },
0172     {
0173         .name = "small IIO_VAL_FRACTIONAL, 0 < scale < 1",
0174         .numerator = 6,
0175         .denominator = 6,
0176         .schan_scale_type = IIO_VAL_FRACTIONAL,
0177         .schan_val = 1,
0178         .schan_val2 = 3,
0179         .expected = "0.3333333333333333",
0180     },
0181     {
0182         .name = "small IIO_VAL_FRACTIONAL, -1 < scale < 0",
0183         .numerator = -6,
0184         .denominator = 6,
0185         .schan_scale_type = IIO_VAL_FRACTIONAL,
0186         .schan_val = 1,
0187         .schan_val2 = 3,
0188         .expected = "-0.3333333333333333",
0189     },
0190     {
0191         .name = "small IIO_VAL_FRACTIONAL, 0 < scale < 2",
0192         .numerator = 8,
0193         .denominator = 2,
0194         .schan_scale_type = IIO_VAL_FRACTIONAL,
0195         .schan_val = 1,
0196         .schan_val2 = 3,
0197         .expected = "1.3333333333333333",
0198     },
0199     {
0200         .name = "small IIO_VAL_FRACTIONAL, -2 < scale < 0",
0201         .numerator = -8,
0202         .denominator = 2,
0203         .schan_scale_type = IIO_VAL_FRACTIONAL,
0204         .schan_val = 1,
0205         .schan_val2 = 3,
0206         .expected = "-1.3333333333333333",
0207     },
0208     {
0209         .name = "small IIO_VAL_FRACTIONAL_LOG2, 760/32768 scaled by 15/22",
0210         .numerator = 760,
0211         .denominator = 32768,
0212         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0213         .schan_val = 15,
0214         .schan_val2 = 22,
0215         .expected = "0.000000082946",
0216     },
0217     {
0218         .name = "small IIO_VAL_FRACTIONAL_LOG2, 761/32768 scaled by 15/22",
0219         .numerator = 761,
0220         .denominator = 32768,
0221         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0222         .schan_val = 15,
0223         .schan_val2 = 22,
0224         .expected = "0.000000083055",
0225     },
0226     {
0227         .name = "small IIO_VAL_FRACTIONAL_LOG2, 0 < scale < 1",
0228         .numerator = 16,
0229         .denominator = 3,
0230         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0231         .schan_val = 1,
0232         .schan_val2 = 4,
0233         .expected = "0.3333333333333333",
0234     },
0235     {
0236         .name = "small IIO_VAL_FRACTIONAL_LOG2, -1 < scale < 0",
0237         .numerator = -16,
0238         .denominator = 3,
0239         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0240         .schan_val = 1,
0241         .schan_val2 = 4,
0242         .expected = "-0.3333333333333333",
0243     },
0244     {
0245         .name = "small IIO_VAL_FRACTIONAL_LOG2, 0 < scale < 2",
0246         .numerator = 8,
0247         .denominator = 3,
0248         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0249         .schan_val = 1,
0250         .schan_val2 = 1,
0251         .expected = "1.3333333333333333",
0252     },
0253     {
0254         .name = "small IIO_VAL_FRACTIONAL_LOG2, -2 < scale < 0",
0255         .numerator = -8,
0256         .denominator = 3,
0257         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0258         .schan_val = 1,
0259         .schan_val2 = 1,
0260         .expected = "-1.3333333333333333",
0261     },
0262     {
0263         .name = "small IIO_VAL_INT_PLUS_MICRO, positive",
0264         .numerator = 1,
0265         .denominator = 2,
0266         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0267         .schan_val = 5,
0268         .schan_val2 = 1234,
0269         .expected = "2.500617",
0270     },
0271     {
0272         .name = "small IIO_VAL_INT_PLUS_MICRO, negative",
0273         .numerator = -1,
0274         .denominator = 2,
0275         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0276         .schan_val = 5,
0277         .schan_val2 = 1234,
0278         .expected = "-2.500617",
0279     },
0280     /*
0281      * INT_PLUS_{MICRO,NANO} positive/negative corner cases
0282      */
0283     {
0284         .name = "negative IIO_VAL_INT_PLUS_NANO, negative schan",
0285         .numerator = 1000000,
0286         .denominator = 8060,
0287         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0288         .schan_val = -10,
0289         .schan_val2 = 123456,
0290         .expected = "-1240.710106203",
0291     },
0292     {
0293         .name = "negative IIO_VAL_INT_PLUS_NANO, both negative",
0294         .numerator = -1000000,
0295         .denominator = 8060,
0296         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0297         .schan_val = -10,
0298         .schan_val2 = 123456,
0299         .expected = "1240.710106203",
0300     },
0301     {
0302         .name = "negative IIO_VAL_INT_PLUS_NANO, 3 negative",
0303         .numerator = -1000000,
0304         .denominator = -8060,
0305         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0306         .schan_val = -10,
0307         .schan_val2 = 123456,
0308         .expected = "-1240.710106203",
0309     },
0310     {
0311         .name = "negative IIO_VAL_INT_PLUS_NANO, 4 negative",
0312         .numerator = -1000000,
0313         .denominator = -8060,
0314         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0315         .schan_val = -10,
0316         .schan_val2 = -123456,
0317         .expected = "-1240.710106203",
0318     },
0319     {
0320         .name = "negative IIO_VAL_INT_PLUS_NANO, negative, *val = 0",
0321         .numerator = 1,
0322         .denominator = -10,
0323         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0324         .schan_val = 0,
0325         .schan_val2 = 123456789,
0326         .expected = "-0.012345678",
0327     },
0328     /*
0329      * INT_PLUS_{MICRO,NANO} decimal part overflow
0330      */
0331     {
0332         .name = "decimal overflow IIO_VAL_INT_PLUS_NANO, positive",
0333         .numerator = 1000000,
0334         .denominator = 8060,
0335         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0336         .schan_val = 10,
0337         .schan_val2 = 123456789,
0338         .expected = "1256.01200856",
0339     },
0340     {
0341         .name = "decimal overflow IIO_VAL_INT_PLUS_NANO, negative",
0342         .numerator = -1000000,
0343         .denominator = 8060,
0344         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0345         .schan_val = 10,
0346         .schan_val2 = 123456789,
0347         .expected = "-1256.01200856",
0348     },
0349     {
0350         .name = "decimal overflow IIO_VAL_INT_PLUS_NANO, negative schan",
0351         .numerator = 1000000,
0352         .denominator = 8060,
0353         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0354         .schan_val = -10,
0355         .schan_val2 = 123456789,
0356         .expected = "-1256.01200856",
0357     },
0358     {
0359         .name = "decimal overflow IIO_VAL_INT_PLUS_MICRO, positive",
0360         .numerator = 1000000,
0361         .denominator = 8060,
0362         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0363         .schan_val = 10,
0364         .schan_val2 = 123456789,
0365         .expected = "16557.914267",
0366     },
0367     {
0368         .name = "decimal overflow IIO_VAL_INT_PLUS_MICRO, negative",
0369         .numerator = -1000000,
0370         .denominator = 8060,
0371         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0372         .schan_val = 10,
0373         .schan_val2 = 123456789,
0374         .expected = "-16557.914267",
0375     },
0376     {
0377         .name = "decimal overflow IIO_VAL_INT_PLUS_MICRO, negative schan",
0378         .numerator = 1000000,
0379         .denominator = 8060,
0380         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0381         .schan_val = -10,
0382         .schan_val2 = 123456789,
0383         .expected = "-16557.914267",
0384     },
0385     /*
0386      * 32-bit overflow conditions
0387      */
0388     {
0389         .name = "overflow IIO_VAL_FRACTIONAL, positive",
0390         .numerator = 2,
0391         .denominator = 20,
0392         .schan_scale_type = IIO_VAL_FRACTIONAL,
0393         .schan_val = S32_MAX,
0394         .schan_val2 = 1,
0395         .expected = "214748364.7",
0396     },
0397     {
0398         .name = "overflow IIO_VAL_FRACTIONAL, negative",
0399         .numerator = -2,
0400         .denominator = 20,
0401         .schan_scale_type = IIO_VAL_FRACTIONAL,
0402         .schan_val = S32_MAX,
0403         .schan_val2 = 1,
0404         .expected = "-214748364.7",
0405     },
0406     {
0407         .name = "overflow IIO_VAL_FRACTIONAL_LOG2, positive",
0408         .numerator = S32_MAX,
0409         .denominator = 4096,
0410         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0411         .schan_val = 4096,
0412         .schan_val2 = 16,
0413         .expected = "32767.99998474121",
0414     },
0415     {
0416         .name = "overflow IIO_VAL_FRACTIONAL_LOG2, negative",
0417         .numerator = S32_MAX,
0418         .denominator = 4096,
0419         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0420         .schan_val = -4096,
0421         .schan_val2 = 16,
0422         .expected = "-32767.99998474121",
0423     },
0424     {
0425         .name = "overflow IIO_VAL_INT_PLUS_NANO, positive",
0426         .numerator = 2,
0427         .denominator = 20,
0428         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0429         .schan_val = 10,
0430         .schan_val2 = S32_MAX,
0431         .expected = "1.214748364",
0432     },
0433     {
0434         .name = "overflow IIO_VAL_INT_PLUS_NANO, negative",
0435         .numerator = -2,
0436         .denominator = 20,
0437         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0438         .schan_val = 10,
0439         .schan_val2 = S32_MAX,
0440         .expected = "-1.214748364",
0441     },
0442     {
0443         .name = "overflow IIO_VAL_INT_PLUS_NANO, negative schan",
0444         .numerator = 2,
0445         .denominator = 20,
0446         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0447         .schan_val = -10,
0448         .schan_val2 = S32_MAX,
0449         .expected = "-1.214748364",
0450     },
0451     {
0452         .name = "overflow IIO_VAL_INT_PLUS_MICRO, positive",
0453         .numerator = 2,
0454         .denominator = 20,
0455         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0456         .schan_val = 10,
0457         .schan_val2 = S32_MAX,
0458         .expected = "215.748364",
0459     },
0460     {
0461         .name = "overflow IIO_VAL_INT_PLUS_MICRO, negative",
0462         .numerator = -2,
0463         .denominator = 20,
0464         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0465         .schan_val = 10,
0466         .schan_val2 = S32_MAX,
0467         .expected = "-215.748364",
0468     },
0469     {
0470         .name = "overflow IIO_VAL_INT_PLUS_MICRO, negative schan",
0471         .numerator = 2,
0472         .denominator = 20,
0473         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0474         .schan_val = -10,
0475         .schan_val2 = S32_MAX,
0476         .expected = "-215.748364",
0477     },
0478 };
0479 
0480 const struct rescale_tc_data offset_cases[] = {
0481     /*
0482      * Typical use cases
0483      */
0484     {
0485         .name = "typical IIO_VAL_INT, positive",
0486         .offset = 1234,
0487         .schan_scale_type = IIO_VAL_INT,
0488         .schan_val = 123,
0489         .schan_val2 = 0,
0490         .schan_off = 14,
0491         .expected_off = "24", /* 23.872 */
0492     },
0493     {
0494         .name = "typical IIO_VAL_INT, negative",
0495         .offset = -1234,
0496         .schan_scale_type = IIO_VAL_INT,
0497         .schan_val = 12,
0498         .schan_val2 = 0,
0499         .schan_off = 14,
0500         .expected_off = "-88", /* -88.83333333333333 */
0501     },
0502     {
0503         .name = "typical IIO_VAL_FRACTIONAL, positive",
0504         .offset = 1234,
0505         .schan_scale_type = IIO_VAL_FRACTIONAL,
0506         .schan_val = 12,
0507         .schan_val2 = 34,
0508         .schan_off = 14,
0509         .expected_off = "3510", /* 3510.333333333333 */
0510     },
0511     {
0512         .name = "typical IIO_VAL_FRACTIONAL, negative",
0513         .offset = -1234,
0514         .schan_scale_type = IIO_VAL_FRACTIONAL,
0515         .schan_val = 12,
0516         .schan_val2 = 34,
0517         .schan_off = 14,
0518         .expected_off = "-3482", /* -3482.333333333333 */
0519     },
0520     {
0521         .name = "typical IIO_VAL_FRACTIONAL_LOG2, positive",
0522         .offset = 1234,
0523         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0524         .schan_val = 12,
0525         .schan_val2 = 16,
0526         .schan_off = 14,
0527         .expected_off = "6739299", /* 6739299.333333333 */
0528     },
0529     {
0530         .name = "typical IIO_VAL_FRACTIONAL_LOG2, negative",
0531         .offset = -1234,
0532         .schan_scale_type = IIO_VAL_FRACTIONAL_LOG2,
0533         .schan_val = 12,
0534         .schan_val2 = 16,
0535         .schan_off = 14,
0536         .expected_off = "-6739271", /* -6739271.333333333 */
0537     },
0538     {
0539         .name = "typical IIO_VAL_INT_PLUS_NANO, positive",
0540         .offset = 1234,
0541         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0542         .schan_val = 10,
0543         .schan_val2 = 123456789,
0544         .schan_off = 14,
0545         .expected_off = "135", /* 135.8951219647469 */
0546     },
0547     {
0548         .name = "typical IIO_VAL_INT_PLUS_NANO, negative",
0549         .offset = -1234,
0550         .schan_scale_type = IIO_VAL_INT_PLUS_NANO,
0551         .schan_val = 10,
0552         .schan_val2 = 123456789,
0553         .schan_off = 14,
0554         .expected_off = "-107", /* -107.89512196474689 */
0555     },
0556     {
0557         .name = "typical IIO_VAL_INT_PLUS_MICRO, positive",
0558         .offset = 1234,
0559         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0560         .schan_val = 10,
0561         .schan_val2 = 123456789,
0562         .schan_off = 14,
0563         .expected_off = "23", /* 23.246438560723952 */
0564     },
0565     {
0566         .name = "typical IIO_VAL_INT_PLUS_MICRO, negative",
0567         .offset = -12345,
0568         .schan_scale_type = IIO_VAL_INT_PLUS_MICRO,
0569         .schan_val = 10,
0570         .schan_val2 = 123456789,
0571         .schan_off = 14,
0572         .expected_off = "-78", /* -78.50185091745313 */
0573     },
0574 };
0575 
0576 static void case_to_desc(const struct rescale_tc_data *t, char *desc)
0577 {
0578     strcpy(desc, t->name);
0579 }
0580 
0581 KUNIT_ARRAY_PARAM(iio_rescale_scale, scale_cases, case_to_desc);
0582 KUNIT_ARRAY_PARAM(iio_rescale_offset, offset_cases, case_to_desc);
0583 
0584 /**
0585  * iio_str_to_nano() - Parse a fixed-point string to get an
0586  *                      IIO_VAL_INT_PLUS_NANO value
0587  * @str: The string to parse
0588  * @nano: The number as an integer
0589  *
0590  * Returns 0 on success, or a negative error code if the string cound not be
0591  * parsed.
0592  */
0593 static int iio_str_to_nano(const char *str, s64 *nano)
0594 {
0595     int tmp, tmp2;
0596     int ret = 0;
0597 
0598     /*
0599      * iio_str_to_fixpoint() uses 10^8 here instead of 10^9 as fract_mult is
0600      * the multiplier for the first decimal place.
0601      */
0602     ret = iio_str_to_fixpoint(str, 100000000, &tmp, &tmp2);
0603     if (ret < 0)
0604         return ret;
0605 
0606     if (tmp < 0)
0607         tmp2 *= -1;
0608 
0609     *nano = (s64)tmp * 1000000000UL + tmp2;
0610 
0611     return ret;
0612 }
0613 
0614 /**
0615  * iio_test_relative_error_ppm() - Compute relative error (in parts-per-million)
0616  *                                 between two fixed-point strings
0617  * @real_str: The real value as a string
0618  * @exp_str: The expected value as a string
0619  *
0620  * Returns a negative error code if the strings cound not be parsed, or the
0621  * relative error in parts-per-million.
0622  */
0623 static int iio_test_relative_error_ppm(const char *real_str, const char *exp_str)
0624 {
0625     s64 real, exp, err;
0626     int ret;
0627 
0628     ret = iio_str_to_nano(real_str, &real);
0629     if (ret < 0)
0630         return ret;
0631 
0632     ret = iio_str_to_nano(exp_str, &exp);
0633     if (ret < 0)
0634         return ret;
0635 
0636     if (!exp) {
0637         pr_err("Expected value is null, relative error is undefined\n");
0638         return -EINVAL;
0639     }
0640 
0641     err = 1000000UL * abs(exp - real);
0642 
0643     return (int)div64_u64(err, abs(exp));
0644 }
0645 
0646 static void iio_rescale_test_scale(struct kunit *test)
0647 {
0648     struct rescale_tc_data *t = (struct rescale_tc_data *)test->param_value;
0649     char *buff = kunit_kmalloc(test, PAGE_SIZE, GFP_KERNEL);
0650     struct rescale rescale;
0651     int values[2];
0652     int rel_ppm;
0653     int ret;
0654 
0655     rescale.numerator = t->numerator;
0656     rescale.denominator = t->denominator;
0657     rescale.offset = t->offset;
0658     values[0] = t->schan_val;
0659     values[1] = t->schan_val2;
0660 
0661     ret = rescale_process_scale(&rescale, t->schan_scale_type,
0662                     &values[0], &values[1]);
0663 
0664     ret = iio_format_value(buff, ret, 2, values);
0665     KUNIT_EXPECT_EQ(test, (int)strlen(buff), ret);
0666 
0667     rel_ppm = iio_test_relative_error_ppm(buff, t->expected);
0668     KUNIT_EXPECT_GE_MSG(test, rel_ppm, 0, "failed to compute ppm\n");
0669 
0670     KUNIT_EXPECT_EQ_MSG(test, rel_ppm, 0,
0671                 "\t    real=%s"
0672                 "\texpected=%s\n",
0673                 buff, t->expected);
0674 }
0675 
0676 static void iio_rescale_test_offset(struct kunit *test)
0677 {
0678     struct rescale_tc_data *t = (struct rescale_tc_data *)test->param_value;
0679     char *buff_off = kunit_kmalloc(test, PAGE_SIZE, GFP_KERNEL);
0680     struct rescale rescale;
0681     int values[2];
0682     int ret;
0683 
0684     rescale.numerator = t->numerator;
0685     rescale.denominator = t->denominator;
0686     rescale.offset = t->offset;
0687     values[0] = t->schan_val;
0688     values[1] = t->schan_val2;
0689 
0690     ret = rescale_process_offset(&rescale, t->schan_scale_type,
0691                      t->schan_val, t->schan_val2, t->schan_off,
0692                      &values[0], &values[1]);
0693 
0694     ret = iio_format_value(buff_off, ret, 2, values);
0695     KUNIT_EXPECT_EQ(test, (int)strlen(buff_off), ret);
0696 
0697     KUNIT_EXPECT_STREQ(test, strim(buff_off), t->expected_off);
0698 }
0699 
0700 static struct kunit_case iio_rescale_test_cases[] = {
0701     KUNIT_CASE_PARAM(iio_rescale_test_scale, iio_rescale_scale_gen_params),
0702     KUNIT_CASE_PARAM(iio_rescale_test_offset, iio_rescale_offset_gen_params),
0703     {}
0704 };
0705 
0706 static struct kunit_suite iio_rescale_test_suite = {
0707     .name = "iio-rescale",
0708     .test_cases = iio_rescale_test_cases,
0709 };
0710 kunit_test_suite(iio_rescale_test_suite);
0711 
0712 MODULE_AUTHOR("Liam Beguin <liambeguin@gmail.com>");
0713 MODULE_DESCRIPTION("Test IIO rescale conversion functions");
0714 MODULE_LICENSE("GPL v2");
0715 MODULE_IMPORT_NS(IIO_RESCALE);