Merge branch 'refactor/remove_legacy_ldo_driver' into 'master'

refactor(ldo): remove legacy private ldo driver

Closes IDF-9566

See merge request espressif/esp-idf!29834
This commit is contained in:
morris 2024-04-08 17:11:49 +08:00
commit b2afd70b32
3 changed files with 1 additions and 352 deletions

View File

@ -78,7 +78,7 @@ if(NOT BOOTLOADER_BUILD)
endif()
if(CONFIG_SOC_GP_LDO_SUPPORTED)
list(APPEND srcs "ldo/esp_ldo.c" "ldo/esp_ldo_regulator.c")
list(APPEND srcs "ldo/esp_ldo_regulator.c")
endif()
if(CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED)

View File

@ -1,131 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "hal/ldo_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of LDO unit handle
*/
typedef struct ldo_unit_ctx_t *esp_ldo_unit_handle_t;
/**
* @brief LDO unit configurations
*/
typedef struct {
int voltage_mv; ///< LDO output voltage in mV
} esp_ldo_unit_cfg_t;
/**
* @brief LDO driver initial configurations
*/
typedef struct {
int unit_id; ///< LDO ID, this is aligned with datasheet, e.g. you should set this to 1, if using LDO ID 1
esp_ldo_unit_cfg_t cfg; ///< LDO unit configuration
struct {
uint32_t enable_unit: 1; ///< Enable the LDO unit after it's initialised
uint32_t shared_ldo: 1; ///< Mark this LDO unit as shared
} flags; ///< LDO unit flags
} esp_ldo_unit_init_cfg_t;
/**
* @brief Init a LDO during early stage
*
* @note This API is only for early stage usage
*
* @param[in] unit_id LDO unit ID
* @param[in] cfg LDO unit configuration
*
* @return LDO unit handle
*/
esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *init_config);
/**
* @brief Init a LDO
*
* @param[in] init_config LDO initial configurations
* @param[out] ret_unit LDO unit handle
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid arguments
* - ESP_ERR_NOT_FOUND: LDO unit is in use already
*/
esp_err_t esp_ldo_init_unit(const esp_ldo_unit_init_cfg_t *init_config, esp_ldo_unit_handle_t *ret_unit);
/**
* @brief Enable a LDO
*
* @param[in] unit LDO unit handle
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid arguments
* - ESP_ERR_INVALID_STATE: LDO is enabled already
*/
esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit);
/**
* @brief Set LDO output voltage
*
* @param[in] unit LDO unit handle
* @param[in] voltage_mv Voltage in mV
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid arguments
*/
esp_err_t esp_ldo_set_voltage(esp_ldo_unit_handle_t unit, int voltage_mv);
/**
* @Brief Disable a LDO
*
* @param[in] unit LDO unit handle
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid arguments
* - ESP_ERR_INVALID_STATE: LDO is disabled already
*/
esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit);
/**
* @brief Deinit a LDO
*
* @param[in] unit LDO unit handle
*
* @return
* - ESP_OK: On success
* - ESP_ERR_INVALID_ARG: Invalid arguments
* - ESP_ERR_INVALID_STATE: LDO is still enabled
*/
esp_err_t esp_ldo_deinit_unit(esp_ldo_unit_handle_t unit);
/**
* @brief Dump LDO usages
*
* @note This API shall not be called from an ISR.
* @note This API does not guarantee thread safety
*
* @param stream stream to print information to; use stdout or stderr to print
* to the console; use fmemopen/open_memstream to print to a
* string buffer.
* @return
* - ESP_OK
*/
esp_err_t esp_ldo_usage_dump(FILE* stream);
#ifdef __cplusplus
}
#endif

View File

@ -1,220 +0,0 @@
/*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "sdkconfig.h"
#include "stdatomic.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "soc/soc_caps.h"
#include "hal/ldo_ll.h"
#include "esp_private/esp_ldo.h"
static const DRAM_ATTR char TAG[] = "ldo";
typedef struct ldo_unit_ctx_t {
int unit_id;
int voltage_mv;
bool enabled;
int ref_cnt;
portMUX_TYPE spinlock;
} ldo_unit_ctx_t;
typedef struct ldo_ctx_t {
_lock_t mutex;
ldo_unit_ctx_t units[LDO_LL_UNIT_NUM];
} ldo_ctx_t;
static ldo_ctx_t s_ctx; //LDO context
//LDO1 is always reserved for Flash usage
static atomic_bool s_ldo_unit_claimed[LDO_LL_UNIT_NUM] = {ATOMIC_VAR_INIT(true),
ATOMIC_VAR_INIT(false),
ATOMIC_VAR_INIT(false),
ATOMIC_VAR_INIT(false)};
static bool s_ldo_unit_claim(uint32_t unit);
static bool s_ldo_unit_free(uint32_t unit);
static bool s_ldo_unit_needs_claim(const esp_ldo_unit_init_cfg_t *init_config);
//This API should always success
esp_ldo_unit_handle_t esp_ldo_init_unit_early(const esp_ldo_unit_init_cfg_t *init_config)
{
assert(init_config);
assert(ldo_ll_is_valid_ldo_id(init_config->unit_id));
int unit_id = LDO_ID2UNIT(init_config->unit_id);
ldo_unit_ctx_t *unit = &s_ctx.units[unit_id];
bool needs_claim = s_ldo_unit_needs_claim(init_config);
bool success_claim = false;
if (needs_claim) {
success_claim = s_ldo_unit_claim(unit_id);
assert(success_claim);
unit->unit_id = unit_id;
unit->voltage_mv = init_config->cfg.voltage_mv;
unit->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
ldo_ll_set_output_voltage_mv(unit_id, init_config->cfg.voltage_mv);
if (init_config->flags.enable_unit) {
ldo_ll_enable(unit_id, true);
unit->enabled = true;
}
} else {
bool same_voltage = init_config->cfg.voltage_mv == unit->voltage_mv;
assert(same_voltage);
}
unit->ref_cnt++;
return unit;
}
esp_err_t esp_ldo_init_unit(const esp_ldo_unit_init_cfg_t *init_config, esp_ldo_unit_handle_t *ret_unit)
{
ESP_RETURN_ON_FALSE(init_config && ret_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(ldo_ll_is_valid_ldo_id(init_config->unit_id), ESP_ERR_INVALID_ARG, TAG, "invalid ldo id");
int unit_id = LDO_ID2UNIT(init_config->unit_id);
ldo_unit_ctx_t *unit = &s_ctx.units[unit_id];
bool needs_claim = s_ldo_unit_needs_claim(init_config);
bool success_claim = false;
if (needs_claim) {
success_claim = s_ldo_unit_claim(unit_id);
ESP_RETURN_ON_FALSE(success_claim, ESP_ERR_NOT_FOUND, TAG, "ldo%d is already in use", init_config->unit_id);
unit->unit_id = unit_id;
unit->voltage_mv = init_config->cfg.voltage_mv;
unit->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
ldo_ll_set_output_voltage_mv(unit_id, init_config->cfg.voltage_mv);
if (init_config->flags.enable_unit) {
ldo_ll_enable(unit_id, true);
unit->enabled = true;
}
ESP_LOGD(TAG, "new ldo %d is created", unit->unit_id + 1);
} else {
bool same_voltage = init_config->cfg.voltage_mv == unit->voltage_mv;
ESP_RETURN_ON_FALSE(same_voltage, ESP_ERR_INVALID_ARG, TAG, "not same voltage, cannot share ldo%d", init_config->unit_id);
ESP_LOGD(TAG, "new ldo %d is shared", unit->unit_id + 1);
}
portENTER_CRITICAL(&unit->spinlock);
unit->ref_cnt++;
portEXIT_CRITICAL(&unit->spinlock);
*ret_unit = unit;
return ESP_OK;
}
esp_err_t esp_ldo_deinit_unit(esp_ldo_unit_handle_t unit)
{
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: uninitialized handler");
ESP_RETURN_ON_FALSE(unit->enabled == false, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is still enabled");
bool needs_free = false;
portENTER_CRITICAL(&unit->spinlock);
unit->ref_cnt -= 1;
if (unit->ref_cnt == 0) {
needs_free = true;
}
portEXIT_CRITICAL(&unit->spinlock);
if (needs_free) {
bool success_free = false;
success_free = s_ldo_unit_free(unit->unit_id);
ESP_RETURN_ON_FALSE(success_free, ESP_ERR_NOT_FOUND, TAG, "ldo%d isn't in use", unit->unit_id + 1);
ESP_LOGD(TAG, "ldo unit%d is deleted", unit->unit_id + 1);
_lock_acquire(&s_ctx.mutex);
memset(&s_ctx.units[unit->unit_id], 0x0, sizeof(ldo_unit_ctx_t));
_lock_release(&s_ctx.mutex);
}
return ESP_OK;
}
esp_err_t esp_ldo_enable_unit(esp_ldo_unit_handle_t unit)
{
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(unit->enabled == false, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is enabled already");
ldo_ll_enable(unit->unit_id, true);
unit->enabled = true;
return ESP_OK;
}
esp_err_t esp_ldo_set_voltage(esp_ldo_unit_handle_t unit, int voltage_mv)
{
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ldo_ll_set_output_voltage_mv(unit->unit_id, voltage_mv);
return ESP_OK;
}
esp_err_t esp_ldo_disable_unit(esp_ldo_unit_handle_t unit)
{
ESP_RETURN_ON_FALSE(unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(unit->enabled == true, ESP_ERR_INVALID_STATE, TAG, "invalid state: ldo unit is disabled already");
ldo_ll_enable(unit->unit_id, false);
unit->enabled = false;
return ESP_OK;
}
esp_err_t esp_ldo_usage_dump(FILE* stream)
{
char line[100];
fprintf(stream, "LDOs Info:\n");
for (int i = 0; i < LDO_LL_UNIT_NUM; i++) {
fprintf(stream, "%-15s %-14s %-14s\n", "LDO ID", "voltage_mv", "enabled");
char *buf = line;
size_t len = sizeof(line);
memset(line, 0x0, len);
snprintf(buf, len, "%-15d 0x%-12d %-11x\n",
s_ctx.units[i].unit_id + 1,
s_ctx.units[i].voltage_mv,
s_ctx.units[i].enabled);
fputs(line, stream);
}
fprintf(stream, "You can use a disabled LDO unit, or share an enabled LDO unit\n");
return ESP_OK;
}
static bool s_ldo_unit_claim(uint32_t unit)
{
bool false_var = false;
return atomic_compare_exchange_strong(&s_ldo_unit_claimed[unit], &false_var, true);
}
static bool s_ldo_unit_free(uint32_t unit)
{
bool true_var = true;
return atomic_compare_exchange_strong(&s_ldo_unit_claimed[unit], &true_var, false);
}
static bool s_ldo_unit_needs_claim(const esp_ldo_unit_init_cfg_t *init_config)
{
bool needs_claim = false;
int unit_id = LDO_ID2UNIT(init_config->unit_id);
if (s_ctx.units[unit_id].ref_cnt == 0) {
needs_claim = true;
} else {
if (!init_config->flags.shared_ldo) {
needs_claim = true;
}
}
return needs_claim;
}