Software APIs
dif_sensor_ctrl.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 
6 
7 #include <assert.h>
8 
11 #include "sw/device/lib/base/multibits.h"
13 
14 #include "sensor_ctrl_regs.h" // Generated
15 
16 /**
17  * Helper function to determine if a higher than supported event was supplied
18  * as an argument. This check is used in multiple places so use a helper
19  * function.
20  */
21 static inline bool is_ast_event_valid(dif_sensor_ctrl_event_idx_t event_idx) {
22  return event_idx < SENSOR_CTRL_PARAM_NUM_ALERT_EVENTS;
23 }
24 
25 /**
26  * Helper function to get CFG_REGWEN
27  */
28 static bool is_locked(const dif_sensor_ctrl_t *sensor_ctrl) {
29  return (mmio_region_read32(sensor_ctrl->base_addr,
30  SENSOR_CTRL_CFG_REGWEN_REG_OFFSET) == 0);
31 }
32 
35  if (sensor_ctrl == NULL) {
36  return kDifBadArg;
37  }
38 
39  mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_CFG_REGWEN_REG_OFFSET,
40  0);
41 
42  return kDifOk;
43 }
44 
47  const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
48  dif_toggle_t *enable) {
49  if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx) || enable == NULL) {
50  return kDifBadArg;
51  };
52 
53  uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
54  SENSOR_CTRL_ALERT_TRIG_REG_OFFSET);
55  *enable = dif_bool_to_toggle(bitfield_bit32_read(reg, event_idx));
56 
57  return kDifOk;
58 }
59 
62  const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
63  dif_toggle_t enable) {
64  if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
65  return kDifBadArg;
66  };
67 
68  uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
69  SENSOR_CTRL_ALERT_TRIG_REG_OFFSET);
70  reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(enable));
71  mmio_region_write32(sensor_ctrl->base_addr, SENSOR_CTRL_ALERT_TRIG_REG_OFFSET,
72  reg);
73 
74  return kDifOk;
75 }
76 
80  dif_toggle_t en) {
81  if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
82  return kDifBadArg;
83  };
84 
85  if (is_locked(sensor_ctrl)) {
86  return kDifLocked;
87  }
88 
89  mmio_region_write32(
90  sensor_ctrl->base_addr,
91  SENSOR_CTRL_ALERT_EN_0_REG_OFFSET + ((ptrdiff_t)event_idx << 2),
93 
94  return kDifOk;
95 }
96 
99  const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_event_idx_t event_idx,
100  dif_toggle_t en_fatal) {
101  if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
102  return kDifBadArg;
103  };
104 
105  if (is_locked(sensor_ctrl)) {
106  return kDifLocked;
107  }
108 
109  uint32_t reg = mmio_region_read32(sensor_ctrl->base_addr,
110  SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET);
111  reg = bitfield_bit32_write(reg, event_idx, dif_toggle_to_bool(en_fatal));
112  mmio_region_write32(sensor_ctrl->base_addr,
113  SENSOR_CTRL_FATAL_ALERT_EN_REG_OFFSET, reg);
114 
115  return kDifOk;
116 }
117 
120  const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) {
121  if (sensor_ctrl == NULL || events == NULL) {
122  return kDifBadArg;
123  };
124 
125  *events = mmio_region_read32(sensor_ctrl->base_addr,
126  SENSOR_CTRL_RECOV_ALERT_REG_OFFSET);
127 
128  return kDifOk;
129 };
130 
133  const dif_sensor_ctrl_t *sensor_ctrl,
134  dif_sensor_ctrl_event_idx_t event_idx) {
135  if (sensor_ctrl == NULL || !is_ast_event_valid(event_idx)) {
136  return kDifBadArg;
137  };
138 
139  uint32_t reg = bitfield_bit32_write(0, event_idx, 1);
140  mmio_region_write32(sensor_ctrl->base_addr,
141  SENSOR_CTRL_RECOV_ALERT_REG_OFFSET, reg);
142 
143  return kDifOk;
144 }
145 
148  const dif_sensor_ctrl_t *sensor_ctrl, dif_sensor_ctrl_events_t *events) {
149  if (sensor_ctrl == NULL || events == NULL) {
150  return kDifBadArg;
151  };
152 
153  *events = mmio_region_read32(sensor_ctrl->base_addr,
154  SENSOR_CTRL_FATAL_ALERT_REG_OFFSET);
155 
156  return kDifOk;
157 };
158 
161  const dif_sensor_ctrl_t *sensor_ctrl, dif_toggle_t *done) {
162  if (sensor_ctrl == NULL || done == NULL) {
163  return kDifBadArg;
164  };
165 
166  uint32_t reg =
167  mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET);
168  *done = dif_bool_to_toggle(
169  bitfield_bit32_read(reg, SENSOR_CTRL_STATUS_AST_INIT_DONE_BIT));
170 
171  return kDifOk;
172 }
173 
176  const dif_sensor_ctrl_t *sensor_ctrl,
177  dif_sensor_ctrl_io_power_status_t *io_power_status) {
178  if (sensor_ctrl == NULL || io_power_status == NULL) {
179  return kDifBadArg;
180  };
181 
182  uint32_t reg =
183  mmio_region_read32(sensor_ctrl->base_addr, SENSOR_CTRL_STATUS_REG_OFFSET);
184  *io_power_status =
185  bitfield_field32_read(reg, SENSOR_CTRL_STATUS_IO_POK_FIELD);
186 
187  return kDifOk;
188 }