/* SPDX-FileCopyrightText: 2024 Google LLC */
/* SPDX-License-Identifier: Apache-2.0 */

#pragma once

#include <stdbool.h>

typedef enum {
  InhibitorMain,
  InhibitorDbgSerial,
  InhibitorButton,
  InhibitorBluetooth,
  InhibitorDisplay,
  InhibitorBacklight,
  InhibitorCommMode,
  InhibitorFlash,
  InhibitorI2C1,
  InhibitorI2C2,
  InhibitorMic,
  InhibitorAccessory,
  InhibitorVibes,
  InhibitorCompositor,
  InhibitorI2C3,
  InhibitorI2C4,
  InhibitorBluetoothWatchdog,
  InhibitorPWM,

  InhibitorNumItems
} StopModeInhibitor;

/** Enter stop mode.
 *
 *  \note Probably no good reason to call this function from most application 
 *  code. Let the FreeRTOS scheduler do its job.
 */
void enter_stop_mode(void);

/** Prevent the scheduler from entering stop mode in idle.  Usually called when
 * we know that there is some resource or peripheral being used that does not 
 * require the use of the CPU, but that going into stop mode would interrupt.
 * \note Internally this is implemented as a reference counter, so it is
 * necessary to balance each call to disallow_stop_mode with a matching call to
 * allow_stop_mode.
 *  CAUTION: This function cannot be called at priorities > Systick
 */
void stop_mode_disable(StopModeInhibitor inhibitor);

/** Allow the scheduler to enter stop mode in idle again.
 *  CAUTION: This function cannot be called at priorities > Systick
 */
void stop_mode_enable(StopModeInhibitor inhibitor);

//! Check whether we are permitted to go into stop mode
bool stop_mode_is_allowed(void);


//! Enable or disable sleep mode.
//! Note: When sleep mode is disabled so is stop mode. When sleep mode is enabled, stop mode is
//! controlled by stop_mode_is_allowed.
void sleep_mode_enable(bool enable);

//! Check whether we are permitted to go into sleep mode.
bool sleep_mode_is_allowed(void);

