blob: 4b96d940f9d8cb53c2a43a1c6441061f71d2e8ae [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[] = {
Jakub Czapigac08b6a72022-01-10 13:36:47 +000021 {
22 .bus = 0,
23 .slave = 0xA,
24 .regs = {
25 {.reg = 0x0, .data = 0xB},
26 {.reg = 0x1, .data = 0x6},
27 {.reg = 0x2, .data = 0xF},
28 }
29 },
30 {
31 .bus = 0,
32 .slave = 0x3,
33 .regs = {
34 {.reg = 0x0, .data = 0xDE},
35 {.reg = 0x1, .data = 0xAD},
36 {.reg = 0x2, .data = 0xBE},
37 }
38 },
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020039};
40
Jakub Czapigac08b6a72022-01-10 13:36:47 +000041int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020042{
43 int i;
44 int reg;
45 struct i2c_msg *tmp = segments;
46 i2c_ex_devs_t *i2c_dev = NULL;
47
48 check_expected(count);
49
50 for (i = 0; i < count; i++, segments++) {
51 check_expected_ptr(segments->buf);
52 check_expected(segments->flags);
53 }
54
55 reg = tmp->buf[0];
56
57 /* Find object for requested device */
Julius Werner1e14de82020-06-10 15:35:08 -070058 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020059 if (i2c_ex_devs[i].slave == tmp->slave) {
60 i2c_dev = &i2c_ex_devs[i];
61 break;
62 }
63
64 if (i2c_dev == NULL)
65 return -1;
66
67 /* Write commands */
68 if (tmp->len > 1) {
69 i2c_dev->regs[reg].data = tmp->buf[1];
70 };
71
72 /* Read commands */
73 for (i = 0; i < count; i++, tmp++)
74 if (tmp->flags & I2C_M_RD) {
75 *(tmp->buf) = i2c_dev->regs[reg].data;
76 };
Julius Werner1e14de82020-06-10 15:35:08 -070077
78 return 0;
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020079}
80
81static void mock_expect_params_platform_i2c_transfer(void)
82{
Jakub Czapigac08b6a72022-01-10 13:36:47 +000083 unsigned long int expected_flags[] = {0, I2C_M_RD, I2C_M_TEN, I2C_M_RECV_LEN,
84 I2C_M_NOSTART};
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020085
86 /* Flags should always be only within supported range */
Jakub Czapigac08b6a72022-01-10 13:36:47 +000087 expect_in_set_count(platform_i2c_transfer, segments->flags, expected_flags, -1);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020088
Jakub Czapigac08b6a72022-01-10 13:36:47 +000089 expect_not_value_count(platform_i2c_transfer, segments->buf, NULL, -1);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020090
Jakub Czapigac08b6a72022-01-10 13:36:47 +000091 expect_in_range_count(platform_i2c_transfer, count, 1, INT_MAX, -1);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020092}
93
Jakub Czapigac08b6a72022-01-10 13:36:47 +000094#define MASK 0x3
95#define SHIFT 0x1
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020096
97static void i2c_read_field_test(void **state)
98{
Jan Dabrosa67cc5f2020-04-20 14:34:16 +020099 int i, j;
100 uint8_t buf;
101
102 mock_expect_params_platform_i2c_transfer();
103
104 /* Read particular bits in all registers in all devices, then compare
105 with expected value. */
106 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
107 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000108 i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
109 i2c_ex_devs[i].regs[j].reg, &buf, MASK, SHIFT);
110 assert_int_equal(
111 (i2c_ex_devs[i].regs[j].data & (MASK << SHIFT)) >> SHIFT, buf);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200112 };
113
114 /* Read whole registers */
115 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
116 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000117 i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
118 i2c_ex_devs[i].regs[j].reg, &buf, 0xFF, 0);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200119 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;
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000136 i2c_write_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
137 i2c_ex_devs[i].regs[j].reg, buf, MASK, SHIFT);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200138 assert_int_equal(i2c_ex_devs[i].regs[j].data,
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000139 (tmp & ~(MASK << SHIFT)) | (buf << SHIFT));
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200140 };
141
142 /* Set all bits in all registers, this time verify using
143 i2c_read_field() accessor. */
144 for (i = 0; i < ARRAY_SIZE(i2c_ex_devs); i++)
145 for (j = 0; j < ARRAY_SIZE(i2c_ex_devs[0].regs); j++) {
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000146 i2c_write_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
147 i2c_ex_devs[i].regs[j].reg, 0xFF, 0xFF, 0);
148 i2c_read_field(i2c_ex_devs[i].bus, i2c_ex_devs[i].slave,
149 i2c_ex_devs[i].regs[j].reg, &buf, 0xFF, 0);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200150 assert_int_equal(buf, 0xFF);
151 };
152}
153
154int main(void)
155{
Jakub Czapigac08b6a72022-01-10 13:36:47 +0000156 const struct CMUnitTest tests[] = {cmocka_unit_test(i2c_read_field_test),
157 cmocka_unit_test(i2c_write_field_test)};
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200158
Jakub Czapiga7c6081e2021-08-25 16:27:35 +0200159 return cb_run_group_tests(tests, NULL, NULL);
Jan Dabrosa67cc5f2020-04-20 14:34:16 +0200160}