1cf996f03SMatti Vaittinen // SPDX-License-Identifier: GPL-2.0-only
2cf996f03SMatti Vaittinen /* Unit tests for IIO light sensor gain-time-scale helpers
3cf996f03SMatti Vaittinen *
4cf996f03SMatti Vaittinen * Copyright (c) 2023 Matti Vaittinen <mazziesaccount@gmail.com>
5cf996f03SMatti Vaittinen */
6cf996f03SMatti Vaittinen
7cf996f03SMatti Vaittinen #include <kunit/device.h>
8cf996f03SMatti Vaittinen #include <kunit/test.h>
9cf996f03SMatti Vaittinen #include <linux/device.h>
10cf996f03SMatti Vaittinen #include <linux/iio/iio-gts-helper.h>
11cf996f03SMatti Vaittinen #include <linux/iio/types.h>
12cf996f03SMatti Vaittinen
13cf996f03SMatti Vaittinen /*
14cf996f03SMatti Vaittinen * Please, read the "rant" from the top of the lib/test_linear_ranges.c if
15cf996f03SMatti Vaittinen * you see a line of helper code which is not being tested.
16cf996f03SMatti Vaittinen *
17cf996f03SMatti Vaittinen * Then, please look at the line which is not being tested. Is this line
18cf996f03SMatti Vaittinen * somehow unusually complex? If answer is "no", then chances are that the
19cf996f03SMatti Vaittinen * "development inertia" caused by adding a test exceeds the benefits.
20cf996f03SMatti Vaittinen *
21cf996f03SMatti Vaittinen * If yes, then adding a test is probably a good idea but please stop for a
22cf996f03SMatti Vaittinen * moment and consider the effort of changing all the tests when code gets
23cf996f03SMatti Vaittinen * refactored. Eventually it neeeds to be.
24cf996f03SMatti Vaittinen */
25cf996f03SMatti Vaittinen
26cf996f03SMatti Vaittinen #define TEST_TSEL_50 1
27cf996f03SMatti Vaittinen #define TEST_TSEL_X_MIN TEST_TSEL_50
28cf996f03SMatti Vaittinen #define TEST_TSEL_100 0
29cf996f03SMatti Vaittinen #define TEST_TSEL_200 2
30cf996f03SMatti Vaittinen #define TEST_TSEL_400 4
31cf996f03SMatti Vaittinen #define TEST_TSEL_X_MAX TEST_TSEL_400
32cf996f03SMatti Vaittinen
33cf996f03SMatti Vaittinen #define TEST_GSEL_1 0x00
34cf996f03SMatti Vaittinen #define TEST_GSEL_X_MIN TEST_GSEL_1
35cf996f03SMatti Vaittinen #define TEST_GSEL_4 0x08
36cf996f03SMatti Vaittinen #define TEST_GSEL_16 0x0a
37cf996f03SMatti Vaittinen #define TEST_GSEL_32 0x0b
38cf996f03SMatti Vaittinen #define TEST_GSEL_64 0x0c
39cf996f03SMatti Vaittinen #define TEST_GSEL_256 0x18
40cf996f03SMatti Vaittinen #define TEST_GSEL_512 0x19
41cf996f03SMatti Vaittinen #define TEST_GSEL_1024 0x1a
42cf996f03SMatti Vaittinen #define TEST_GSEL_2048 0x1b
43cf996f03SMatti Vaittinen #define TEST_GSEL_4096 0x1c
44cf996f03SMatti Vaittinen #define TEST_GSEL_X_MAX TEST_GSEL_4096
45cf996f03SMatti Vaittinen
46cf996f03SMatti Vaittinen #define TEST_SCALE_1X 64
47cf996f03SMatti Vaittinen #define TEST_SCALE_MIN_X TEST_SCALE_1X
48cf996f03SMatti Vaittinen #define TEST_SCALE_2X 32
49cf996f03SMatti Vaittinen #define TEST_SCALE_4X 16
50cf996f03SMatti Vaittinen #define TEST_SCALE_8X 8
51cf996f03SMatti Vaittinen #define TEST_SCALE_16X 4
52cf996f03SMatti Vaittinen #define TEST_SCALE_32X 2
53cf996f03SMatti Vaittinen #define TEST_SCALE_64X 1
54cf996f03SMatti Vaittinen
55cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_128X 500000000
56cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_256X 250000000
57cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_512X 125000000
58cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_1024X 62500000
59cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_2048X 31250000
60cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_4096X 15625000
61cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_4096X2 7812500
62cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_4096X4 3906250
63cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_4096X8 1953125
64cf996f03SMatti Vaittinen
65cf996f03SMatti Vaittinen #define TEST_SCALE_NANO_MAX_X TEST_SCALE_NANO_4096X8
66cf996f03SMatti Vaittinen
67cf996f03SMatti Vaittinen /*
68cf996f03SMatti Vaittinen * Can't have this allocated from stack because the kunit clean-up will
69cf996f03SMatti Vaittinen * happen only after the test function has already gone
70cf996f03SMatti Vaittinen */
71cf996f03SMatti Vaittinen static struct iio_gts gts;
72cf996f03SMatti Vaittinen
73*6de2f3a1SMatti Vaittinen /* Keep the gain and time tables unsorted to test the sorting */
74cf996f03SMatti Vaittinen static const struct iio_gain_sel_pair gts_test_gains[] = {
75cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(1, TEST_GSEL_1),
76cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(4, TEST_GSEL_4),
77cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(16, TEST_GSEL_16),
78cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(32, TEST_GSEL_32),
79cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(64, TEST_GSEL_64),
80cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(256, TEST_GSEL_256),
81cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(512, TEST_GSEL_512),
82cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(1024, TEST_GSEL_1024),
83cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(4096, TEST_GSEL_4096),
84*6de2f3a1SMatti Vaittinen GAIN_SCALE_GAIN(2048, TEST_GSEL_2048),
85cf996f03SMatti Vaittinen #define HWGAIN_MAX 4096
86cf996f03SMatti Vaittinen };
87cf996f03SMatti Vaittinen
88cf996f03SMatti Vaittinen static const struct iio_itime_sel_mul gts_test_itimes[] = {
89cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(100 * 1000, TEST_TSEL_100, 2),
90*6de2f3a1SMatti Vaittinen GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 8),
91*6de2f3a1SMatti Vaittinen GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 8),
92cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(50 * 1000, TEST_TSEL_50, 1),
93*6de2f3a1SMatti Vaittinen GAIN_SCALE_ITIME_US(200 * 1000, TEST_TSEL_200, 4),
94cf996f03SMatti Vaittinen #define TIMEGAIN_MAX 8
95cf996f03SMatti Vaittinen };
96cf996f03SMatti Vaittinen #define TOTAL_GAIN_MAX (HWGAIN_MAX * TIMEGAIN_MAX)
97cf996f03SMatti Vaittinen #define IIO_GTS_TEST_DEV "iio-gts-test-dev"
98cf996f03SMatti Vaittinen
__test_init_iio_gain_scale(struct kunit * test,struct iio_gts * gts,const struct iio_gain_sel_pair * g_table,int num_g,const struct iio_itime_sel_mul * i_table,int num_i)99cf996f03SMatti Vaittinen static struct device *__test_init_iio_gain_scale(struct kunit *test,
100cf996f03SMatti Vaittinen struct iio_gts *gts, const struct iio_gain_sel_pair *g_table,
101cf996f03SMatti Vaittinen int num_g, const struct iio_itime_sel_mul *i_table, int num_i)
102cf996f03SMatti Vaittinen {
103cf996f03SMatti Vaittinen struct device *dev;
104cf996f03SMatti Vaittinen int ret;
105cf996f03SMatti Vaittinen
106cf996f03SMatti Vaittinen dev = kunit_device_register(test, IIO_GTS_TEST_DEV);
107cf996f03SMatti Vaittinen
108cf996f03SMatti Vaittinen KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev);
109cf996f03SMatti Vaittinen if (IS_ERR_OR_NULL(dev))
110cf996f03SMatti Vaittinen return NULL;
111cf996f03SMatti Vaittinen
112cf996f03SMatti Vaittinen ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, g_table, num_g,
113cf996f03SMatti Vaittinen i_table, num_i, gts);
114cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
115cf996f03SMatti Vaittinen if (ret)
116cf996f03SMatti Vaittinen return NULL;
117cf996f03SMatti Vaittinen
118cf996f03SMatti Vaittinen return dev;
119cf996f03SMatti Vaittinen }
120cf996f03SMatti Vaittinen
121cf996f03SMatti Vaittinen #define test_init_iio_gain_scale(test, gts) \
122cf996f03SMatti Vaittinen __test_init_iio_gain_scale(test, gts, gts_test_gains, \
123cf996f03SMatti Vaittinen ARRAY_SIZE(gts_test_gains), gts_test_itimes, \
124cf996f03SMatti Vaittinen ARRAY_SIZE(gts_test_itimes))
125cf996f03SMatti Vaittinen
test_init_iio_gts_invalid(struct kunit * test)126cf996f03SMatti Vaittinen static void test_init_iio_gts_invalid(struct kunit *test)
127cf996f03SMatti Vaittinen {
128cf996f03SMatti Vaittinen struct device *dev;
129cf996f03SMatti Vaittinen int ret;
130cf996f03SMatti Vaittinen const struct iio_itime_sel_mul itimes_neg[] = {
131cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(-10, TEST_TSEL_400, 8),
132cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(200 * 1000, TEST_TSEL_200, 4),
133cf996f03SMatti Vaittinen };
134cf996f03SMatti Vaittinen const struct iio_gain_sel_pair gains_neg[] = {
135cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(1, TEST_GSEL_1),
136cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(2, TEST_GSEL_4),
137cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(-2, TEST_GSEL_16),
138cf996f03SMatti Vaittinen };
139cf996f03SMatti Vaittinen /* 55555 * 38656 = 2147534080 => overflows 32bit int */
140cf996f03SMatti Vaittinen const struct iio_itime_sel_mul itimes_overflow[] = {
141cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(400 * 1000, TEST_TSEL_400, 55555),
142cf996f03SMatti Vaittinen GAIN_SCALE_ITIME_US(200 * 1000, TEST_TSEL_200, 4),
143cf996f03SMatti Vaittinen };
144cf996f03SMatti Vaittinen const struct iio_gain_sel_pair gains_overflow[] = {
145cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(1, TEST_GSEL_1),
146cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(2, TEST_GSEL_4),
147cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(38656, TEST_GSEL_16),
148cf996f03SMatti Vaittinen };
149cf996f03SMatti Vaittinen
150cf996f03SMatti Vaittinen dev = kunit_device_register(test, IIO_GTS_TEST_DEV);
151cf996f03SMatti Vaittinen KUNIT_EXPECT_NOT_ERR_OR_NULL(test, dev);
152cf996f03SMatti Vaittinen if (!dev)
153cf996f03SMatti Vaittinen return;
154cf996f03SMatti Vaittinen
155cf996f03SMatti Vaittinen /* Ok gains, negative time */
156cf996f03SMatti Vaittinen ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, gts_test_gains,
157cf996f03SMatti Vaittinen ARRAY_SIZE(gts_test_gains), itimes_neg,
158cf996f03SMatti Vaittinen ARRAY_SIZE(itimes_neg), >s);
159cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, -EINVAL, ret);
160cf996f03SMatti Vaittinen
161cf996f03SMatti Vaittinen /* Ok times, negative gain */
162cf996f03SMatti Vaittinen ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, gains_neg,
163cf996f03SMatti Vaittinen ARRAY_SIZE(gains_neg), gts_test_itimes,
164cf996f03SMatti Vaittinen ARRAY_SIZE(gts_test_itimes), >s);
165cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, -EINVAL, ret);
166cf996f03SMatti Vaittinen
167cf996f03SMatti Vaittinen /* gain * time overflow int */
168cf996f03SMatti Vaittinen ret = devm_iio_init_iio_gts(dev, TEST_SCALE_1X, 0, gains_overflow,
169cf996f03SMatti Vaittinen ARRAY_SIZE(gains_overflow), itimes_overflow,
170cf996f03SMatti Vaittinen ARRAY_SIZE(itimes_overflow), >s);
171cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, -EOVERFLOW, ret);
172cf996f03SMatti Vaittinen }
173cf996f03SMatti Vaittinen
test_iio_gts_find_gain_for_scale_using_time(struct kunit * test)174cf996f03SMatti Vaittinen static void test_iio_gts_find_gain_for_scale_using_time(struct kunit *test)
175cf996f03SMatti Vaittinen {
176cf996f03SMatti Vaittinen struct device *dev;
177cf996f03SMatti Vaittinen int ret, gain_sel;
178cf996f03SMatti Vaittinen
179cf996f03SMatti Vaittinen dev = test_init_iio_gain_scale(test, >s);
180cf996f03SMatti Vaittinen if (!dev)
181cf996f03SMatti Vaittinen return;
182cf996f03SMatti Vaittinen
183cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_100,
184cf996f03SMatti Vaittinen TEST_SCALE_8X, 0, &gain_sel);
185cf996f03SMatti Vaittinen /*
186cf996f03SMatti Vaittinen * Meas time 100 => gain by time 2x
187cf996f03SMatti Vaittinen * TEST_SCALE_8X matches total gain 8x
188cf996f03SMatti Vaittinen * => required HWGAIN 4x
189cf996f03SMatti Vaittinen */
190cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
191cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_GSEL_4, gain_sel);
192cf996f03SMatti Vaittinen
193cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_200, 0,
194cf996f03SMatti Vaittinen TEST_SCALE_NANO_256X, &gain_sel);
195cf996f03SMatti Vaittinen /*
196cf996f03SMatti Vaittinen * Meas time 200 => gain by time 4x
197cf996f03SMatti Vaittinen * TEST_SCALE_256X matches total gain 256x
198cf996f03SMatti Vaittinen * => required HWGAIN 256/4 => 64x
199cf996f03SMatti Vaittinen */
200cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
201cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_GSEL_64, gain_sel);
202cf996f03SMatti Vaittinen
203cf996f03SMatti Vaittinen /* Min time, Min gain */
204cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_X_MIN,
205cf996f03SMatti Vaittinen TEST_SCALE_MIN_X, 0, &gain_sel);
206cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
207cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_GSEL_1, gain_sel);
208cf996f03SMatti Vaittinen
209cf996f03SMatti Vaittinen /* Max time, Max gain */
210cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_X_MAX,
211cf996f03SMatti Vaittinen 0, TEST_SCALE_NANO_MAX_X, &gain_sel);
212cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
213cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_GSEL_4096, gain_sel);
214cf996f03SMatti Vaittinen
215cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_100, 0,
216cf996f03SMatti Vaittinen TEST_SCALE_NANO_256X, &gain_sel);
217cf996f03SMatti Vaittinen /*
218cf996f03SMatti Vaittinen * Meas time 100 => gain by time 2x
219cf996f03SMatti Vaittinen * TEST_SCALE_256X matches total gain 256x
220cf996f03SMatti Vaittinen * => required HWGAIN 256/2 => 128x (not in gain-table - unsupported)
221cf996f03SMatti Vaittinen */
222cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
223cf996f03SMatti Vaittinen
224cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_200, 0,
225cf996f03SMatti Vaittinen TEST_SCALE_NANO_MAX_X, &gain_sel);
226cf996f03SMatti Vaittinen /* We can't reach the max gain with integration time smaller than MAX */
227cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
228cf996f03SMatti Vaittinen
229cf996f03SMatti Vaittinen ret = iio_gts_find_gain_sel_for_scale_using_time(>s, TEST_TSEL_50, 0,
230cf996f03SMatti Vaittinen TEST_SCALE_NANO_MAX_X, &gain_sel);
231cf996f03SMatti Vaittinen /* We can't reach the max gain with integration time smaller than MAX */
232cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
233cf996f03SMatti Vaittinen }
234cf996f03SMatti Vaittinen
test_iio_gts_find_new_gain_sel_by_old_gain_time(struct kunit * test)235cf996f03SMatti Vaittinen static void test_iio_gts_find_new_gain_sel_by_old_gain_time(struct kunit *test)
236cf996f03SMatti Vaittinen {
237cf996f03SMatti Vaittinen struct device *dev;
238cf996f03SMatti Vaittinen int ret, old_gain, new_gain, old_time_sel, new_time_sel;
239cf996f03SMatti Vaittinen
240cf996f03SMatti Vaittinen dev = test_init_iio_gain_scale(test, >s);
241cf996f03SMatti Vaittinen if (!dev)
242cf996f03SMatti Vaittinen return;
243cf996f03SMatti Vaittinen
244cf996f03SMatti Vaittinen old_gain = 32;
245cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_200;
246cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_400;
247cf996f03SMatti Vaittinen
248cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
249cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
250cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
251cf996f03SMatti Vaittinen /*
252cf996f03SMatti Vaittinen * Doubling the integration time doubles the total gain - so old
253cf996f03SMatti Vaittinen * (hw)gain must be divided by two to compensate. => 32 / 2 => 16
254cf996f03SMatti Vaittinen */
255cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 16, new_gain);
256cf996f03SMatti Vaittinen
257cf996f03SMatti Vaittinen old_gain = 4;
258cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_50;
259cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_200;
260cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
261cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
262cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
263cf996f03SMatti Vaittinen /*
264cf996f03SMatti Vaittinen * gain by time 1x => 4x - (hw)gain 4x => 1x
265cf996f03SMatti Vaittinen */
266cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 1, new_gain);
267cf996f03SMatti Vaittinen
268cf996f03SMatti Vaittinen old_gain = 512;
269cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_400;
270cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_50;
271cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
272cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
273cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
274cf996f03SMatti Vaittinen /*
275cf996f03SMatti Vaittinen * gain by time 8x => 1x - (hw)gain 512x => 4096x)
276cf996f03SMatti Vaittinen */
277cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 4096, new_gain);
278cf996f03SMatti Vaittinen
279cf996f03SMatti Vaittinen /* Unsupported gain 2x */
280cf996f03SMatti Vaittinen old_gain = 4;
281cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_200;
282cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_400;
283cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
284cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
285cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
286cf996f03SMatti Vaittinen
287cf996f03SMatti Vaittinen /* Too small gain */
288cf996f03SMatti Vaittinen old_gain = 4;
289cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_50;
290cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_400;
291cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
292cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
293cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
294cf996f03SMatti Vaittinen
295cf996f03SMatti Vaittinen /* Too big gain */
296cf996f03SMatti Vaittinen old_gain = 1024;
297cf996f03SMatti Vaittinen old_time_sel = TEST_TSEL_400;
298cf996f03SMatti Vaittinen new_time_sel = TEST_TSEL_50;
299cf996f03SMatti Vaittinen ret = iio_gts_find_new_gain_sel_by_old_gain_time(>s, old_gain,
300cf996f03SMatti Vaittinen old_time_sel, new_time_sel, &new_gain);
301cf996f03SMatti Vaittinen KUNIT_EXPECT_NE(test, 0, ret);
302cf996f03SMatti Vaittinen
303cf996f03SMatti Vaittinen }
304cf996f03SMatti Vaittinen
test_iio_find_closest_gain_low(struct kunit * test)305cf996f03SMatti Vaittinen static void test_iio_find_closest_gain_low(struct kunit *test)
306cf996f03SMatti Vaittinen {
307cf996f03SMatti Vaittinen struct device *dev;
308cf996f03SMatti Vaittinen bool in_range;
309cf996f03SMatti Vaittinen int ret;
310cf996f03SMatti Vaittinen
311cf996f03SMatti Vaittinen const struct iio_gain_sel_pair gts_test_gains_gain_low[] = {
312cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(4, TEST_GSEL_4),
313cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(16, TEST_GSEL_16),
314cf996f03SMatti Vaittinen GAIN_SCALE_GAIN(32, TEST_GSEL_32),
315cf996f03SMatti Vaittinen };
316cf996f03SMatti Vaittinen
317cf996f03SMatti Vaittinen dev = test_init_iio_gain_scale(test, >s);
318cf996f03SMatti Vaittinen if (!dev)
319cf996f03SMatti Vaittinen return;
320cf996f03SMatti Vaittinen
321cf996f03SMatti Vaittinen ret = iio_find_closest_gain_low(>s, 2, &in_range);
322cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 1, ret);
323cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, true, in_range);
324cf996f03SMatti Vaittinen
325cf996f03SMatti Vaittinen ret = iio_find_closest_gain_low(>s, 1, &in_range);
326cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 1, ret);
327cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, true, in_range);
328cf996f03SMatti Vaittinen
329cf996f03SMatti Vaittinen ret = iio_find_closest_gain_low(>s, 4095, &in_range);
330cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 2048, ret);
331cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, true, in_range);
332cf996f03SMatti Vaittinen
333cf996f03SMatti Vaittinen ret = iio_find_closest_gain_low(>s, 4097, &in_range);
334cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 4096, ret);
335cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, false, in_range);
336cf996f03SMatti Vaittinen
337cf996f03SMatti Vaittinen kunit_device_unregister(test, dev);
338cf996f03SMatti Vaittinen
339cf996f03SMatti Vaittinen dev = __test_init_iio_gain_scale(test, >s, gts_test_gains_gain_low,
340cf996f03SMatti Vaittinen ARRAY_SIZE(gts_test_gains_gain_low),
341cf996f03SMatti Vaittinen gts_test_itimes, ARRAY_SIZE(gts_test_itimes));
342cf996f03SMatti Vaittinen if (!dev)
343cf996f03SMatti Vaittinen return;
344cf996f03SMatti Vaittinen
345cf996f03SMatti Vaittinen ret = iio_find_closest_gain_low(>s, 3, &in_range);
346cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, -EINVAL, ret);
347cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, false, in_range);
348cf996f03SMatti Vaittinen }
349cf996f03SMatti Vaittinen
test_iio_gts_total_gain_to_scale(struct kunit * test)350cf996f03SMatti Vaittinen static void test_iio_gts_total_gain_to_scale(struct kunit *test)
351cf996f03SMatti Vaittinen {
352cf996f03SMatti Vaittinen struct device *dev;
353cf996f03SMatti Vaittinen int ret, scale_int, scale_nano;
354cf996f03SMatti Vaittinen
355cf996f03SMatti Vaittinen dev = test_init_iio_gain_scale(test, >s);
356cf996f03SMatti Vaittinen if (!dev)
357cf996f03SMatti Vaittinen return;
358cf996f03SMatti Vaittinen
359cf996f03SMatti Vaittinen ret = iio_gts_total_gain_to_scale(>s, 1, &scale_int, &scale_nano);
360cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
361cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_SCALE_1X, scale_int);
362cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, scale_nano);
363cf996f03SMatti Vaittinen
364cf996f03SMatti Vaittinen ret = iio_gts_total_gain_to_scale(>s, 1, &scale_int, &scale_nano);
365cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
366cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_SCALE_1X, scale_int);
367cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, scale_nano);
368cf996f03SMatti Vaittinen
369cf996f03SMatti Vaittinen ret = iio_gts_total_gain_to_scale(>s, 4096 * 8, &scale_int,
370cf996f03SMatti Vaittinen &scale_nano);
371cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
372cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, scale_int);
373cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, TEST_SCALE_NANO_4096X8, scale_nano);
374cf996f03SMatti Vaittinen }
375cf996f03SMatti Vaittinen
test_iio_gts_chk_times(struct kunit * test,const int * vals)376cf996f03SMatti Vaittinen static void test_iio_gts_chk_times(struct kunit *test, const int *vals)
377cf996f03SMatti Vaittinen {
378cf996f03SMatti Vaittinen static const int expected[] = {0, 50000, 0, 100000, 0, 200000, 0, 400000};
379cf996f03SMatti Vaittinen int i;
380cf996f03SMatti Vaittinen
381cf996f03SMatti Vaittinen for (i = 0; i < ARRAY_SIZE(expected); i++)
382cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, expected[i], vals[i]);
383cf996f03SMatti Vaittinen }
384cf996f03SMatti Vaittinen
test_iio_gts_chk_scales_all(struct kunit * test,struct iio_gts * gts,const int * vals,int len)385cf996f03SMatti Vaittinen static void test_iio_gts_chk_scales_all(struct kunit *test, struct iio_gts *gts,
386cf996f03SMatti Vaittinen const int *vals, int len)
387cf996f03SMatti Vaittinen {
388cf996f03SMatti Vaittinen static const int gains[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
389cf996f03SMatti Vaittinen 1024, 2048, 4096, 4096 * 2, 4096 * 4,
390cf996f03SMatti Vaittinen 4096 * 8};
391cf996f03SMatti Vaittinen int expected[ARRAY_SIZE(gains) * 2];
392cf996f03SMatti Vaittinen int i, ret;
393cf996f03SMatti Vaittinen int exp_len = ARRAY_SIZE(gains) * 2;
394cf996f03SMatti Vaittinen
395cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, exp_len, len);
396cf996f03SMatti Vaittinen if (len != exp_len)
397cf996f03SMatti Vaittinen return;
398cf996f03SMatti Vaittinen
399cf996f03SMatti Vaittinen for (i = 0; i < ARRAY_SIZE(gains); i++) {
400cf996f03SMatti Vaittinen ret = iio_gts_total_gain_to_scale(gts, gains[i],
401cf996f03SMatti Vaittinen &expected[2 * i],
402cf996f03SMatti Vaittinen &expected[2 * i + 1]);
403cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
404cf996f03SMatti Vaittinen if (ret)
405cf996f03SMatti Vaittinen return;
406cf996f03SMatti Vaittinen }
407cf996f03SMatti Vaittinen
408cf996f03SMatti Vaittinen for (i = 0; i < ARRAY_SIZE(expected); i++)
409cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, expected[i], vals[i]);
410cf996f03SMatti Vaittinen }
411cf996f03SMatti Vaittinen
test_iio_gts_chk_scales_t200(struct kunit * test,struct iio_gts * gts,const int * vals,int len)412cf996f03SMatti Vaittinen static void test_iio_gts_chk_scales_t200(struct kunit *test, struct iio_gts *gts,
413cf996f03SMatti Vaittinen const int *vals, int len)
414cf996f03SMatti Vaittinen {
415cf996f03SMatti Vaittinen /* The gain caused by time 200 is 4x */
416cf996f03SMatti Vaittinen static const int gains[] = {
417cf996f03SMatti Vaittinen 1 * 4,
418cf996f03SMatti Vaittinen 4 * 4,
419cf996f03SMatti Vaittinen 16 * 4,
420cf996f03SMatti Vaittinen 32 * 4,
421cf996f03SMatti Vaittinen 64 * 4,
422cf996f03SMatti Vaittinen 256 * 4,
423cf996f03SMatti Vaittinen 512 * 4,
424cf996f03SMatti Vaittinen 1024 * 4,
425cf996f03SMatti Vaittinen 2048 * 4,
426cf996f03SMatti Vaittinen 4096 * 4
427cf996f03SMatti Vaittinen };
428cf996f03SMatti Vaittinen int expected[ARRAY_SIZE(gains) * 2];
429cf996f03SMatti Vaittinen int i, ret;
430cf996f03SMatti Vaittinen
431cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 2 * ARRAY_SIZE(gains), len);
432cf996f03SMatti Vaittinen if (len < 2 * ARRAY_SIZE(gains))
433cf996f03SMatti Vaittinen return;
434cf996f03SMatti Vaittinen
435cf996f03SMatti Vaittinen for (i = 0; i < ARRAY_SIZE(gains); i++) {
436cf996f03SMatti Vaittinen ret = iio_gts_total_gain_to_scale(gts, gains[i],
437cf996f03SMatti Vaittinen &expected[2 * i],
438cf996f03SMatti Vaittinen &expected[2 * i + 1]);
439cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 0, ret);
440cf996f03SMatti Vaittinen if (ret)
441cf996f03SMatti Vaittinen return;
442cf996f03SMatti Vaittinen }
443cf996f03SMatti Vaittinen
444cf996f03SMatti Vaittinen for (i = 0; i < ARRAY_SIZE(expected); i++)
445cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, expected[i], vals[i]);
446cf996f03SMatti Vaittinen }
447cf996f03SMatti Vaittinen
test_iio_gts_avail_test(struct kunit * test)448cf996f03SMatti Vaittinen static void test_iio_gts_avail_test(struct kunit *test)
449cf996f03SMatti Vaittinen {
450cf996f03SMatti Vaittinen struct device *dev;
451cf996f03SMatti Vaittinen int ret;
452cf996f03SMatti Vaittinen int type, len;
453cf996f03SMatti Vaittinen const int *vals;
454cf996f03SMatti Vaittinen
455cf996f03SMatti Vaittinen dev = test_init_iio_gain_scale(test, >s);
456cf996f03SMatti Vaittinen if (!dev)
457cf996f03SMatti Vaittinen return;
458cf996f03SMatti Vaittinen
459cf996f03SMatti Vaittinen /* test table building for times and iio_gts_avail_times() */
460cf996f03SMatti Vaittinen ret = iio_gts_avail_times(>s, &vals, &type, &len);
461cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_AVAIL_LIST, ret);
462cf996f03SMatti Vaittinen if (ret)
463cf996f03SMatti Vaittinen return;
464cf996f03SMatti Vaittinen
465cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_VAL_INT_PLUS_MICRO, type);
466cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, 8, len);
467cf996f03SMatti Vaittinen if (len < 8)
468cf996f03SMatti Vaittinen return;
469cf996f03SMatti Vaittinen
470cf996f03SMatti Vaittinen test_iio_gts_chk_times(test, vals);
471cf996f03SMatti Vaittinen
472cf996f03SMatti Vaittinen /* Test table building for all scales and iio_gts_all_avail_scales() */
473cf996f03SMatti Vaittinen ret = iio_gts_all_avail_scales(>s, &vals, &type, &len);
474cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_AVAIL_LIST, ret);
475cf996f03SMatti Vaittinen if (ret)
476cf996f03SMatti Vaittinen return;
477cf996f03SMatti Vaittinen
478cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_VAL_INT_PLUS_NANO, type);
479cf996f03SMatti Vaittinen
480cf996f03SMatti Vaittinen test_iio_gts_chk_scales_all(test, >s, vals, len);
481cf996f03SMatti Vaittinen
482cf996f03SMatti Vaittinen /*
483cf996f03SMatti Vaittinen * Test table building for scales/time and
484cf996f03SMatti Vaittinen * iio_gts_avail_scales_for_time()
485cf996f03SMatti Vaittinen */
486cf996f03SMatti Vaittinen ret = iio_gts_avail_scales_for_time(>s, 200000, &vals, &type, &len);
487cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_AVAIL_LIST, ret);
488cf996f03SMatti Vaittinen if (ret)
489cf996f03SMatti Vaittinen return;
490cf996f03SMatti Vaittinen
491cf996f03SMatti Vaittinen KUNIT_EXPECT_EQ(test, IIO_VAL_INT_PLUS_NANO, type);
492cf996f03SMatti Vaittinen test_iio_gts_chk_scales_t200(test, >s, vals, len);
493cf996f03SMatti Vaittinen }
494cf996f03SMatti Vaittinen
495cf996f03SMatti Vaittinen static struct kunit_case iio_gts_test_cases[] = {
496cf996f03SMatti Vaittinen KUNIT_CASE(test_init_iio_gts_invalid),
497cf996f03SMatti Vaittinen KUNIT_CASE(test_iio_gts_find_gain_for_scale_using_time),
498cf996f03SMatti Vaittinen KUNIT_CASE(test_iio_gts_find_new_gain_sel_by_old_gain_time),
499cf996f03SMatti Vaittinen KUNIT_CASE(test_iio_find_closest_gain_low),
500cf996f03SMatti Vaittinen KUNIT_CASE(test_iio_gts_total_gain_to_scale),
501cf996f03SMatti Vaittinen KUNIT_CASE(test_iio_gts_avail_test),
502cf996f03SMatti Vaittinen {}
503cf996f03SMatti Vaittinen };
504cf996f03SMatti Vaittinen
505cf996f03SMatti Vaittinen static struct kunit_suite iio_gts_test_suite = {
506cf996f03SMatti Vaittinen .name = "iio-gain-time-scale",
507cf996f03SMatti Vaittinen .test_cases = iio_gts_test_cases,
508cf996f03SMatti Vaittinen };
509cf996f03SMatti Vaittinen
510cf996f03SMatti Vaittinen kunit_test_suite(iio_gts_test_suite);
511cf996f03SMatti Vaittinen
512cf996f03SMatti Vaittinen MODULE_LICENSE("GPL");
513cf996f03SMatti Vaittinen MODULE_AUTHOR("Matti Vaittinen <mazziesaccount@gmail.com>");
514cf996f03SMatti Vaittinen MODULE_DESCRIPTION("Test IIO light sensor gain-time-scale helpers");
515cf996f03SMatti Vaittinen MODULE_IMPORT_NS(IIO_GTS_HELPER);
516