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