diff --git a/flags/hfp.aconfig b/flags/hfp.aconfig
index ad97e98ec11e11d2c4c7f04632b917aa50789e45..8be4e6597c323ed78a5c7fc3881f18c282cee152 100644
--- a/flags/hfp.aconfig
+++ b/flags/hfp.aconfig
@@ -20,3 +20,10 @@ flag {
     description: "AptX Voice codec support for HFP calls"
     bug: "308497929"
 }
+
+flag {
+    name: "use_dsp_codec_when_controller_does_not_support"
+    namespace: "bluetooth"
+    description: "use codec on the DSP when the BT controller does not support it"
+    bug: "308838380"
+}
diff --git a/system/bta/Android.bp b/system/bta/Android.bp
index 3e00c2d364608ed4c3dad9b826aa093f190a36ec..4db637e75c9244372de57985aae734d82036fdb3 100644
--- a/system/bta/Android.bp
+++ b/system/bta/Android.bp
@@ -264,8 +264,10 @@ cc_test {
         "libcrypto",
         "libcutils",
         "liblog",
+        "server_configurable_flags",
     ],
     static_libs: [
+        "bluetooth_flags_c_lib",
         "libbase",
         "libbluetooth-types",
         "libbluetooth_crypto_toolbox",
diff --git a/system/btif/Android.bp b/system/btif/Android.bp
index 38a005777f6aa3dfdc7ddfd36b18e2b723661a69..6b9ad4f1d0786429d7bd4a19ce97829f38a60656 100644
--- a/system/btif/Android.bp
+++ b/system/btif/Android.bp
@@ -624,10 +624,12 @@ cc_test {
         "libhidlbase",
         "liblog",
         "libutils",
+        "server_configurable_flags",
     ],
     static_libs: [
         "android.hardware.bluetooth.a2dp@1.0",
         "avrcp-target-service",
+        "bluetooth_flags_c_lib",
         "lib-bt-packets",
         "lib-bt-packets-avrcp",
         "lib-bt-packets-base",
@@ -765,10 +767,12 @@ cc_test {
         "libhidlbase",
         "liblog",
         "libutils",
+        "server_configurable_flags",
     ],
     static_libs: [
         "android.hardware.bluetooth.a2dp@1.0",
         "avrcp-target-service",
+        "bluetooth_flags_c_lib",
         "lib-bt-packets",
         "lib-bt-packets-avrcp",
         "lib-bt-packets-base",
diff --git a/system/device/Android.bp b/system/device/Android.bp
index 81ab4295deecfb54bb1300a0e4890a53f27d10c5..5b6216d1836131c479f3b439a9f0d13ab80d7c6b 100644
--- a/system/device/Android.bp
+++ b/system/device/Android.bp
@@ -31,9 +31,18 @@ cc_library_static {
     apex_available: [
         "com.android.btservices",
     ],
+    generated_headers: [
+        "BluetoothGeneratedDumpsysDataSchema_h",
+    ],
     min_sdk_version: "Tiramisu",
     header_libs: ["libbluetooth_headers"],
-    static_libs: ["libbt_shim_bridge"],
+    static_libs: [
+        "bluetooth_flags_c_lib",
+        "libbluetooth_hci_pdl",
+        "libbt_shim_bridge",
+        "libflatbuffers-cpp",
+        "server_configurable_flags",
+    ],
 }
 
 // Bluetooth device unit tests for target
diff --git a/system/device/BUILD.gn b/system/device/BUILD.gn
index 8baad55f67351357743b318c269ef069ec220126..8b1ffd45d04e8b2e43cff763dab45c4d9ffa8446 100644
--- a/system/device/BUILD.gn
+++ b/system/device/BUILD.gn
@@ -36,6 +36,7 @@ static_library("device") {
   deps = [
     "//bt/system/gd/rust/shim:init_flags_bridge_header",
     "//bt/system/gd/rust/shim:libbluetooth_rust_interop",
+    "//bt/system/pdl:BluetoothGeneratedPackets_h",
   ]
 }
 
diff --git a/system/device/fuzzer/Android.bp b/system/device/fuzzer/Android.bp
index 4181de97ef10831657f8a3a7726301c5f23f66e5..35cf3d092dc1009c4b9388d04e11320b2a52810c 100644
--- a/system/device/fuzzer/Android.bp
+++ b/system/device/fuzzer/Android.bp
@@ -27,6 +27,7 @@ cc_fuzz {
     name: "btdevice_esco_fuzzer",
     defaults: ["fluoride_defaults"],
     srcs: [
+        ":TestMockMainShimEntry",
         "btdevice_esco_fuzzer.cpp",
     ],
     header_libs: [
@@ -35,20 +36,28 @@ cc_fuzz {
     shared_libs: [
         "libdl",
         "liblog",
+        "server_configurable_flags",
+    ],
+    generated_headers: [
+        "BluetoothGeneratedDumpsysDataSchema_h",
     ],
     static_libs: [
+        "bluetooth_flags_c_lib",
         "libbluetooth-types",
         "libbluetooth_gd",
+        "libbluetooth_hci_pdl",
         "libbt_shim_bridge",
         "libbt_shim_ffi",
         "libbtcore",
         "libbtdevice",
         "libchrome",
+        "libgmock",
         "libosi",
     ],
     include_dirs: [
         "packages/modules/Bluetooth/system",
         "packages/modules/Bluetooth/system/device/include",
+        "packages/modules/Bluetooth/system/gd",
     ],
     cflags: [
         "-DBUILDCFG",
diff --git a/system/device/src/esco_parameters.cc b/system/device/src/esco_parameters.cc
index 861dfd90ccd88308af4f969bcb3a84223eca6e7a..8f241dbce5c3308d2cf3ea8cc54d504364dab211 100644
--- a/system/device/src/esco_parameters.cc
+++ b/system/device/src/esco_parameters.cc
@@ -16,11 +16,14 @@
  *
  ******************************************************************************/
 
-#include "base/logging.h"
-
 #include "device/include/esco_parameters.h"
 
+#include <android_bluetooth_flags.h>
+
+#include "base/logging.h"
 #include "check.h"
+#include "hci/controller.h"
+#include "main/shim/entry.h"
 
 static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = {
     // CVSD D1
@@ -295,6 +298,29 @@ enh_esco_params_t esco_parameters_for_codec(esco_codec_t codec, bool offload) {
   CHECK(codec >= 0) << "codec index " << (int)codec << "< 0";
   CHECK(codec < ESCO_NUM_CODECS)
       << "codec index " << (int)codec << " > " << ESCO_NUM_CODECS;
+
+  std::vector<uint8_t> codecIds;
+  if (IS_FLAG_ENABLED(use_dsp_codec_when_controller_does_not_support)) {
+    auto controller = bluetooth::shim::GetController();
+    if (controller == nullptr) {
+      LOG_WARN("controller is null");
+    } else {
+      codecIds = controller->GetLocalSupportedBrEdrCodecIds();
+      if (std::find(codecIds.begin(), codecIds.end(), ESCO_CODING_FORMAT_LC3) ==
+          codecIds.end()) {
+        LOG_INFO("BT controller does not support LC3 codec, use DSP codec");
+        if (codec == ESCO_CODEC_LC3_T1 || codec == ESCO_CODEC_LC3_T2) {
+          enh_esco_params_t param = default_esco_parameters[codec];
+          param.input_coding_format.coding_format = ESCO_CODING_FORMAT_LC3;
+          param.output_coding_format.coding_format = ESCO_CODING_FORMAT_LC3;
+          param.input_bandwidth = TXRX_64KBITS_RATE;
+          param.output_bandwidth = TXRX_64KBITS_RATE;
+          return param;
+        }
+      }
+    }
+  }
+
   if (offload) {
     return default_esco_parameters[codec];
   }