diff --git a/CODEOWNERS b/CODEOWNERS
index 56e20133ef..e2c674cfd3 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -133,6 +133,7 @@ esphome/components/ens160_i2c/* @latonita
 esphome/components/ens160_spi/* @latonita
 esphome/components/ens210/* @itn3rd77
 esphome/components/es7210/* @kahrendt
+esphome/components/es8156/* @kbx81
 esphome/components/es8311/* @kahrendt @kroimon
 esphome/components/esp32/* @esphome/core
 esphome/components/esp32_ble/* @Rapsssito @jesserockz
diff --git a/esphome/components/es8156/__init__.py b/esphome/components/es8156/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/esphome/components/es8156/audio_dac.py b/esphome/components/es8156/audio_dac.py
new file mode 100644
index 0000000000..b9d8eae6b0
--- /dev/null
+++ b/esphome/components/es8156/audio_dac.py
@@ -0,0 +1,27 @@
+import esphome.codegen as cg
+from esphome.components import i2c
+from esphome.components.audio_dac import AudioDac
+import esphome.config_validation as cv
+from esphome.const import CONF_ID
+
+CODEOWNERS = ["@kbx81"]
+DEPENDENCIES = ["i2c"]
+
+es8156_ns = cg.esphome_ns.namespace("es8156")
+ES8156 = es8156_ns.class_("ES8156", AudioDac, cg.Component, i2c.I2CDevice)
+
+CONFIG_SCHEMA = (
+    cv.Schema(
+        {
+            cv.GenerateID(): cv.declare_id(ES8156),
+        }
+    )
+    .extend(cv.COMPONENT_SCHEMA)
+    .extend(i2c.i2c_device_schema(0x08))
+)
+
+
+async def to_code(config):
+    var = cg.new_Pvariable(config[CONF_ID])
+    await cg.register_component(var, config)
+    await i2c.register_i2c_device(var, config)
diff --git a/esphome/components/es8156/es8156.cpp b/esphome/components/es8156/es8156.cpp
new file mode 100644
index 0000000000..62d35aa2d2
--- /dev/null
+++ b/esphome/components/es8156/es8156.cpp
@@ -0,0 +1,87 @@
+#include "es8156.h"
+#include "es8156_const.h"
+#include "esphome/core/hal.h"
+#include "esphome/core/log.h"
+#include <cinttypes>
+
+namespace esphome {
+namespace es8156 {
+
+static const char *const TAG = "es8156";
+
+// Mark the component as failed; use only in setup
+#define ES8156_ERROR_FAILED(func) \
+  if (!(func)) { \
+    this->mark_failed(); \
+    return; \
+  }
+
+void ES8156::setup() {
+  ESP_LOGCONFIG(TAG, "Setting up ES8156...");
+
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG02_SCLK_MODE, 0x04));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG20_ANALOG_SYS1, 0x2A));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG21_ANALOG_SYS2, 0x3C));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG22_ANALOG_SYS3, 0x00));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG24_ANALOG_LP, 0x07));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG23_ANALOG_SYS4, 0x00));
+
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0A_TIME_CONTROL1, 0x01));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0B_TIME_CONTROL2, 0x01));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG11_DAC_SDP, 0x00));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG19_EQ_CONTROL1, 0x20));
+
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG0D_P2S_CONTROL, 0x14));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG09_MISC_CONTROL2, 0x00));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG18_MISC_CONTROL3, 0x00));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG08_CLOCK_ON_OFF, 0x3F));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x02));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG00_RESET, 0x03));
+  ES8156_ERROR_FAILED(this->write_byte(ES8156_REG25_ANALOG_SYS5, 0x20));
+}
+
+void ES8156::dump_config() {
+  ESP_LOGCONFIG(TAG, "ES8156 Audio Codec:");
+
+  if (this->is_failed()) {
+    ESP_LOGCONFIG(TAG, "  Failed to initialize");
+    return;
+  }
+}
+
+bool ES8156::set_volume(float volume) {
+  volume = clamp(volume, 0.0f, 1.0f);
+  uint8_t reg = remap<uint8_t, float>(volume, 0.0f, 1.0f, 0, 255);
+  ESP_LOGV(TAG, "Setting ES8156_REG14_VOLUME_CONTROL to %u (volume: %f)", reg, volume);
+  return this->write_byte(ES8156_REG14_VOLUME_CONTROL, reg);
+}
+
+float ES8156::volume() {
+  uint8_t reg;
+  this->read_byte(ES8156_REG14_VOLUME_CONTROL, &reg);
+  return remap<float, uint8_t>(reg, 0, 255, 0.0f, 1.0f);
+}
+
+bool ES8156::set_mute_state_(bool mute_state) {
+  uint8_t reg13;
+
+  this->is_muted_ = mute_state;
+
+  if (!this->read_byte(ES8156_REG13_DAC_MUTE, &reg13)) {
+    return false;
+  }
+
+  ESP_LOGV(TAG, "Read ES8156_REG13_DAC_MUTE: %u", reg13);
+
+  if (mute_state) {
+    reg13 |= BIT(1) | BIT(2);
+  } else {
+    reg13 &= ~(BIT(1) | BIT(2));
+  }
+
+  ESP_LOGV(TAG, "Setting ES8156_REG13_DAC_MUTE to %u (muted: %s)", reg13, YESNO(mute_state));
+  return this->write_byte(ES8156_REG13_DAC_MUTE, reg13);
+}
+
+}  // namespace es8156
+}  // namespace esphome
diff --git a/esphome/components/es8156/es8156.h b/esphome/components/es8156/es8156.h
new file mode 100644
index 0000000000..e973599a7a
--- /dev/null
+++ b/esphome/components/es8156/es8156.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "esphome/components/audio_dac/audio_dac.h"
+#include "esphome/components/i2c/i2c.h"
+#include "esphome/core/component.h"
+
+namespace esphome {
+namespace es8156 {
+
+class ES8156 : public audio_dac::AudioDac, public Component, public i2c::I2CDevice {
+ public:
+  /////////////////////////
+  // Component overrides //
+  /////////////////////////
+
+  void setup() override;
+  float get_setup_priority() const override { return setup_priority::DATA; }
+  void dump_config() override;
+
+  ////////////////////////
+  // AudioDac overrides //
+  ////////////////////////
+
+  /// @brief Writes the volume out to the DAC
+  /// @param volume floating point between 0.0 and 1.0
+  /// @return True if successful and false otherwise
+  bool set_volume(float volume) override;
+
+  /// @brief Gets the current volume out from the DAC
+  /// @return floating point between 0.0 and 1.0
+  float volume() override;
+
+  /// @brief Disables mute for audio out
+  /// @return True if successful and false otherwise
+  bool set_mute_off() override { return this->set_mute_state_(false); }
+
+  /// @brief Enables mute for audio out
+  /// @return True if successful and false otherwise
+  bool set_mute_on() override { return this->set_mute_state_(true); }
+
+  bool is_muted() override { return this->is_muted_; }
+
+ 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);
+};
+
+}  // namespace es8156
+}  // namespace esphome
diff --git a/esphome/components/es8156/es8156_const.h b/esphome/components/es8156/es8156_const.h
new file mode 100644
index 0000000000..0bc8f89dd4
--- /dev/null
+++ b/esphome/components/es8156/es8156_const.h
@@ -0,0 +1,68 @@
+#pragma once
+
+#include "es8156.h"
+
+namespace esphome {
+namespace es8156 {
+
+/* ES8156 register addresses */
+/*
+ * RESET Control
+ */
+static const uint8_t ES8156_REG00_RESET = 0x00;
+/*
+ * Clock Managerment
+ */
+static const uint8_t ES8156_REG01_MAINCLOCK_CTL = 0x01;
+static const uint8_t ES8156_REG02_SCLK_MODE = 0x02;
+static const uint8_t ES8156_REG03_LRCLK_DIV_H = 0x03;
+static const uint8_t ES8156_REG04_LRCLK_DIV_L = 0x04;
+static const uint8_t ES8156_REG05_SCLK_DIV = 0x05;
+static const uint8_t ES8156_REG06_NFS_CONFIG = 0x06;
+static const uint8_t ES8156_REG07_MISC_CONTROL1 = 0x07;
+static const uint8_t ES8156_REG08_CLOCK_ON_OFF = 0x08;
+static const uint8_t ES8156_REG09_MISC_CONTROL2 = 0x09;
+static const uint8_t ES8156_REG0A_TIME_CONTROL1 = 0x0a;
+static const uint8_t ES8156_REG0B_TIME_CONTROL2 = 0x0b;
+/*
+ * System Control
+ */
+static const uint8_t ES8156_REG0C_CHIP_STATUS = 0x0c;
+static const uint8_t ES8156_REG0D_P2S_CONTROL = 0x0d;
+static const uint8_t ES8156_REG10_DAC_OSR_COUNTER = 0x10;
+/*
+ * SDP Control
+ */
+static const uint8_t ES8156_REG11_DAC_SDP = 0x11;
+static const uint8_t ES8156_REG12_AUTOMUTE_SET = 0x12;
+static const uint8_t ES8156_REG13_DAC_MUTE = 0x13;
+static const uint8_t ES8156_REG14_VOLUME_CONTROL = 0x14;
+
+/*
+ * ALC Control
+ */
+static const uint8_t ES8156_REG15_ALC_CONFIG1 = 0x15;
+static const uint8_t ES8156_REG16_ALC_CONFIG2 = 0x16;
+static const uint8_t ES8156_REG17_ALC_CONFIG3 = 0x17;
+static const uint8_t ES8156_REG18_MISC_CONTROL3 = 0x18;
+static const uint8_t ES8156_REG19_EQ_CONTROL1 = 0x19;
+static const uint8_t ES8156_REG1A_EQ_CONTROL2 = 0x1a;
+/*
+ * Analog System Control
+ */
+static const uint8_t ES8156_REG20_ANALOG_SYS1 = 0x20;
+static const uint8_t ES8156_REG21_ANALOG_SYS2 = 0x21;
+static const uint8_t ES8156_REG22_ANALOG_SYS3 = 0x22;
+static const uint8_t ES8156_REG23_ANALOG_SYS4 = 0x23;
+static const uint8_t ES8156_REG24_ANALOG_LP = 0x24;
+static const uint8_t ES8156_REG25_ANALOG_SYS5 = 0x25;
+/*
+ * Chip Information
+ */
+static const uint8_t ES8156_REGFC_I2C_PAGESEL = 0xFC;
+static const uint8_t ES8156_REGFD_CHIPID1 = 0xFD;
+static const uint8_t ES8156_REGFE_CHIPID0 = 0xFE;
+static const uint8_t ES8156_REGFF_CHIP_VERSION = 0xFF;
+
+}  // namespace es8156
+}  // namespace esphome
diff --git a/tests/components/es8156/common.yaml b/tests/components/es8156/common.yaml
new file mode 100644
index 0000000000..addaa0b70a
--- /dev/null
+++ b/tests/components/es8156/common.yaml
@@ -0,0 +1,15 @@
+esphome:
+  on_boot:
+    then:
+      - audio_dac.mute_off:
+      - audio_dac.mute_on:
+      - audio_dac.set_volume:
+          volume: 50%
+
+i2c:
+  - id: i2c_es8156
+    scl: ${scl_pin}
+    sda: ${sda_pin}
+
+audio_dac:
+  - platform: es8156
diff --git a/tests/components/es8156/test.esp32-ard.yaml b/tests/components/es8156/test.esp32-ard.yaml
new file mode 100644
index 0000000000..63c3bd6afd
--- /dev/null
+++ b/tests/components/es8156/test.esp32-ard.yaml
@@ -0,0 +1,5 @@
+substitutions:
+  scl_pin: GPIO16
+  sda_pin: GPIO17
+
+<<: !include common.yaml
diff --git a/tests/components/es8156/test.esp32-c3-ard.yaml b/tests/components/es8156/test.esp32-c3-ard.yaml
new file mode 100644
index 0000000000..ee2c29ca4e
--- /dev/null
+++ b/tests/components/es8156/test.esp32-c3-ard.yaml
@@ -0,0 +1,5 @@
+substitutions:
+  scl_pin: GPIO5
+  sda_pin: GPIO4
+
+<<: !include common.yaml
diff --git a/tests/components/es8156/test.esp32-c3-idf.yaml b/tests/components/es8156/test.esp32-c3-idf.yaml
new file mode 100644
index 0000000000..ee2c29ca4e
--- /dev/null
+++ b/tests/components/es8156/test.esp32-c3-idf.yaml
@@ -0,0 +1,5 @@
+substitutions:
+  scl_pin: GPIO5
+  sda_pin: GPIO4
+
+<<: !include common.yaml
diff --git a/tests/components/es8156/test.esp32-idf.yaml b/tests/components/es8156/test.esp32-idf.yaml
new file mode 100644
index 0000000000..63c3bd6afd
--- /dev/null
+++ b/tests/components/es8156/test.esp32-idf.yaml
@@ -0,0 +1,5 @@
+substitutions:
+  scl_pin: GPIO16
+  sda_pin: GPIO17
+
+<<: !include common.yaml
diff --git a/tests/components/es8156/test.esp8266-ard.yaml b/tests/components/es8156/test.esp8266-ard.yaml
new file mode 100644
index 0000000000..ee2c29ca4e
--- /dev/null
+++ b/tests/components/es8156/test.esp8266-ard.yaml
@@ -0,0 +1,5 @@
+substitutions:
+  scl_pin: GPIO5
+  sda_pin: GPIO4
+
+<<: !include common.yaml