blob: 9303456261527e6c6bd1e8bbc45b86fd281016fd [file] [log] [blame]
Jan Dabrosb0800d32020-05-06 16:01:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Jan Dabrosa67cc5f2020-04-20 14:34:16 +02002
3#include <stdarg.h>
4#include <stddef.h>
5#include <setjmp.h>
6#include <limits.h>
7#include <cmocka.h>
8
9#include <device/i2c_simple.h>
10
11/* Simulate two i2c devices, both on bus 0, each with three uint8_t regs
12 implemented. */
13typedef struct {
14 uint8_t reg;
15 uint8_t data;
16} i2c_ex_regs_t;
17
18typedef struct {
19 unsigned int bus;
20 uint8_t slave;
21 i2c_ex_regs_t regs[3];
22} i2c_ex_devs_t;
23
24i2c_ex_devs_t i2c_ex_devs[] = {
25 {.bus = 0, .slave = 0xA, .regs = {
26 {.reg = 0x0, .data = 0xB},
27 {.reg = 0x1, .data = 0x6},
28 {.reg = 0x2, .data = 0xF},
29 } },
30 {.bus = 0, .slave = 0x3, .regs = {
31 {.reg = 0x0, .data = 0xDE},
32 {.reg = 0x1, .data = 0xAD},
33 {.reg = 0x2, .data = 0xBE},
34 } },
35};
36
37int __wrap_platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
38 int count)
39{
40 int i;
41 int reg;
42 struct i2c_msg *tmp = segments;
43 i2c_ex_devs_t *i2c_dev = NULL;
44
45 check_expected(count);
46
47 for (i = 0; i < count; i++, segments++) {
48 check_expected_ptr(segments->buf);
49 check_expected(segments->flags);
50 }
51
52 reg = tmp->buf[0];
53
54 /* Find object for requested device */
55 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++, i2c_dev++)
56 if (i2c_ex_devs[i].slave == tmp->slave) {
57 i2c_dev = &i2c_ex_devs[i];
58 break;
59 }
60
61 if (i2c_dev == NULL)
62 return -1;
63
64 /* Write commands */
65 if (tmp->len > 1) {
66 i2c_dev->regs[reg].data = tmp->buf[1];
67 };
68
69 /* Read commands */
70 for (i = 0; i < count; i++, tmp++)
71 if (tmp->flags & I2C_M_RD) {
72 *(tmp->buf) = i2c_dev->regs[reg].data;
73 };
74}
75
76static void mock_expect_params_platform_i2c_transfer(void)
77{
78 unsigned long int expected_flags[] = {0, I2C_M_RD, I2C_M_TEN,
79 I2C_M_RECV_LEN, I2C_M_NOSTART};
80
81 /* Flags should always be only within supported range */
82 expect_in_set_count(__wrap_platform_i2c_transfer, segments->flags,
83 expected_flags, -1);
84
85 expect_not_value_count(__wrap_platform_i2c_transfer, segments->buf,
86 NULL, -1);
87
88 expect_in_range_count(__wrap_platform_i2c_transfer, count, 1, INT_MAX,
89 -1);
90}
91
92#define MASK 0x3
93#define SHIFT 0x1
94
95static void i2c_read_field_test(void **state)
96{
97 int bus, slave, reg;
98 int i, j;
99 uint8_t buf;
100
101 mock_expect_params_platform_i2c_transfer();
102
103 /* Read particular bits in all registers in all devices, then compare
104 with expected value. */
105 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
106 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
107 i2c_read_field(i2c_ex_devs[i].bus,
108 i2c_ex_devs[i].slave,
109 i2c_ex_devs[i].regs[j].reg,
110 &buf, MASK, SHIFT);
111 assert_int_equal((i2c_ex_devs[i].regs[j].data &
112 (MASK << SHIFT)) >> SHIFT, buf);
113 };
114
115 /* Read whole registers */
116 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
117 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
118 i2c_read_field(i2c_ex_devs[i].bus,
119 i2c_ex_devs[i].slave,
120 i2c_ex_devs[i].regs[j].reg,
121 &buf, 0xFF, 0);
122 assert_int_equal(i2c_ex_devs[i].regs[j].data, buf);
123 };
124}
125
126static void i2c_write_field_test(void **state)
127{
128 int bus, slave, reg;
129 int i, j;
130 uint8_t buf, tmp;
131
132 mock_expect_params_platform_i2c_transfer();
133
134 /* Clear particular bits in all registers in all devices, then compare
135 with expected value. */
136 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
137 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
138 buf = 0x0;
139 tmp = i2c_ex_devs[i].regs[j].data;
140 i2c_write_field(i2c_ex_devs[i].bus,
141 i2c_ex_devs[i].slave,
142 i2c_ex_devs[i].regs[j].reg,
143 buf, MASK, SHIFT);
144 assert_int_equal(i2c_ex_devs[i].regs[j].data,
145 (tmp & ~(MASK << SHIFT)) | (buf << SHIFT));
146 };
147
148 /* Set all bits in all registers, this time verify using
149 i2c_read_field() accessor. */
150 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
151 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
152 i2c_write_field(i2c_ex_devs[i].bus,
153 i2c_ex_devs[i].slave,
154 i2c_ex_devs[i].regs[j].reg,
155 0xFF, 0xFF, 0);
156 i2c_read_field(i2c_ex_devs[i].bus,
157 i2c_ex_devs[i].slave,
158 i2c_ex_devs[i].regs[j].reg,
159 &buf, 0xFF, 0);
160 assert_int_equal(buf, 0xFF);
161 };
162}
163
164int main(void)
165{
166 const struct CMUnitTest tests[] = {
167 cmocka_unit_test(i2c_read_field_test),
168 cmocka_unit_test(i2c_write_field_test)
169 };
170
171 return cmocka_run_group_tests(tests, NULL, NULL);
172}