diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py
index e9775d6969..6f01e3f04b 100644
--- a/esphome/components/logger/__init__.py
+++ b/esphome/components/logger/__init__.py
@@ -40,14 +40,11 @@ from esphome.components.libretiny.const import (
     COMPONENT_BK72XX,
     COMPONENT_RTL87XX,
 )
-from esphome.components.zephyr import zephyr_add_overlay, zephyr_add_prj_conf
-from esphome.components.zephyr_uart import zephyr_add_cdc_acm
-
-
-def AUTO_LOAD():
-    if CORE.using_zephyr:
-        return ["zephyr_uart"]
-    return []
+from esphome.components.zephyr import (
+    zephyr_add_overlay,
+    zephyr_add_prj_conf,
+    zephyr_add_cdc_acm,
+)
 
 
 CODEOWNERS = ["@esphome/core"]
diff --git a/esphome/components/zephyr/__init__.py b/esphome/components/zephyr/__init__.py
index dd63d56d57..0c687daabd 100644
--- a/esphome/components/zephyr/__init__.py
+++ b/esphome/components/zephyr/__init__.py
@@ -51,7 +51,7 @@ def zephyr_add_prj_conf(name: str, value: PrjConfValueType):
         old_value = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name]
         if old_value != value:
             raise ValueError(
-                f"{name} alread set with value {old_value}, new value {value}"
+                f"{name} already set with value '{old_value}', cannot set again to '{value}'"
             )
     CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF][name] = value
 
@@ -116,7 +116,8 @@ def zephyr_to_code(conf):
     zephyr_add_prj_conf("WDT_DISABLE_AT_BOOT", False)
     # disable console
     zephyr_add_prj_conf("UART_CONSOLE", False)
-    zephyr_add_prj_conf("CONSOLE", False)
+    # TODO disable when no OTA USB CDC
+    # zephyr_add_prj_conf("CONSOLE", False)
     # TODO debug only
     zephyr_add_prj_conf("DEBUG_THREAD_INFO", True)
     # zephyr_add_prj_conf("DEBUG", True)
@@ -152,6 +153,23 @@ def _format_prj_conf_val(value: PrjConfValueType) -> str:
     raise ValueError
 
 
+def zephyr_add_cdc_acm(config):
+    zephyr_add_prj_conf("USB_DEVICE_STACK", True)
+    zephyr_add_prj_conf("USB_CDC_ACM", True)
+    # prevent device to go to susspend, without this communication stop working in python
+    # there should be a way to solve it
+    zephyr_add_prj_conf("USB_DEVICE_REMOTE_WAKEUP", False)
+    zephyr_add_overlay(
+        """
+&zephyr_udc0 {
+    cdc_acm_uart0: cdc_acm_uart0 {
+        compatible = "zephyr,cdc-acm-uart";
+    };
+};
+"""
+    )
+
+
 # Called by writer.py
 def copy_files():
     want_opts = CORE.data[KEY_ZEPHYR][KEY_PRJ_CONF]
diff --git a/esphome/components/zephyr_mcumgr/ota/__init__.py b/esphome/components/zephyr_mcumgr/ota/__init__.py
index 4c5544ad93..9350266480 100644
--- a/esphome/components/zephyr_mcumgr/ota/__init__.py
+++ b/esphome/components/zephyr_mcumgr/ota/__init__.py
@@ -10,7 +10,11 @@ from esphome.const import (
 from esphome.core import CORE, coroutine_with_priority
 import esphome.final_validate as fv
 from esphome.components.zephyr.const import BOOTLOADER_MCUBOOT
-from esphome.components.zephyr import zephyr_add_prj_conf
+from esphome.components.zephyr import (
+    zephyr_add_prj_conf,
+    zephyr_add_cdc_acm,
+    zephyr_add_overlay,
+)
 
 AUTO_LOAD = ["zephyr_mcumgr"]
 
@@ -78,8 +82,6 @@ def _final_validate(config):
 
 FINAL_VALIDATE_SCHEMA = _final_validate
 
-# TODO cdc ota
-
 
 @coroutine_with_priority(50.0)
 async def to_code(config):
@@ -107,7 +109,6 @@ async def to_code(config):
     zephyr_add_prj_conf("MCUMGR_MGMT_NOTIFICATION_HOOKS", True)
     zephyr_add_prj_conf("MCUMGR_GRP_IMG_STATUS_HOOKS", True)
     zephyr_add_prj_conf("MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK", True)
-    # mcumgr ble
     if config[CONF_BLE]:
         zephyr_add_prj_conf("MCUMGR_TRANSPORT_BT", True)
         zephyr_add_prj_conf("MCUMGR_TRANSPORT_BT_REASSEMBLY", True)
@@ -116,3 +117,17 @@ async def to_code(config):
         zephyr_add_prj_conf("MCUMGR_GRP_OS_MCUMGR_PARAMS", True)
 
         zephyr_add_prj_conf("NCS_SAMPLE_MCUMGR_BT_OTA_DFU_SPEEDUP", True)
+    if config[CONF_USB_CDC]:
+        zephyr_add_cdc_acm(config)
+        zephyr_add_prj_conf("MCUMGR_TRANSPORT_UART", True)
+        zephyr_add_prj_conf("BASE64", True)
+        zephyr_add_prj_conf("CONSOLE", True)
+        zephyr_add_overlay(
+            """
+/ {
+    chosen {
+        zephyr,uart-mcumgr = &cdc_acm_uart0;
+    };
+};
+"""
+        )
diff --git a/esphome/components/zephyr_mcumgr/ota_zephyr_mcumgr.cpp b/esphome/components/zephyr_mcumgr/ota_zephyr_mcumgr.cpp
index 3169701544..582d851398 100644
--- a/esphome/components/zephyr_mcumgr/ota_zephyr_mcumgr.cpp
+++ b/esphome/components/zephyr_mcumgr/ota_zephyr_mcumgr.cpp
@@ -6,6 +6,7 @@
 #include <zephyr/mgmt/mcumgr/mgmt/callbacks.h>
 #include <zephyr/sys/math_extras.h>
 #include <zephyr/dfu/mcuboot.h>
+#include <zephyr/usb/usb_device.h>
 
 struct img_mgmt_upload_action {
   /** The total size of the image. */
@@ -54,7 +55,15 @@ OTAComponent::OTAComponent() {
 #endif
 }
 
-void OTAComponent::setup() { mgmt_callback_register(&IMG_MGMT_CALLBACK); }
+void OTAComponent::setup() {
+  mgmt_callback_register(&IMG_MGMT_CALLBACK);
+  // TODO check if ota cdc is set
+  // use zephyr,uart-mcumgr
+  auto uart_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(cdc_acm_uart0));
+  if (device_is_ready(uart_dev)) {
+    usb_enable(NULL);
+  }
+}
 
 void OTAComponent::loop() {
   if (!is_confirmed_) {
diff --git a/esphome/components/zephyr_uart/__init__.py b/esphome/components/zephyr_uart/__init__.py
deleted file mode 100644
index a57079ba25..0000000000
--- a/esphome/components/zephyr_uart/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from esphome.components.zephyr import zephyr_add_prj_conf, zephyr_add_overlay
-
-
-def zephyr_add_cdc_acm(config):
-    zephyr_add_prj_conf("USB_DEVICE_STACK", True)
-    zephyr_add_prj_conf("USB_CDC_ACM", True)
-    # prevent device to go to susspend, without this communication stop working in python
-    # there should be a way to solve it
-    zephyr_add_prj_conf("USB_DEVICE_REMOTE_WAKEUP", False)
-    zephyr_add_overlay(
-        """
-&zephyr_udc0 {
-    cdc_acm_uart0: cdc_acm_uart0 {
-        compatible = "zephyr,cdc-acm-uart";
-    };
-};
-"""
-    )
diff --git a/tests/test12.2.yaml b/tests/test12.2.yaml
index 5bfe0dbc4f..8efcb1e0a0 100644
--- a/tests/test12.2.yaml
+++ b/tests/test12.2.yaml
@@ -45,6 +45,7 @@ dfu:
 
 ota:
   - platform: zephyr_mcumgr
+    usb_cdc: True
     on_begin:
       then:
         - logger.log: "OTA start"