Software APIs
dif_i2c_autogen.c
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5
6
7
8
9
10
11// THIS FILE HAS BEEN GENERATED, DO NOT EDIT MANUALLY. COMMAND:
12// util/autogen_dif.py -i hw/ip/i2c/data/i2c.hjson -o
13// bazel-out/k8-fastbuild-ST-24cc6a2908d2/bin/sw/device/lib/dif/autogen
14
15
16#include <stdint.h>
17
19#include "sw/device/lib/dif/autogen/dif_i2c_autogen.h"
20
21#include "i2c_regs.h" // Generated.
22
23
25dif_result_t dif_i2c_init(
26 mmio_region_t base_addr,
27 dif_i2c_t *i2c) {
28 if (i2c == NULL) {
29 return kDifBadArg;
30 }
31
32 i2c->dt = kDtI2cCount;
33 i2c->base_addr = base_addr;
34
35 return kDifOk;
36}
37
39dif_result_t dif_i2c_init_from_dt(
40 dt_i2c_t dt,
41 dif_i2c_t *i2c) {
42 if (i2c == NULL) {
43 return kDifBadArg;
44 }
45
46 i2c->dt = dt;
47 i2c->base_addr = mmio_region_from_addr(dt_i2c_primary_reg_block(dt));
48
49 return kDifOk;
50}
51
52dif_result_t dif_i2c_get_dt(
53 const dif_i2c_t *i2c,
54 dt_i2c_t *dt) {
55 if (i2c->dt == kDtI2cCount || dt == NULL) {
56 return kDifBadArg;
57 }
58 *dt = i2c->dt;
59 return kDifOk;
60}
61
62 dif_result_t dif_i2c_alert_force(
63 const dif_i2c_t *i2c,
64 dif_i2c_alert_t alert) {
65 if (i2c == NULL) {
66 return kDifBadArg;
67 }
68
69 bitfield_bit32_index_t alert_idx;
70 switch (alert) {
72 alert_idx = I2C_ALERT_TEST_FATAL_FAULT_BIT;
73 break;
74 default:
75 return kDifBadArg;
76 }
77
78 uint32_t alert_test_reg = bitfield_bit32_write(0, alert_idx, true);
79 mmio_region_write32(
80 i2c->base_addr,
81 (ptrdiff_t)I2C_ALERT_TEST_REG_OFFSET,
82 alert_test_reg);
83
84
85 return kDifOk;
86}
87
88
89 /**
90 * Get the corresponding interrupt register bit offset of the IRQ.
91 */
92 static bool i2c_get_irq_bit_index(
93 dif_i2c_irq_t irq,
94 bitfield_bit32_index_t *index_out) {
95
96 switch (irq) {
98 *index_out = I2C_INTR_COMMON_FMT_THRESHOLD_BIT;
99 break;
101 *index_out = I2C_INTR_COMMON_RX_THRESHOLD_BIT;
102 break;
104 *index_out = I2C_INTR_COMMON_ACQ_THRESHOLD_BIT;
105 break;
107 *index_out = I2C_INTR_COMMON_RX_OVERFLOW_BIT;
108 break;
110 *index_out = I2C_INTR_COMMON_CONTROLLER_HALT_BIT;
111 break;
113 *index_out = I2C_INTR_COMMON_SCL_INTERFERENCE_BIT;
114 break;
116 *index_out = I2C_INTR_COMMON_SDA_INTERFERENCE_BIT;
117 break;
119 *index_out = I2C_INTR_COMMON_STRETCH_TIMEOUT_BIT;
120 break;
122 *index_out = I2C_INTR_COMMON_SDA_UNSTABLE_BIT;
123 break;
125 *index_out = I2C_INTR_COMMON_CMD_COMPLETE_BIT;
126 break;
128 *index_out = I2C_INTR_COMMON_TX_STRETCH_BIT;
129 break;
131 *index_out = I2C_INTR_COMMON_TX_THRESHOLD_BIT;
132 break;
134 *index_out = I2C_INTR_COMMON_ACQ_STRETCH_BIT;
135 break;
137 *index_out = I2C_INTR_COMMON_UNEXP_STOP_BIT;
138 break;
140 *index_out = I2C_INTR_COMMON_HOST_TIMEOUT_BIT;
141 break;
142 default:
143 return false;
144 }
145
146 return true;
147 }
148
149 static dif_irq_type_t irq_types[] = {
165 };
166
168 dif_result_t dif_i2c_irq_get_type(
169 const dif_i2c_t *i2c,
170 dif_i2c_irq_t irq,
171 dif_irq_type_t *type) {
172
173
174 if (i2c == NULL ||
175 type == NULL ||
177 irq > kDifI2cIrqHostTimeout) {
178 return kDifBadArg;
179 }
180
181 *type = irq_types[irq];
182
183 return kDifOk;
184 }
185
187 dif_result_t dif_i2c_irq_get_state(
188 const dif_i2c_t *i2c,
190
191 if (i2c == NULL || snapshot == NULL) {
192 return kDifBadArg;
193 }
194
195 *snapshot = mmio_region_read32(
196 i2c->base_addr,
197 (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET);
198
199
200 return kDifOk;
201 }
202
204 dif_result_t dif_i2c_irq_acknowledge_state(
205 const dif_i2c_t *i2c,
207 if (i2c == NULL) {
208 return kDifBadArg;
209 }
210
211 mmio_region_write32(
212 i2c->base_addr,
213 (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
214 snapshot);
215
216
217 return kDifOk;
218 }
219
221 dif_result_t dif_i2c_irq_is_pending(
222 const dif_i2c_t *i2c,
223 dif_i2c_irq_t irq,
224 bool *is_pending) {
225
226 if (i2c == NULL || is_pending == NULL) {
227 return kDifBadArg;
228 }
229
231 if (!i2c_get_irq_bit_index(irq, &index)) {
232 return kDifBadArg;
233 }
234
235 uint32_t intr_state_reg = mmio_region_read32(
236 i2c->base_addr,
237 (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET);
238
239
240 *is_pending = bitfield_bit32_read(intr_state_reg, index);
241
242 return kDifOk;
243 }
244
246 dif_result_t dif_i2c_irq_acknowledge_all(
247 const dif_i2c_t *i2c
248 ) {
249
250 if (i2c == NULL) {
251 return kDifBadArg;
252 }
253
254 // Writing to the register clears the corresponding bits (Write-one clear).
255 mmio_region_write32(
256 i2c->base_addr,
257 (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
258 UINT32_MAX);
259
260
261 return kDifOk;
262 }
263
265 dif_result_t dif_i2c_irq_acknowledge(
266 const dif_i2c_t *i2c,
267 dif_i2c_irq_t irq) {
268
269 if (i2c == NULL) {
270 return kDifBadArg;
271 }
272
274 if (!i2c_get_irq_bit_index(irq, &index)) {
275 return kDifBadArg;
276 }
277
278 // Writing to the register clears the corresponding bits (Write-one clear).
279 uint32_t intr_state_reg = bitfield_bit32_write(0, index, true);
280 mmio_region_write32(
281 i2c->base_addr,
282 (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
283 intr_state_reg);
284
285
286 return kDifOk;
287 }
288
290 dif_result_t dif_i2c_irq_force(
291 const dif_i2c_t *i2c,
292 dif_i2c_irq_t irq,
293 const bool val) {
294
295 if (i2c == NULL) {
296 return kDifBadArg;
297 }
298
300 if (!i2c_get_irq_bit_index(irq, &index)) {
301 return kDifBadArg;
302 }
303
304 uint32_t intr_test_reg = bitfield_bit32_write(0, index, val);
305 mmio_region_write32(
306 i2c->base_addr,
307 (ptrdiff_t)I2C_INTR_TEST_REG_OFFSET,
308 intr_test_reg);
309
310
311 return kDifOk;
312 }
313
315 dif_result_t dif_i2c_irq_get_enabled(
316 const dif_i2c_t *i2c,
317 dif_i2c_irq_t irq,
318 dif_toggle_t *state) {
319
320 if (i2c == NULL || state == NULL) {
321 return kDifBadArg;
322 }
323
325 if (!i2c_get_irq_bit_index(irq, &index)) {
326 return kDifBadArg;
327 }
328
329 uint32_t intr_enable_reg = mmio_region_read32(
330 i2c->base_addr,
331 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
332
333
334 bool is_enabled = bitfield_bit32_read(intr_enable_reg, index);
335 *state = is_enabled ?
337
338 return kDifOk;
339 }
340
342 dif_result_t dif_i2c_irq_set_enabled(
343 const dif_i2c_t *i2c,
344 dif_i2c_irq_t irq,
345 dif_toggle_t state) {
346
347 if (i2c == NULL) {
348 return kDifBadArg;
349 }
350
352 if (!i2c_get_irq_bit_index(irq, &index)) {
353 return kDifBadArg;
354 }
355
356 uint32_t intr_enable_reg = mmio_region_read32(
357 i2c->base_addr,
358 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
359
360
361 bool enable_bit = (state == kDifToggleEnabled) ? true : false;
362 intr_enable_reg = bitfield_bit32_write(intr_enable_reg, index, enable_bit);
363 mmio_region_write32(
364 i2c->base_addr,
365 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
366 intr_enable_reg);
367
368
369 return kDifOk;
370 }
371
373 dif_result_t dif_i2c_irq_disable_all(
374 const dif_i2c_t *i2c,
376
377 if (i2c == NULL) {
378 return kDifBadArg;
379 }
380
381 // Pass the current interrupt state to the caller, if requested.
382 if (snapshot != NULL) {
383 *snapshot = mmio_region_read32(
384 i2c->base_addr,
385 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
386
387 }
388
389 // Disable all interrupts.
390 mmio_region_write32(
391 i2c->base_addr,
392 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
393 0u);
394
395
396 return kDifOk;
397 }
398
400 dif_result_t dif_i2c_irq_restore_all(
401 const dif_i2c_t *i2c,
402 const dif_i2c_irq_enable_snapshot_t *snapshot) {
403
404 if (i2c == NULL || snapshot == NULL) {
405 return kDifBadArg;
406 }
407
408 mmio_region_write32(
409 i2c->base_addr,
410 (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
411 *snapshot);
412
413
414 return kDifOk;
415 }
416