mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 08:55:36 +00:00
[pcm5122] Add analog gain, channel mixing, volume range, standby/powerdown switch, and XSMT enable pin support (#17313)
This commit is contained in:
@@ -5,6 +5,7 @@ from esphome.components.audio_dac import AudioDac
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_BITS_PER_SAMPLE,
|
||||
CONF_ENABLE_PIN,
|
||||
CONF_ID,
|
||||
CONF_INPUT,
|
||||
CONF_INVERTED,
|
||||
@@ -16,6 +17,11 @@ from esphome.const import (
|
||||
CODEOWNERS = ["@remcom"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
CONF_ANALOG_GAIN = "analog_gain"
|
||||
CONF_CHANNEL_MIX = "channel_mix"
|
||||
CONF_VOLUME_MIN_DB = "volume_min_db"
|
||||
CONF_VOLUME_MAX_DB = "volume_max_db"
|
||||
|
||||
pcm5122_ns = cg.esphome_ns.namespace("pcm5122")
|
||||
PCM5122 = pcm5122_ns.class_("PCM5122", AudioDac, cg.Component, i2c.I2CDevice)
|
||||
CONF_PCM5122 = "pcm5122"
|
||||
@@ -27,26 +33,60 @@ PCM5122_BITS_PER_SAMPLE_ENUM = {
|
||||
32: pcm5122_bits_per_sample.PCM5122_BITS_PER_SAMPLE_32,
|
||||
}
|
||||
|
||||
pcm5122_analog_gain = pcm5122_ns.enum("PCM5122AnalogGain")
|
||||
PCM5122_ANALOG_GAIN_ENUM = {
|
||||
"0db": pcm5122_analog_gain.PCM5122_ANALOG_GAIN_0DB,
|
||||
"-6db": pcm5122_analog_gain.PCM5122_ANALOG_GAIN_MINUS_6DB,
|
||||
}
|
||||
|
||||
pcm5122_channel_mix = pcm5122_ns.enum("PCM5122ChannelMix")
|
||||
PCM5122_CHANNEL_MIX_ENUM = {
|
||||
"stereo": pcm5122_channel_mix.PCM5122_CHANNEL_MIX_STEREO,
|
||||
"left": pcm5122_channel_mix.PCM5122_CHANNEL_MIX_LEFT_ONLY,
|
||||
"right": pcm5122_channel_mix.PCM5122_CHANNEL_MIX_RIGHT_ONLY,
|
||||
"swapped": pcm5122_channel_mix.PCM5122_CHANNEL_MIX_SWAPPED,
|
||||
}
|
||||
|
||||
_validate_bits = cv.float_with_unit("bits", "bit")
|
||||
|
||||
|
||||
def _validate_volume_range(config):
|
||||
if config[CONF_VOLUME_MIN_DB] >= config[CONF_VOLUME_MAX_DB]:
|
||||
raise cv.Invalid(f"{CONF_VOLUME_MIN_DB} must be less than {CONF_VOLUME_MAX_DB}")
|
||||
return config
|
||||
|
||||
|
||||
PCM5122GPIOPin = pcm5122_ns.class_(
|
||||
"PCM5122GPIOPin",
|
||||
cg.GPIOPin,
|
||||
cg.Parented.template(PCM5122),
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PCM5122),
|
||||
cv.Optional(CONF_BITS_PER_SAMPLE, default="16bit"): cv.All(
|
||||
_validate_bits, cv.enum(PCM5122_BITS_PER_SAMPLE_ENUM)
|
||||
),
|
||||
cv.Optional(CONF_ANALOG_GAIN, default="0db"): cv.enum(
|
||||
PCM5122_ANALOG_GAIN_ENUM, lower=True
|
||||
),
|
||||
cv.Optional(CONF_CHANNEL_MIX, default="stereo"): cv.enum(
|
||||
PCM5122_CHANNEL_MIX_ENUM, lower=True
|
||||
),
|
||||
cv.Optional(CONF_VOLUME_MIN_DB, default="-52.5dB"): cv.All(
|
||||
cv.decibel, cv.float_range(min=-103.0, max=24.0)
|
||||
),
|
||||
cv.Optional(CONF_VOLUME_MAX_DB, default="0dB"): cv.All(
|
||||
cv.decibel, cv.float_range(min=-103.0, max=24.0)
|
||||
),
|
||||
cv.Optional(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x4D))
|
||||
.extend(i2c.i2c_device_schema(0x4D)),
|
||||
_validate_volume_range,
|
||||
)
|
||||
|
||||
|
||||
@@ -96,3 +136,10 @@ async def to_code(config):
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
|
||||
cg.add(var.set_analog_gain(config[CONF_ANALOG_GAIN]))
|
||||
cg.add(var.set_channel_mix(config[CONF_CHANNEL_MIX]))
|
||||
cg.add(var.set_volume_min_db(config[CONF_VOLUME_MIN_DB]))
|
||||
cg.add(var.set_volume_max_db(config[CONF_VOLUME_MAX_DB]))
|
||||
if enable_pin_config := config.get(CONF_ENABLE_PIN):
|
||||
enable_pin = await cg.gpio_pin_expression(enable_pin_config)
|
||||
cg.add(var.set_enable_pin(enable_pin))
|
||||
|
||||
@@ -10,6 +10,12 @@ namespace esphome::pcm5122 {
|
||||
static const char *const TAG = "pcm5122";
|
||||
|
||||
void PCM5122::setup() {
|
||||
// Hold XSMT low (soft mute asserted) until init completes
|
||||
if (this->enable_pin_ != nullptr) {
|
||||
this->enable_pin_->setup();
|
||||
this->enable_pin_->digital_write(false);
|
||||
}
|
||||
|
||||
// Select page 0 and verify chip presence via I2C ACK
|
||||
if (!this->select_page_(0)) {
|
||||
ESP_LOGE(TAG, "Write failed");
|
||||
@@ -51,7 +57,22 @@ void PCM5122::setup() {
|
||||
}
|
||||
this->reg(PCM5122_REG_AUDIO_FORMAT) = PCM5122_AUDIO_FORMAT_I2S | alen;
|
||||
|
||||
if (!this->write_channel_mix_()) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this->write_analog_gain_()) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
// PLL reference clock: BCK
|
||||
if (!this->select_page_(0)) {
|
||||
ESP_LOGE(TAG, "Write failed");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
optional<uint8_t> pll_ref = this->read_byte(PCM5122_REG_PLL_REF);
|
||||
if (!pll_ref.has_value()) {
|
||||
ESP_LOGE(TAG, "Failed to read PLL_REF");
|
||||
@@ -67,15 +88,40 @@ void PCM5122::setup() {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
// Release XSMT (soft un-mute) now that init has completed
|
||||
if (this->enable_pin_ != nullptr) {
|
||||
this->enable_pin_->digital_write(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PCM5122::dump_config() {
|
||||
const char *channel_mix_str;
|
||||
switch (this->channel_mix_) {
|
||||
case PCM5122_CHANNEL_MIX_LEFT_ONLY:
|
||||
channel_mix_str = "left only";
|
||||
break;
|
||||
case PCM5122_CHANNEL_MIX_RIGHT_ONLY:
|
||||
channel_mix_str = "right only";
|
||||
break;
|
||||
case PCM5122_CHANNEL_MIX_SWAPPED:
|
||||
channel_mix_str = "swapped";
|
||||
break;
|
||||
default:
|
||||
channel_mix_str = "stereo";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, "Audio DAC:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
" Bits per sample: %u\n"
|
||||
" Analog gain: %s\n"
|
||||
" Channel mix: %s\n"
|
||||
" Volume range: %.1f dB to %.1f dB\n"
|
||||
" Muted: %s",
|
||||
this->bits_per_sample_, YESNO(this->is_muted_));
|
||||
this->bits_per_sample_, this->analog_gain_ == PCM5122_ANALOG_GAIN_0DB ? "0 dB" : "-6 dB",
|
||||
channel_mix_str, this->volume_min_db_, this->volume_max_db_, YESNO(this->is_muted_));
|
||||
LOG_PIN(" Enable Pin: ", this->enable_pin_);
|
||||
}
|
||||
|
||||
bool PCM5122::set_mute_off() {
|
||||
@@ -118,11 +164,11 @@ bool PCM5122::write_mute_() {
|
||||
}
|
||||
|
||||
bool PCM5122::write_volume_() {
|
||||
// DVOL register: 0x00 = +24 dB, 0x30 = 0 dB, 0xFF = mute (-0.5 dB/step).
|
||||
// Note: volume=0.0 maps to -52.5 dB (still audible), not true silence.
|
||||
// DVOL register: 0x00 = +24 dB, 0x30 = 0 dB, 0xFE = -103 dB, 0xFF = mute (-0.5 dB/step).
|
||||
// Note: volume=0.0 maps to volume_min_db_, which is not true silence unless set to -103 dB.
|
||||
// Use set_mute_on() for silence.
|
||||
const uint8_t dvol_max_volume = 0x30; // 0 dB at full scale
|
||||
const uint8_t dvol_min_volume = 0x99; // -52.5 dB at minimum
|
||||
const uint8_t dvol_max_volume = static_cast<uint8_t>(lroundf(0x30 - this->volume_max_db_ * 2.0f));
|
||||
const uint8_t dvol_min_volume = static_cast<uint8_t>(lroundf(0x30 - this->volume_min_db_ * 2.0f));
|
||||
|
||||
const uint8_t volume_byte =
|
||||
dvol_max_volume + static_cast<uint8_t>(lroundf((1.0f - this->volume_) * (dvol_min_volume - dvol_max_volume)));
|
||||
@@ -137,4 +183,52 @@ bool PCM5122::write_volume_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCM5122::write_analog_gain_() {
|
||||
uint8_t gain_byte = this->analog_gain_;
|
||||
if (!this->select_page_(1) || !this->write_byte(PCM5122_REG_ANALOG_GAIN, gain_byte)) {
|
||||
ESP_LOGE(TAG, "Writing analog gain failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCM5122::write_channel_mix_() {
|
||||
uint8_t channel_mix_byte = this->channel_mix_;
|
||||
if (!this->select_page_(0) || !this->write_byte(PCM5122_REG_DAC_DATA_PATH, channel_mix_byte)) {
|
||||
ESP_LOGE(TAG, "Writing channel mix failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCM5122::set_standby(bool enable) {
|
||||
bool prev_standby = this->standby_;
|
||||
this->standby_ = enable;
|
||||
if (!this->write_power_control_()) {
|
||||
this->standby_ = prev_standby;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCM5122::set_powerdown(bool enable) {
|
||||
bool prev_powerdown = this->powerdown_;
|
||||
this->powerdown_ = enable;
|
||||
if (!this->write_power_control_()) {
|
||||
this->powerdown_ = prev_powerdown;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PCM5122::write_power_control_() {
|
||||
uint8_t power_byte =
|
||||
(this->standby_ ? PCM5122_POWER_CONTROL_RQST : 0) | (this->powerdown_ ? PCM5122_POWER_CONTROL_RQPD : 0);
|
||||
if (!this->select_page_(0) || !this->write_byte(PCM5122_REG_POWER_CONTROL, power_byte)) {
|
||||
ESP_LOGE(TAG, "Writing power control failed");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace esphome::pcm5122
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "esphome/components/audio_dac/audio_dac.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/gpio.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome::pcm5122 {
|
||||
@@ -10,11 +11,13 @@ namespace esphome::pcm5122 {
|
||||
// Page 0 register addresses
|
||||
static const uint8_t PCM5122_REG_PAGE_SELECT = 0x00;
|
||||
static const uint8_t PCM5122_REG_RESET = 0x01;
|
||||
static const uint8_t PCM5122_REG_POWER_CONTROL = 0x02;
|
||||
static const uint8_t PCM5122_REG_MUTE = 0x03;
|
||||
static const uint8_t PCM5122_REG_GPIO_ENABLE = 0x08;
|
||||
static const uint8_t PCM5122_REG_PLL_REF = 0x0D;
|
||||
static const uint8_t PCM5122_REG_ERROR_DETECT = 0x25;
|
||||
static const uint8_t PCM5122_REG_AUDIO_FORMAT = 0x28;
|
||||
static const uint8_t PCM5122_REG_DAC_DATA_PATH = 0x2A;
|
||||
static const uint8_t PCM5122_REG_DVOL_LEFT = 0x3D;
|
||||
static const uint8_t PCM5122_REG_DVOL_RIGHT = 0x3E;
|
||||
static const uint8_t PCM5122_REG_GPIO_OUTPUT_SELECT = 0x50; // Base address; GPIO n uses offset n-1
|
||||
@@ -23,6 +26,9 @@ static const uint8_t PCM5122_REG_GPIO_OUTPUT = 0x56;
|
||||
static const uint8_t PCM5122_REG_GPIO_INVERT = 0x57;
|
||||
static const uint8_t PCM5122_REG_GPIO_INPUT = 0x77;
|
||||
|
||||
// Page 1 register addresses
|
||||
static const uint8_t PCM5122_REG_ANALOG_GAIN = 0x02;
|
||||
|
||||
// Register values for init sequence
|
||||
static const uint8_t PCM5122_RESET_MODULES = 0x10; // RSTM: reset audio modules
|
||||
static const uint8_t PCM5122_AUDIO_FORMAT_I2S = 0x00; // AFMT = I2S (bits [5:4] = 00)
|
||||
@@ -35,12 +41,33 @@ static const uint8_t PCM5122_ERROR_DETECT_DISABLE_DIV_AUTOSET = (1 << 1);
|
||||
static const uint8_t PCM5122_PLL_REF_MASK = (7 << 4); // SREF bits [6:4]
|
||||
static const uint8_t PCM5122_PLL_REF_SOURCE_BCK = (1 << 4); // SREF = 001 (BCK)
|
||||
|
||||
// Page 0, Register 2 (Power Control): RQST = standby request, RQPD = powerdown request (§10.5.3)
|
||||
static const uint8_t PCM5122_POWER_CONTROL_RQST = (1 << 4);
|
||||
static const uint8_t PCM5122_POWER_CONTROL_RQPD = (1 << 0);
|
||||
|
||||
// Page 1, Register 2 (Analog Gain Control): LAGN/RAGN select 0 dB or -6 dB analog gain (§8.3.5.5)
|
||||
static const uint8_t PCM5122_ANALOG_GAIN_LAGN = (1 << 4);
|
||||
static const uint8_t PCM5122_ANALOG_GAIN_RAGN = (1 << 0);
|
||||
|
||||
enum PCM5122BitsPerSample : uint8_t {
|
||||
PCM5122_BITS_PER_SAMPLE_16 = 16,
|
||||
PCM5122_BITS_PER_SAMPLE_24 = 24,
|
||||
PCM5122_BITS_PER_SAMPLE_32 = 32,
|
||||
};
|
||||
|
||||
enum PCM5122AnalogGain : uint8_t {
|
||||
PCM5122_ANALOG_GAIN_0DB = 0x00,
|
||||
PCM5122_ANALOG_GAIN_MINUS_6DB = PCM5122_ANALOG_GAIN_LAGN | PCM5122_ANALOG_GAIN_RAGN,
|
||||
};
|
||||
|
||||
// Page 0, Register 0x2A (DAC Data Path): AUPL/AUPR select which channel's data feeds each output (§7.4.2.42)
|
||||
enum PCM5122ChannelMix : uint8_t {
|
||||
PCM5122_CHANNEL_MIX_STEREO = 0x11, // Left data -> left out, right data -> right out
|
||||
PCM5122_CHANNEL_MIX_LEFT_ONLY = 0x12, // Left data -> both outputs
|
||||
PCM5122_CHANNEL_MIX_RIGHT_ONLY = 0x21, // Right data -> both outputs
|
||||
PCM5122_CHANNEL_MIX_SWAPPED = 0x22, // Left/right outputs swapped
|
||||
};
|
||||
|
||||
class PCM5122 final : public audio_dac::AudioDac, public Component, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
@@ -48,6 +75,11 @@ class PCM5122 final : public audio_dac::AudioDac, public Component, public i2c::
|
||||
float get_setup_priority() const override { return setup_priority::IO; }
|
||||
|
||||
void set_bits_per_sample(PCM5122BitsPerSample bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
|
||||
void set_analog_gain(PCM5122AnalogGain analog_gain) { this->analog_gain_ = analog_gain; }
|
||||
void set_channel_mix(PCM5122ChannelMix channel_mix) { this->channel_mix_ = channel_mix; }
|
||||
void set_volume_min_db(float volume_min_db) { this->volume_min_db_ = volume_min_db; }
|
||||
void set_volume_max_db(float volume_max_db) { this->volume_max_db_ = volume_max_db; }
|
||||
void set_enable_pin(GPIOPin *enable_pin) { this->enable_pin_ = enable_pin; }
|
||||
|
||||
bool set_mute_off() override;
|
||||
bool set_mute_on() override;
|
||||
@@ -56,17 +88,30 @@ class PCM5122 final : public audio_dac::AudioDac, public Component, public i2c::
|
||||
bool is_muted() override;
|
||||
float volume() override;
|
||||
|
||||
bool set_standby(bool enable);
|
||||
bool set_powerdown(bool enable);
|
||||
|
||||
friend class PCM5122GPIOPin;
|
||||
|
||||
protected:
|
||||
bool select_page_(uint8_t page);
|
||||
bool write_mute_();
|
||||
bool write_volume_();
|
||||
bool write_analog_gain_();
|
||||
bool write_channel_mix_();
|
||||
bool write_power_control_();
|
||||
|
||||
float volume_{1.0f}; // Matches chip post-reset DVOL default (0x30 = 0 dB)
|
||||
int16_t current_page_{-1}; // -1 = unknown; cached to skip redundant page-select writes
|
||||
GPIOPin *enable_pin_{nullptr};
|
||||
float volume_{1.0f}; // Matches chip post-reset DVOL default (0x30 = 0 dB)
|
||||
float volume_min_db_{-52.5f}; // Matches the previous hardcoded minimum (0x99)
|
||||
float volume_max_db_{0.0f}; // Matches the previous hardcoded maximum (0x30)
|
||||
int16_t current_page_{-1}; // -1 = unknown; cached to skip redundant page-select writes
|
||||
bool is_muted_{false};
|
||||
bool standby_{false};
|
||||
bool powerdown_{false};
|
||||
PCM5122BitsPerSample bits_per_sample_{PCM5122_BITS_PER_SAMPLE_16};
|
||||
PCM5122AnalogGain analog_gain_{PCM5122_ANALOG_GAIN_0DB};
|
||||
PCM5122ChannelMix channel_mix_{PCM5122_CHANNEL_MIX_STEREO};
|
||||
};
|
||||
|
||||
} // namespace esphome::pcm5122
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import switch
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_POWER_MODE, ENTITY_CATEGORY_CONFIG
|
||||
|
||||
from ..audio_dac import CONF_PCM5122, PCM5122, pcm5122_ns
|
||||
|
||||
PCM5122PowerSwitch = pcm5122_ns.class_("PCM5122PowerSwitch", switch.Switch)
|
||||
|
||||
pcm5122_power_switch_mode = pcm5122_ns.enum("PCM5122PowerSwitchMode")
|
||||
PCM5122_POWER_SWITCH_MODE_ENUM = {
|
||||
"standby": pcm5122_power_switch_mode.PCM5122_POWER_SWITCH_MODE_STANDBY,
|
||||
"powerdown": pcm5122_power_switch_mode.PCM5122_POWER_SWITCH_MODE_POWERDOWN,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = switch.switch_schema(
|
||||
PCM5122PowerSwitch,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(CONF_PCM5122): cv.use_id(PCM5122),
|
||||
cv.Optional(CONF_POWER_MODE, default="powerdown"): cv.enum(
|
||||
PCM5122_POWER_SWITCH_MODE_ENUM, lower=True
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = await switch.new_switch(config)
|
||||
await cg.register_parented(var, config[CONF_PCM5122])
|
||||
cg.add(var.set_power_mode(config[CONF_POWER_MODE]))
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "power_switch.h"
|
||||
|
||||
namespace esphome::pcm5122 {
|
||||
|
||||
void PCM5122PowerSwitch::write_state(bool state) {
|
||||
bool ok = (this->mode_ == PCM5122_POWER_SWITCH_MODE_STANDBY) ? this->parent_->set_standby(state)
|
||||
: this->parent_->set_powerdown(state);
|
||||
if (ok)
|
||||
this->publish_state(state);
|
||||
}
|
||||
|
||||
} // namespace esphome::pcm5122
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/switch/switch.h"
|
||||
|
||||
#include "../pcm5122.h"
|
||||
|
||||
namespace esphome::pcm5122 {
|
||||
|
||||
enum PCM5122PowerSwitchMode : uint8_t {
|
||||
PCM5122_POWER_SWITCH_MODE_STANDBY,
|
||||
PCM5122_POWER_SWITCH_MODE_POWERDOWN,
|
||||
};
|
||||
|
||||
class PCM5122PowerSwitch final : public switch_::Switch, public Parented<PCM5122> {
|
||||
public:
|
||||
void set_power_mode(PCM5122PowerSwitchMode mode) { this->mode_ = mode; }
|
||||
|
||||
protected:
|
||||
void write_state(bool state) override;
|
||||
|
||||
PCM5122PowerSwitchMode mode_{PCM5122_POWER_SWITCH_MODE_POWERDOWN};
|
||||
};
|
||||
|
||||
} // namespace esphome::pcm5122
|
||||
@@ -4,6 +4,11 @@ audio_dac:
|
||||
i2c_id: i2c_bus
|
||||
address: 0x4D
|
||||
bits_per_sample: 32bit
|
||||
analog_gain: -6db
|
||||
channel_mix: swapped
|
||||
volume_min_db: -60dB
|
||||
volume_max_db: -3dB
|
||||
enable_pin: GPIO12
|
||||
|
||||
output:
|
||||
- platform: gpio
|
||||
@@ -22,3 +27,9 @@ binary_sensor:
|
||||
number: 4
|
||||
mode:
|
||||
input: true
|
||||
|
||||
switch:
|
||||
- platform: pcm5122
|
||||
pcm5122: pcm5122_dac
|
||||
name: PCM5122 Power Down
|
||||
power_mode: powerdown
|
||||
|
||||
Reference in New Issue
Block a user