[es8388] Add initial option configuration for DAC output and ADC input mic (#16342)

Co-authored-by: J. Nick Koston <nick@home-assistant.io>
This commit is contained in:
cociweb
2026-10-13 08:14:43 -10:00
committed by GitHub
co-authored by J. Nick Koston
parent d27ec8ec49
commit 1d8423edd8
5 changed files with 87 additions and 19 deletions
+26 -14
View File
@@ -111,24 +111,36 @@ void ES8388::setup() {
// Power on ADC, Enable LIN&RIN, Power off MICBIAS, set int1lp to low power mode
ES8388_ERROR_FAILED(this->write_byte(ES8388_ADCPOWER, 0x09));
#ifdef USE_SELECT
#ifdef USE_ES8388_SELECT
if (this->dac_output_select_ != nullptr) {
auto dac_power = this->get_dac_power();
if (dac_power.has_value()) {
if (this->dac_output_select_->has_index(dac_power.value())) {
this->dac_output_select_->publish_state(dac_power.value());
} else {
ESP_LOGW(TAG, "Unknown DAC output power value: %d", dac_power.value());
if (this->dac_output_initial_.has_value()) {
const DacOutputLine line = this->dac_output_initial_.value();
ES8388_ERROR_FAILED(this->set_dac_output(line));
this->dac_output_select_->publish_state(static_cast<size_t>(line));
} else {
auto dac_power = this->get_dac_power();
if (dac_power.has_value()) {
if (this->dac_output_select_->has_index(dac_power.value())) {
this->dac_output_select_->publish_state(dac_power.value());
} else {
ESP_LOGW(TAG, "Unknown DAC output power value: %d", dac_power.value());
}
}
}
}
if (this->adc_input_mic_select_ != nullptr) {
auto mic_input = this->get_mic_input();
if (mic_input.has_value()) {
if (this->adc_input_mic_select_->has_index(mic_input.value())) {
this->adc_input_mic_select_->publish_state(mic_input.value());
} else {
ESP_LOGW(TAG, "Unknown ADC input mic value: %d", mic_input.value());
if (this->adc_input_mic_initial_.has_value()) {
const AdcInputMicLine line = this->adc_input_mic_initial_.value();
ES8388_ERROR_FAILED(this->set_adc_input_mic(line));
this->adc_input_mic_select_->publish_state(static_cast<size_t>(line));
} else {
auto mic_input = this->get_mic_input();
if (mic_input.has_value()) {
if (this->adc_input_mic_select_->has_index(mic_input.value())) {
this->adc_input_mic_select_->publish_state(mic_input.value());
} else {
ESP_LOGW(TAG, "Unknown ADC input mic value: %d", mic_input.value());
}
}
}
}
@@ -138,7 +150,7 @@ void ES8388::setup() {
void ES8388::dump_config() {
ESP_LOGCONFIG(TAG, "ES8388 Audio Codec:");
LOG_I2C_DEVICE(this);
#ifdef USE_SELECT
#ifdef USE_ES8388_SELECT
LOG_SELECT(" ", "DacOutputSelect", this->dac_output_select_);
LOG_SELECT(" ", "ADCInputMicSelect", this->adc_input_mic_select_);
#endif
+13 -2
View File
@@ -5,7 +5,7 @@
#include "esphome/components/audio_dac/audio_dac.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/core/component.h"
#ifdef USE_SELECT
#ifdef USE_ES8388_SELECT
#include "esphome/components/select/select.h"
#endif
@@ -26,7 +26,7 @@ enum AdcInputMicLine : uint8_t {
};
class ES8388 final : public audio_dac::AudioDac, public Component, public i2c::I2CDevice {
#ifdef USE_SELECT
#ifdef USE_ES8388_SELECT
SUB_SELECT(dac_output)
SUB_SELECT(adc_input_mic)
#endif
@@ -68,11 +68,22 @@ class ES8388 final : public audio_dac::AudioDac, public Component, public i2c::I
bool set_dac_output(DacOutputLine line);
bool set_adc_input_mic(AdcInputMicLine line);
#ifdef USE_ES8388_SELECT
/// Line to apply in setup() instead of keeping what the codec reports.
void set_dac_output_initial(DacOutputLine line) { this->dac_output_initial_ = line; }
void set_adc_input_mic_initial(AdcInputMicLine line) { this->adc_input_mic_initial_ = line; }
#endif
protected:
/// @brief Mutes or unmutes the DAC audio out
/// @param mute_state True to mute, false to unmute
/// @return True if successful and false otherwise
bool set_mute_state_(bool mute_state);
#ifdef USE_ES8388_SELECT
optional<DacOutputLine> dac_output_initial_{};
optional<AdcInputMicLine> adc_input_mic_initial_{};
#endif
};
} // namespace esphome::es8388
+43 -3
View File
@@ -1,7 +1,11 @@
import esphome.codegen as cg
from esphome.components import select
import esphome.config_validation as cv
from esphome.const import ENTITY_CATEGORY_CONFIG, ICON_CHIP # noqa: F401
from esphome.const import (
CONF_INITIAL_OPTION,
ENTITY_CATEGORY_CONFIG,
ICON_CHIP, # noqa: F401
)
from esphome.types import ConfigType
from ..audio_dac import CONF_ES8388_ID, ES8388, es8388_ns
@@ -9,6 +13,21 @@ from ..audio_dac import CONF_ES8388_ID, ES8388, es8388_ns
CONF_DAC_OUTPUT = "dac_output"
CONF_ADC_INPUT_MIC = "adc_input_mic"
DacOutputLine = es8388_ns.enum("DacOutputLine")
DAC_OUTPUT_OPTIONS = {
"LINE1": DacOutputLine.DAC_OUTPUT_LINE1,
"LINE2": DacOutputLine.DAC_OUTPUT_LINE2,
"BOTH": DacOutputLine.DAC_OUTPUT_BOTH,
}
DAC_OUTPUT_OPTION_NAMES = list(DAC_OUTPUT_OPTIONS)
AdcInputMicLine = es8388_ns.enum("AdcInputMicLine")
ADC_INPUT_MIC_OPTIONS = {
"LINE1": AdcInputMicLine.ADC_INPUT_MIC_LINE1,
"LINE2": AdcInputMicLine.ADC_INPUT_MIC_LINE2,
"DIFFERENCE": AdcInputMicLine.ADC_INPUT_MIC_DIFFERENCE,
}
ADC_INPUT_MIC_OPTION_NAMES = list(ADC_INPUT_MIC_OPTIONS)
DacOutputSelect = es8388_ns.class_("DacOutputSelect", select.Select)
ADCInputMicSelect = es8388_ns.class_("ADCInputMicSelect", select.Select)
@@ -19,24 +38,45 @@ CONFIG_SCHEMA = cv.All(
DacOutputSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_CHIP,
).extend(
{
cv.Optional(CONF_INITIAL_OPTION): cv.enum(
DAC_OUTPUT_OPTIONS, upper=True
),
}
),
cv.Optional(CONF_ADC_INPUT_MIC): select.select_schema(
ADCInputMicSelect,
entity_category=ENTITY_CATEGORY_CONFIG,
icon=ICON_CHIP,
).extend(
{
cv.Optional(CONF_INITIAL_OPTION): cv.enum(
ADC_INPUT_MIC_OPTIONS, upper=True
),
}
),
}
)
async def to_code(config: ConfigType) -> None:
cg.add_define("USE_ES8388_SELECT")
hub = await cg.get_variable(config[CONF_ES8388_ID])
selects = select.sub_selects(config, parent=hub)
await selects(
CONF_DAC_OUTPUT, hub.set_dac_output_select, options=["LINE1", "LINE2", "BOTH"]
CONF_DAC_OUTPUT, hub.set_dac_output_select, options=DAC_OUTPUT_OPTION_NAMES
)
await selects(
CONF_ADC_INPUT_MIC,
hub.set_adc_input_mic_select,
options=["LINE1", "LINE2", "DIFFERENCE"],
options=ADC_INPUT_MIC_OPTION_NAMES,
)
if (
initial := config.get(CONF_DAC_OUTPUT, {}).get(CONF_INITIAL_OPTION)
) is not None:
cg.add(hub.set_dac_output_initial(initial))
if (
initial := config.get(CONF_ADC_INPUT_MIC, {}).get(CONF_INITIAL_OPTION)
) is not None:
cg.add(hub.set_adc_input_mic_initial(initial))
+1
View File
@@ -72,6 +72,7 @@
#define USE_ENTITY_DEVICE_CLASS
#define USE_ENTITY_ICON
#define USE_ENTITY_UNIT_OF_MEASUREMENT
#define USE_ES8388_SELECT
#define USE_ESP32_BLE_PSRAM
#define USE_ESP32_CAMERA_JPEG_CONVERSION
#define USE_ESP32_HOSTED
+4
View File
@@ -17,5 +17,9 @@ select:
es8388_id: es8388_parent
dac_output:
name: "DAC Output"
id: es8388_test_dac_output_select
initial_option: BOTH
adc_input_mic:
name: "ADC Input MIC"
id: es8388_test_adc_input_mic_select
initial_option: LINE2