Software APIs
dif_pinmux.h
Go to the documentation of this file.
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 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/top_earlgrey/ip_autogen/pinmux/doc/">Pin Multiplexer</a>
11  * Device Interface Functions
12  */
13 
14 /**
15  * Pin Multiplexer connects peripheral input/output signals to the Padring MIO
16  * pad input/output signals.
17  *
18  * Every peripheral input signal is fed into a multiplexer, where selects
19  * determine which Padring MIO pad input or constants should be connected to it.
20  *
21  * Every Padring MIO pad output signal is fed into a multiplexer, where selects
22  * determine which peripheral output or constants should be connected to it.
23  */
24 
25 #include <stdbool.h>
26 #include <stdint.h>
27 
31 
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif // __cplusplus
37 
38 /**
39  * Pin Multiplexer Padring pad kinds.
40  *
41  * A pad can be a Multiplexed (MIO) or Dedicated (DIO).
42  */
43 typedef enum dif_pinmux_pad_kind {
44  /**
45  * Multiplexed Input/Output pad. Connected to a peripheral input or output
46  * via a multiplexer matrix inside the a Pin Multiplexer.
47  */
49  /**
50  * Dedicated Input/Output pad. Connected directly to a peripheral input
51  * or output, bypassing the multiplexer matrix.
52  */
54  kDifPinmuxPadKindCount,
56 
57 /**
58  * Pin Multiplexer functionality locking.
59  *
60  * Represents a target functionality to be locked for a given
61  * pad/peripheral input.
62  */
63 typedef enum dif_pinmux_lock_target {
64  /**
65  * Lock MIO pad input select for a given peripheral input. This means that
66  * the peripheral input connection can no longer be changed.
67  */
69  /**
70  * Lock peripheral output select for a given MIO pad output. This means
71  * that the MIO pad output connection can no longer be changed.
72  */
74  /**
75  * Lock the sleep mode configuration for a given MIO pad.
76  */
78  /**
79  * Lock the sleep mode configuration for a given DIO pad.
80  */
82  /**
83  * Lock physical characteristics configuration for a given MIO pad.
84  */
86  /**
87  * Lock physical characteristics configuration for a given DIO pad.
88  */
90  /**
91  * Lock wake-up detector configuration for a given detector.
92  */
94 
96 
97 /**
98  * Pin Multiplexer generic index.
99  *
100  * The meaning of this index changes between APIs, and must be documented in
101  * the corresponding function description.
102  */
103 typedef uint32_t dif_pinmux_index_t;
104 
105 /**
106  * Pad slew rate value.
107  *
108  * This selects between available slew rate values, where the largest number
109  * produces the fastest slew rate. See the device's data sheet for the
110  * particular mapping.
111  */
113 
114 /**
115  * Pad drive strength value.
116  *
117  * This selects between available drive strength values, where the largest
118  * number produces the highest drive strength. See the device's data sheet for
119  * the particular mapping.
120  */
122 
123 /**
124  * Pad attribute flag values
125  *
126  * This `enum` is a bitfield, meaning that it is allowed to pass combined value
127  * of multiple individual attributes.
128  *
129  * Some attributes have defined meanings, others are implementation defined. Not
130  * all pads will support all attributes, or attribute combinations. The Pin
131  * Multiplexer DIF checks for conflicting or unsupported attributes provided by
132  * the Write-Any Read-Legal (WARL) semantics of the underlying hardware. If the
133  * combination of attributes is not supported - some/all of these attributes
134  * will still be disabled (relevant bit unset in the attribute field).
135  *
136  * IMPORTANT:
137  * - Functions are used to toggle these attributes, must signal an error if at
138  * least one of the attributes in the bitfield could not be toggled.
139  */
141  kDifPinmuxPadAttrInvertLevel = 1 << 0,
142  kDifPinmuxPadAttrVirtualOpenDrain = 1 << 1,
143  kDifPinmuxPadAttrPullResistorEnable = 1 << 2,
144  kDifPinmuxPadAttrPullResistorUp = 1 << 3,
145  kDifPinmuxPadAttrKeeper = 1 << 4,
146  kDifPinmuxPadAttrSchmittTrigger = 1 << 5,
147  kDifPinmuxPadAttrOpenDrain = 1 << 6,
148  kDifPinmuxPadAttrInputDisable = 1 << 7,
150 
151 /**
152  * Pin multiplexer padring pad attributes.
153  */
154 typedef struct dif_pinmux_pad_attr {
155  /**
156  * Slew rate attribute. A greater number produces a faster slew rate.
157  */
159  /**
160  * Drive strength pad attribute. A greater number produces a stronger drive.
161  */
163  /**
164  * A bit map of single-bit attribute flags. See dif_pinmux_pad_attr_flags_t
165  * for the mapping and definitions.
166  */
169 
170 /**
171  * A sleep mode for a Padring DIO/MIO pad.
172  *
173  * This determines the behaviour of a pad in deep sleep state.
174  *
175  * NOTE:
176  * After the chip has come back from deep sleep, the mode of the pad
177  * persists until it is explicitly cleared by `dif_pinmux_sleep_clear_state`.
178  * Calling `dif_pinmux_sleep_enable` will configure the pad mode for
179  * the next deep sleep, however it will not change the current mode.
180  */
181 typedef enum dif_pinmux_sleep_mode {
182  /**
183  * The pad is driven actively to zero.
184  */
186  /**
187  * The pad is driven actively to one.
188  */
190  /**
191  * The pad is left undriven. Note that the actual driving behaviour will
192  * depend on the pull-up/-down configuration.
193  */
195  /**
196  * Keep last driven value (including high-Z).
197  */
199  kDifPinmuxSleepModeCount,
201 
202 /**
203  * A Pin Multiplexer wake-up detection mode (edge triggered).
204  */
206  /**
207  * Trigger a wakeup request when observing a positive edge.
208  */
210  /**
211  * Trigger a wakeup request when observing a negative edge.
212  */
214  /**
215  * Trigger a wakeup request when observing an edge in any direction.
216  */
218  /**
219  * Trigger a wakeup request when pin is driven HIGH for a certain amount of
220  * always-on clock cycles as configured in
221  * `dif_pinmux_wakeup_timed_config_t`, `counter_threshold` field.
222  */
224  /**
225  * Trigger a wakeup request when pin is driven LOW for a certain amount of
226  * always-on clock cycles as configured in
227  * `dif_pinmux_wakeup_timed_config_t`, `counter_threshold` field.
228  */
230  kDifPinmuxWakeupModeCount,
232 
233 /**
234  * A Pin Multiplexer common wake-up configuration between different modes.
235  */
236 typedef struct dif_pinmux_wakeup_config {
237  /**
238  * Signal filter - signal must be stable for 4 always-on clock cycles
239  * before the value is being forwarded. Can be used for debouncing.
240  */
242  /**
243  * Pad type (MIO or DIO) to enable the wake-up detection for.
244  */
246  /**
247  * Selects a specific pad. In the case of MIO, the pad select index is the
248  * same as used for `dif_pinmux_input_select`, meaning that index 0 and 1 just
249  * select constant 0, and the MIO pads live at indices >= 2. In the case of
250  * DIO pads, the pad select index corresponds 1:1 to the DIO pad to be
251  * selected.
252  */
254  /**
255  * Wake-up detection mode.
256  */
258  /**
259  * Counter threshold for `kDifPinmuxWakeupModeTimedLow` and
260  * `kDifPinmuxWakeupModeTimedHigh` wake-up detector modes. The threshold is in
261  * terms of always-on clock cycles.
262  */
265 
266 /**
267  * Locks out Pin Multiplexer functionality based on the `target` and `index`.
268  *
269  * This function allows for a fine grained locking of the Pin Multiplexer
270  * parts. `index` changes meaning dependent on the `target`. For example, when
271  * `target` is `kDifPinmuxLockTargetInsel`, `index` represents a peripheral
272  * input for which the MIO input select functionality should be locked.
273  *
274  * NOTE:
275  * Locking an already locked register will succeed with the `kDifOk`
276  * return code.
277  *
278  * @param pinmux A Pin Multiplexer handle.
279  * @param index Exact meaning is determined by the `target`, however, it
280  * represents one of the following: peripheral input index,
281  * MIO pad index, DIO pad index or a wakeup detector index.
282  * @param target Target functionality to be locked.
283  * @return The result of the operation.
284  */
287  dif_pinmux_index_t index,
288  dif_pinmux_lock_target_t target);
289 
290 /**
291  * Obtains the Pin Multiplexer Pad lock status based on `target` and `index`.
292  *
293  * @param pinmux A Pin Multiplexer handle.
294  * @param index Exact meaning is determined by the `target`, however, it
295  * represents one of the following: peripheral input index,
296  * MIO pad index, DIO pad index or a wakeup detector index.
297  * @param target Target functionality to be locked.
298  * @param[out] is_locked Out-param for the locked state.
299  * @return The result of the operation.
300  */
303  dif_pinmux_index_t index,
305  bool *is_locked);
306 
307 /**
308  * Sets a connection between a peripheral input and a MIO pad input.
309  *
310  * A peripheral input can be connected to any available MIO pad input.
311  *
312  * @param pinmux A Pin Multiplexer handle.
313  * @param peripheral_input A Peripheral input index.
314  * @param insel Input connection select - a MIO pad input to be connected to
315  * a peripheral input.
316  * @return The result of the operation.
317  */
320  dif_pinmux_index_t peripheral_input,
321  dif_pinmux_index_t insel);
322 
323 /**
324  * Sets a connection between a MIO pad output and peripheral output.
325  *
326  * A MIO pad output can be connected to any available peripheral output.
327  *
328  * @param pinmux A Pin Multiplexer handle.
329  * @param mio_pad_output Padring MIO output index.
330  * @param outsel Peripheral output connection select - a Peripheral output to be
331  * connected to a MIO pad output.
332  * @return The result of the operation.
333  */
336  dif_pinmux_index_t mio_pad_output,
337  dif_pinmux_index_t outsel);
338 
339 /**
340  * Writes attributes for a pad.
341  *
342  * This function completely overwrites the existing configuration of a pad, and
343  * has both enable and disable semantics.
344  *
345  * Not all pads implement all attributes and some combinations cannot be
346  * enabled together. This function returns a `kDifBadArg` error in case of
347  * invalid `attrs_in`.
348  * Not all target platforms support all attribute values and the underlying
349  * hardware registers implement Write-Any Read-Legal (WARL) semantics. For
350  * example, the maximum supported slew rate and drive strength may vary between
351  * platforms. If the specified attribute values are valid but not supported by
352  * the hardware, this function returns `kDifError` and the caller needs to
353  * decide on how to resolve the situation. Unsupported or conflicting attribute
354  * values can be identified by comparing `attrs_in` to `attrs_out`.
355  *
356  * IMPORTANT:
357  * See `dif_pinmux_pad_attr` for information on which attributes are compulsory
358  * and which invariants are mutually exclusive.
359  *
360  * @param pinmux A Pin Multiplexer handle.
361  * @param pad Pad index to write the attributes for.
362  * @param type Pad type (MIO or DIO).
363  * @param attrs_in Attribute values to write.
364  * @param attrs_out[out] The actual attributes written and accepted by the
365  * hardware.
366  * @return The result of the operation.
367  */
370  dif_pinmux_index_t pad,
372  dif_pinmux_pad_attr_t attrs_in,
373  dif_pinmux_pad_attr_t *attrs_out);
374 
375 /**
376  * Get attributes for a pad.
377  *
378  * @param pinmux A Pin Multiplexer handle.
379  * @param pad Pad index to obtain the attributes for.
380  * @param type Pad type (MIO or DIO).
381  * @param attrs[out] Obtained attributes.
382  * @return The result of the operation.
383  */
386  dif_pinmux_index_t pad,
388  dif_pinmux_pad_attr_t *attrs);
389 
390 /**
391  * Enables deep sleep mode of a particular pad.
392  *
393  * NOTE:
394  * After the chip has come back from deep sleep, the mode of a pad persists
395  * until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
396  * `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
397  * sleep, however it will not change the current mode.
398  *
399  * @param pinmux A Pin Multiplexer handle.
400  * @param pad Pad index.
401  * @param type Pad type (MIO or DIO).
402  * @param mode Pad deep sleep mode.
403  * @return The result of the operation.
404  */
407  dif_pinmux_index_t pad,
410 
411 /**
412  * Disables deep sleep mode of a particular pad.
413  *
414  * NOTE:
415  * After the chip has come back from deep sleep, the mode of a pad persists
416  * until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
417  * `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
418  * sleep, however it will not change the current mode.
419  *
420  * @param pinmux A Pin Multiplexer handle.
421  * @param pad Pad index.
422  * @param type Pad type (MIO or DIO).
423  * @return The result of the operation.
424  */
427  dif_pinmux_index_t pad,
428  dif_pinmux_pad_kind_t type);
429 
430 /**
431  * Returns the state of a particular pad.
432  *
433  * When the pad is in deep sleep mode, the mode persists until is explicitly
434  * cleared via `dif_pinmux_pad_sleep_clear_state`.
435  *
436  * @param padmux A Pin Multiplexer handle.
437  * @param pad Pad index.
438  * @param type Padring pad type (MIO or DIO).
439  * @param[out] in_sleep_mode Pad state, `true` when in deep sleep mode.
440  * @return The result of the operation.
441  */
444  dif_pinmux_index_t pad,
446  bool *in_sleep_mode);
447 
448 /**
449  * Clears deep sleep mode for a particular pad.
450  *
451  * When deep sleep mode is enabled for a pad, and the device has entered deep
452  * sleep mode; upon wake-up, the deep sleep status of this pad can only be
453  * cleared by calling this function. Re-configuring this pad will only take
454  * effect during the next deep sleep.
455  *
456  * @param pinmux A Pin Multiplexer handle.
457  * @param pad Pad index.
458  * @param type Padring pad type (MIO or DIO).
459  * @return The result of the operation.
460  */
463  dif_pinmux_index_t pad,
464  dif_pinmux_pad_kind_t type);
465 
466 /**
467  * Enables wake-up mode detection for a particular detector.
468  *
469  * @param pinmux A Pin Multiplexer handle.
470  * @param detector A detector index.
471  * @param config A wake-up detector configuration.
472  * @return The result of the operation.
473  */
476  const dif_pinmux_t *pinmux, dif_pinmux_index_t detector,
478 
479 /**
480  * Disables wake-up detection for a particular detector.
481  *
482  * @param pinmux A Pin Multiplexer handle.
483  * @param detector A detector index.
484  * @return The result of the operation.
485  */
488  dif_pinmux_index_t detector);
489 
490 /**
491  * Clears the wake-up cause information.
492  *
493  * @param pinmux A Pin Multiplexer handle.
494  * @return The result of the operation.
495  */
498 
499 /**
500  * Retrieves the detectors that have detected wake-up patterns.
501  *
502  * @param pinmux A Pin Multiplexer handle.
503  * @param detector_map[out] A bit map representing detectors that have detected
504  * wake-up patterns.
505  * @return The result of the operation.
506  */
509  uint32_t *detector_map);
510 
511 #ifdef __cplusplus
512 } // extern "C"
513 #endif // __cplusplus
514 
515 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_