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 // THIS FILE HAS BEEN GENERATED, DO NOT EDIT MANUALLY. COMMAND:
6 // util/make_new_dif.py --mode=regen --only=autogen
7 
9 
10 #include <stdint.h>
11 
13 
14 #include "i2c_regs.h" // Generated.
15 
18  if (i2c == NULL) {
19  return kDifBadArg;
20  }
21 
22  i2c->base_addr = base_addr;
23 
24  return kDifOk;
25 }
26 
28  if (i2c == NULL) {
29  return kDifBadArg;
30  }
31 
32  bitfield_bit32_index_t alert_idx;
33  switch (alert) {
35  alert_idx = I2C_ALERT_TEST_FATAL_FAULT_BIT;
36  break;
37  default:
38  return kDifBadArg;
39  }
40 
41  uint32_t alert_test_reg = bitfield_bit32_write(0, alert_idx, true);
42  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_ALERT_TEST_REG_OFFSET,
43  alert_test_reg);
44 
45  return kDifOk;
46 }
47 
48 /**
49  * Get the corresponding interrupt register bit offset of the IRQ.
50  */
51 static bool i2c_get_irq_bit_index(dif_i2c_irq_t irq,
52  bitfield_bit32_index_t *index_out) {
53  switch (irq) {
55  *index_out = I2C_INTR_COMMON_FMT_THRESHOLD_BIT;
56  break;
58  *index_out = I2C_INTR_COMMON_RX_THRESHOLD_BIT;
59  break;
61  *index_out = I2C_INTR_COMMON_ACQ_THRESHOLD_BIT;
62  break;
64  *index_out = I2C_INTR_COMMON_RX_OVERFLOW_BIT;
65  break;
67  *index_out = I2C_INTR_COMMON_CONTROLLER_HALT_BIT;
68  break;
70  *index_out = I2C_INTR_COMMON_SCL_INTERFERENCE_BIT;
71  break;
73  *index_out = I2C_INTR_COMMON_SDA_INTERFERENCE_BIT;
74  break;
76  *index_out = I2C_INTR_COMMON_STRETCH_TIMEOUT_BIT;
77  break;
79  *index_out = I2C_INTR_COMMON_SDA_UNSTABLE_BIT;
80  break;
82  *index_out = I2C_INTR_COMMON_CMD_COMPLETE_BIT;
83  break;
85  *index_out = I2C_INTR_COMMON_TX_STRETCH_BIT;
86  break;
88  *index_out = I2C_INTR_COMMON_TX_THRESHOLD_BIT;
89  break;
91  *index_out = I2C_INTR_COMMON_ACQ_STRETCH_BIT;
92  break;
94  *index_out = I2C_INTR_COMMON_UNEXP_STOP_BIT;
95  break;
97  *index_out = I2C_INTR_COMMON_HOST_TIMEOUT_BIT;
98  break;
99  default:
100  return false;
101  }
102 
103  return true;
104 }
105 
106 static dif_irq_type_t irq_types[] = {
111 };
112 
115  dif_irq_type_t *type) {
116  if (i2c == NULL || type == NULL || irq == kDifI2cIrqHostTimeout + 1) {
117  return kDifBadArg;
118  }
119 
120  *type = irq_types[irq];
121 
122  return kDifOk;
123 }
124 
127  dif_i2c_irq_state_snapshot_t *snapshot) {
128  if (i2c == NULL || snapshot == NULL) {
129  return kDifBadArg;
130  }
131 
132  *snapshot =
133  mmio_region_read32(i2c->base_addr, (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET);
134 
135  return kDifOk;
136 }
137 
140  const dif_i2c_t *i2c, dif_i2c_irq_state_snapshot_t snapshot) {
141  if (i2c == NULL) {
142  return kDifBadArg;
143  }
144 
145  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
146  snapshot);
147 
148  return kDifOk;
149 }
150 
153  bool *is_pending) {
154  if (i2c == NULL || is_pending == NULL) {
155  return kDifBadArg;
156  }
157 
159  if (!i2c_get_irq_bit_index(irq, &index)) {
160  return kDifBadArg;
161  }
162 
163  uint32_t intr_state_reg =
164  mmio_region_read32(i2c->base_addr, (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET);
165 
166  *is_pending = bitfield_bit32_read(intr_state_reg, index);
167 
168  return kDifOk;
169 }
170 
173  if (i2c == NULL) {
174  return kDifBadArg;
175  }
176 
177  // Writing to the register clears the corresponding bits (Write-one clear).
178  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
179  UINT32_MAX);
180 
181  return kDifOk;
182 }
183 
186  if (i2c == NULL) {
187  return kDifBadArg;
188  }
189 
191  if (!i2c_get_irq_bit_index(irq, &index)) {
192  return kDifBadArg;
193  }
194 
195  // Writing to the register clears the corresponding bits (Write-one clear).
196  uint32_t intr_state_reg = bitfield_bit32_write(0, index, true);
197  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_STATE_REG_OFFSET,
198  intr_state_reg);
199 
200  return kDifOk;
201 }
202 
205  const bool val) {
206  if (i2c == NULL) {
207  return kDifBadArg;
208  }
209 
211  if (!i2c_get_irq_bit_index(irq, &index)) {
212  return kDifBadArg;
213  }
214 
215  uint32_t intr_test_reg = bitfield_bit32_write(0, index, val);
216  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_TEST_REG_OFFSET,
217  intr_test_reg);
218 
219  return kDifOk;
220 }
221 
224  dif_toggle_t *state) {
225  if (i2c == NULL || state == NULL) {
226  return kDifBadArg;
227  }
228 
230  if (!i2c_get_irq_bit_index(irq, &index)) {
231  return kDifBadArg;
232  }
233 
234  uint32_t intr_enable_reg =
235  mmio_region_read32(i2c->base_addr, (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
236 
237  bool is_enabled = bitfield_bit32_read(intr_enable_reg, index);
238  *state = is_enabled ? kDifToggleEnabled : kDifToggleDisabled;
239 
240  return kDifOk;
241 }
242 
245  dif_toggle_t state) {
246  if (i2c == NULL) {
247  return kDifBadArg;
248  }
249 
251  if (!i2c_get_irq_bit_index(irq, &index)) {
252  return kDifBadArg;
253  }
254 
255  uint32_t intr_enable_reg =
256  mmio_region_read32(i2c->base_addr, (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
257 
258  bool enable_bit = (state == kDifToggleEnabled) ? true : false;
259  intr_enable_reg = bitfield_bit32_write(intr_enable_reg, index, enable_bit);
260  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
261  intr_enable_reg);
262 
263  return kDifOk;
264 }
265 
268  dif_i2c_irq_enable_snapshot_t *snapshot) {
269  if (i2c == NULL) {
270  return kDifBadArg;
271  }
272 
273  // Pass the current interrupt state to the caller, if requested.
274  if (snapshot != NULL) {
275  *snapshot = mmio_region_read32(i2c->base_addr,
276  (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET);
277  }
278 
279  // Disable all interrupts.
280  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
281  0u);
282 
283  return kDifOk;
284 }
285 
288  const dif_i2c_t *i2c, const dif_i2c_irq_enable_snapshot_t *snapshot) {
289  if (i2c == NULL || snapshot == NULL) {
290  return kDifBadArg;
291  }
292 
293  mmio_region_write32(i2c->base_addr, (ptrdiff_t)I2C_INTR_ENABLE_REG_OFFSET,
294  *snapshot);
295 
296  return kDifOk;
297 }