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 
32 #include "sw/device/lib/dif/autogen/dif_pinmux_autogen.h"
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  */
286 dif_result_t dif_pinmux_lock(const dif_pinmux_t *pinmux,
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  */
302 dif_result_t dif_pinmux_is_locked(const dif_pinmux_t *pinmux,
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  */
319 dif_result_t dif_pinmux_input_select(const dif_pinmux_t *pinmux,
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  */
335 dif_result_t dif_pinmux_output_select(const dif_pinmux_t *pinmux,
336  dif_pinmux_index_t mio_pad_output,
337  dif_pinmux_index_t outsel);
338 
339 /**
340  * Sets a connection between a peripheral input and a MIO pad input.
341  *
342  * A peripheral input can be connected to any available MIO pad input.
343  *
344  * @param pinmux A Pin Multiplexer handle.
345  * @param pad A pad.
346  * @param pin A peripheral I/O.
347  * @return The result of the operation.
348  */
350 dif_result_t dif_pinmux_mio_select_input(const dif_pinmux_t *pinmux,
351  dt_periph_io_t periph_io,
352  dt_pad_t pad);
353 
354 /**
355  * Sets a connection between a MIO pad output and peripheral output.
356  *
357  * A MIO pad output can be connected to any available peripheral output.
358  *
359  * @param pinmux A Pin Multiplexer handle.
360  * @param pad A pad.
361  * @param pin A peripheral I/O.
362  * @return The result of the operation.
363  */
365 dif_result_t dif_pinmux_mio_select_output(const dif_pinmux_t *pinmux,
366  dt_pad_t pad,
367  dt_periph_io_t periph_io);
368 
369 /** Convert a `dt_pad_t` into a pair (`dif_pinmux_index_t`,
370  * `dif_pinmux_pad_kind_t`) that can be used for pad control functions
371  * (`dif_pinmux_pad_*` functions).
372  *
373  * This function is there to handle legacy calls to various pad functions.
374  *
375  * @param pad A pad.
376  * @param index_out[out] The index of this pad.
377  * @param type_out[out] The type of pad.
378  * @return The result of the operation.
379  */
382  dif_pinmux_index_t *index_out,
383  dif_pinmux_pad_kind_t *type_out);
384 
385 /**
386  * Writes attributes for a pad.
387  *
388  * This function completely overwrites the existing configuration of a pad, and
389  * has both enable and disable semantics.
390  *
391  * Not all pads implement all attributes and some combinations cannot be
392  * enabled together. This function returns a `kDifBadArg` error in case of
393  * invalid `attrs_in`.
394  * Not all target platforms support all attribute values and the underlying
395  * hardware registers implement Write-Any Read-Legal (WARL) semantics. For
396  * example, the maximum supported slew rate and drive strength may vary between
397  * platforms. If the specified attribute values are valid but not supported by
398  * the hardware, this function returns `kDifError` and the caller needs to
399  * decide on how to resolve the situation. Unsupported or conflicting attribute
400  * values can be identified by comparing `attrs_in` to `attrs_out`.
401  *
402  * IMPORTANT:
403  * See `dif_pinmux_pad_attr` for information on which attributes are compulsory
404  * and which invariants are mutually exclusive.
405  *
406  * @param pinmux A Pin Multiplexer handle.
407  * @param pad Pad index to write the attributes for.
408  * @param type Pad type (MIO or DIO).
409  * @param attrs_in Attribute values to write.
410  * @param attrs_out[out] The actual attributes written and accepted by the
411  * hardware.
412  * @return The result of the operation.
413  */
415 dif_result_t dif_pinmux_pad_write_attrs(const dif_pinmux_t *pinmux,
416  dif_pinmux_index_t pad,
418  dif_pinmux_pad_attr_t attrs_in,
419  dif_pinmux_pad_attr_t *attrs_out);
420 
421 /**
422  * Write attributes for a pad.
423  *
424  * See `dif_pinmux_pad_write_attrs` except that the pad is represented by
425  * a `dt_pad_t` instead of a pair (index,type).
426  */
428 dif_result_t dif_pinmux_pad_write_attrs_dt(const dif_pinmux_t *pinmux,
429  dt_pad_t pad,
430  dif_pinmux_pad_attr_t attrs_in,
431  dif_pinmux_pad_attr_t *attrs_out);
432 
433 /**
434  * Get attributes for a pad.
435  *
436  * @param pinmux A Pin Multiplexer handle.
437  * @param pad Pad index to obtain the attributes for.
438  * @param type Pad type (MIO or DIO).
439  * @param attrs[out] Obtained attributes.
440  * @return The result of the operation.
441  */
443 dif_result_t dif_pinmux_pad_get_attrs(const dif_pinmux_t *pinmux,
444  dif_pinmux_index_t pad,
446  dif_pinmux_pad_attr_t *attrs);
447 
448 /**
449  * Get attributes for a pad.
450  *
451  * See `dif_pinmux_pad_get_attrs` except that the pad is represented by
452  * a `dt_pad_t` instead of a pair (index,type).
453  */
454 dif_result_t dif_pinmux_pad_get_attrs_dt(const dif_pinmux_t *pinmux,
455  dt_pad_t pad,
456  dif_pinmux_pad_attr_t *attrs);
457 
458 /**
459  * Enables deep sleep mode of a particular pad.
460  *
461  * NOTE:
462  * After the chip has come back from deep sleep, the mode of a pad persists
463  * until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
464  * `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
465  * sleep, however it will not change the current mode.
466  *
467  * @param pinmux A Pin Multiplexer handle.
468  * @param pad Pad index.
469  * @param type Pad type (MIO or DIO).
470  * @param mode Pad deep sleep mode.
471  * @return The result of the operation.
472  */
474 dif_result_t dif_pinmux_pad_sleep_enable(const dif_pinmux_t *pinmux,
475  dif_pinmux_index_t pad,
478 
479 /**
480  * Disables deep sleep mode of a particular pad.
481  *
482  * NOTE:
483  * After the chip has come back from deep sleep, the mode of a pad persists
484  * until is explicitly cleared by `dif_pinmux_pad_sleep_clear_state`. Calling
485  * `dif_pinmux_pad_sleep_enable` will configure a pad mode for the next deep
486  * sleep, however it will not change the current mode.
487  *
488  * @param pinmux A Pin Multiplexer handle.
489  * @param pad Pad index.
490  * @param type Pad type (MIO or DIO).
491  * @return The result of the operation.
492  */
494 dif_result_t dif_pinmux_pad_sleep_disable(const dif_pinmux_t *pinmux,
495  dif_pinmux_index_t pad,
496  dif_pinmux_pad_kind_t type);
497 
498 /**
499  * Returns the state of a particular pad.
500  *
501  * When the pad is in deep sleep mode, the mode persists until is explicitly
502  * cleared via `dif_pinmux_pad_sleep_clear_state`.
503  *
504  * @param padmux A Pin Multiplexer handle.
505  * @param pad Pad index.
506  * @param type Padring pad type (MIO or DIO).
507  * @param[out] in_sleep_mode Pad state, `true` when in deep sleep mode.
508  * @return The result of the operation.
509  */
511 dif_result_t dif_pinmux_pad_sleep_get_state(const dif_pinmux_t *pinmux,
512  dif_pinmux_index_t pad,
514  bool *in_sleep_mode);
515 
516 /**
517  * Clears deep sleep mode for a particular pad.
518  *
519  * When deep sleep mode is enabled for a pad, and the device has entered deep
520  * sleep mode; upon wake-up, the deep sleep status of this pad can only be
521  * cleared by calling this function. Re-configuring this pad will only take
522  * effect during the next deep sleep.
523  *
524  * @param pinmux A Pin Multiplexer handle.
525  * @param pad Pad index.
526  * @param type Padring pad type (MIO or DIO).
527  * @return The result of the operation.
528  */
530 dif_result_t dif_pinmux_pad_sleep_clear_state(const dif_pinmux_t *pinmux,
531  dif_pinmux_index_t pad,
532  dif_pinmux_pad_kind_t type);
533 
534 /**
535  * Enables wake-up mode detection for a particular detector.
536  *
537  * @param pinmux A Pin Multiplexer handle.
538  * @param detector A detector index.
539  * @param config A wake-up detector configuration.
540  * @return The result of the operation.
541  */
544  const dif_pinmux_t *pinmux, dif_pinmux_index_t detector,
546 
547 /**
548  * Disables wake-up detection for a particular detector.
549  *
550  * @param pinmux A Pin Multiplexer handle.
551  * @param detector A detector index.
552  * @return The result of the operation.
553  */
555 dif_result_t dif_pinmux_wakeup_detector_disable(const dif_pinmux_t *pinmux,
556  dif_pinmux_index_t detector);
557 
558 /**
559  * Clears the wake-up cause information.
560  *
561  * @param pinmux A Pin Multiplexer handle.
562  * @return The result of the operation.
563  */
565 dif_result_t dif_pinmux_wakeup_cause_clear(const dif_pinmux_t *pinmux);
566 
567 /**
568  * Retrieves the detectors that have detected wake-up patterns.
569  *
570  * @param pinmux A Pin Multiplexer handle.
571  * @param detector_map[out] A bit map representing detectors that have detected
572  * wake-up patterns.
573  * @return The result of the operation.
574  */
576 dif_result_t dif_pinmux_wakeup_cause_get(const dif_pinmux_t *pinmux,
577  uint32_t *detector_map);
578 
579 #ifdef __cplusplus
580 } // extern "C"
581 #endif // __cplusplus
582 
583 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_PINMUX_H_