/* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include #include "es8389_reg.h" #include "es8389_codec.h" #include "es_common.h" #include "esp_log.h" #define TAG "ES8389" typedef struct { audio_codec_if_t base; es8389_codec_cfg_t cfg; bool is_open; bool enabled; float hw_gain; bool use_mclk; } audio_codec_es8389_t; /* * Clock coefficient structure */ struct _coeff_div { uint16_t Ratio; uint32_t MCLK; uint32_t LRCK; uint8_t Reg0x04; uint8_t Reg0x05; uint8_t Reg0x06; uint8_t Reg0x07; uint8_t Reg0x08; uint8_t Reg0x09; uint8_t Reg0x0A; uint8_t Reg0x0F; uint8_t Reg0x11; uint8_t Reg0x21; uint8_t Reg0x22; uint8_t Reg0x26; uint8_t Reg0x30; uint8_t Reg0x41; uint8_t Reg0x42; uint8_t Reg0x43; uint8_t Reg0xF0; uint8_t Reg0xF1; uint8_t Reg0x16; uint8_t Reg0x18; uint8_t Reg0x19; }; /* codec hifi mclk clock divider coefficients */ static const struct _coeff_div coeff_div[] = { // Ratio Freq MCLK FreqLRCK,Reg0x04,Reg0x05,Reg0x06,Reg0x07,Reg0x08,Reg0x09,Reg0x0A,Reg0x0F,Reg0x11,Reg0x21,Reg0x22,Reg0x26,Reg0x30,Reg0x41,Reg0x42,Reg0x43,Reg0xF0,Reg0xF1,Reg0x16,Reg0x18,Reg0x19 {32 ,256000 ,8000 ,0x00 ,0x57 ,0x84 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {36 ,288000 ,8000 ,0x00 ,0x55 ,0x84 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {48 ,384000 ,8000 ,0x02 ,0x5F ,0x04 ,0xC0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {64 ,512000 ,8000 ,0x00 ,0x4D ,0x24 ,0xC0 ,0x03 ,0xD1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {72 ,576000 ,8000 ,0x00 ,0x45 ,0x24 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {96 ,768000 ,8000 ,0x02 ,0x57 ,0x84 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {128 ,1024000 ,8000 ,0x00 ,0x45 ,0x04 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {192 ,1536000 ,8000 ,0x02 ,0x4D ,0x24 ,0xC0 ,0x03 ,0xD1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {256 ,2048000 ,8000 ,0x01 ,0x45 ,0x04 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {288 ,2304000 ,8000 ,0x01 ,0x51 ,0x00 ,0xC0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {384 ,3072000 ,8000 ,0x02 ,0x45 ,0x04 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {512 ,4096000 ,8000 ,0x00 ,0x41 ,0x04 ,0xE0 ,0x00 ,0xD1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {768 ,6144000 ,8000 ,0x05 ,0x45 ,0x04 ,0xD0 ,0x03 ,0xC1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {1024 ,8192000 ,8000 ,0x01 ,0x41 ,0x06 ,0xE0 ,0x00 ,0xD1 ,0xB0 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {1536 ,12288000 ,8000 ,0x02 ,0x41 ,0x04 ,0xE0 ,0x00 ,0xD1 ,0xB0 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {1625 ,13000000 ,8000 ,0x40 ,0x6E ,0x05 ,0xC8 ,0x01 ,0xC2 ,0x90 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {2048 ,16384000 ,8000 ,0x03 ,0x44 ,0x01 ,0xC0 ,0x00 ,0xD2 ,0x80 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {2304 ,18432000 ,8000 ,0x11 ,0x45 ,0x25 ,0xF0 ,0x00 ,0xD1 ,0xB0 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {3072 ,24576000 ,8000 ,0x05 ,0x44 ,0x01 ,0xC0 ,0x00 ,0xD2 ,0x80 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {32 ,512000 ,16000 ,0x00 ,0x55 ,0x84 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {36 ,576000 ,16000 ,0x00 ,0x55 ,0x84 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {48 ,768000 ,16000 ,0x02 ,0x57 ,0x04 ,0xC0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {50 ,800000 ,16000 ,0x00 ,0x7E ,0x01 ,0xD9 ,0x00 ,0xC2 ,0x80 ,0x00 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {64 ,1024000 ,16000 ,0x00 ,0x45 ,0x24 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {72 ,1152000 ,16000 ,0x00 ,0x45 ,0x24 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {96 ,1536000 ,16000 ,0x02 ,0x55 ,0x84 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {128 ,2048000 ,16000 ,0x00 ,0x51 ,0x04 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {144 ,2304000 ,16000 ,0x00 ,0x51 ,0x00 ,0xC0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x23 ,0x8F ,0xB7 ,0xC0 ,0x1F ,0x8F ,0x01 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {192 ,3072000 ,16000 ,0x02 ,0x65 ,0x25 ,0xE0 ,0x00 ,0xE1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {256 ,4096000 ,16000 ,0x00 ,0x41 ,0x04 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {300 ,4800000 ,16000 ,0x02 ,0x66 ,0x01 ,0xD9 ,0x00 ,0xC2 ,0x80 ,0x00 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {384 ,6144000 ,16000 ,0x02 ,0x51 ,0x04 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {512 ,8192000 ,16000 ,0x01 ,0x41 ,0x04 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {750 ,12000000 ,16000 ,0x0E ,0x7E ,0x01 ,0xC9 ,0x00 ,0xC2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {768 ,12288000 ,16000 ,0x02 ,0x41 ,0x04 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1024 ,16384000 ,16000 ,0x03 ,0x41 ,0x04 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1152 ,18432000 ,16000 ,0x08 ,0x51 ,0x04 ,0xD0 ,0x01 ,0xC1 ,0x90 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1200 ,19200000 ,16000 ,0x0B ,0x66 ,0x01 ,0xD9 ,0x00 ,0xC2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1500 ,24000000 ,16000 ,0x0E ,0x26 ,0x01 ,0xD9 ,0x00 ,0xC2 ,0x80 ,0xC0 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1536 ,24576000 ,16000 ,0x05 ,0x41 ,0x04 ,0xC0 ,0x01 ,0xD1 ,0x90 ,0xC0 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0xFF ,0x7F ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {1625 ,26000000 ,16000 ,0x40 ,0x6E ,0x05 ,0xC8 ,0x01 ,0xC2 ,0x90 ,0xC0 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x12 ,0x31 ,0x0E}, {800 ,19200000 ,24000 ,0x07 ,0x66 ,0x01 ,0xD9 ,0x00 ,0xC2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0xC7 ,0x95 ,0x00 ,0x12 ,0x00 ,0x1A ,0x49 ,0x14}, {600 ,19200000 ,32000 ,0x05 ,0x46 ,0x01 ,0xD8 ,0x10 ,0xD2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x23 ,0x61 ,0x1B}, {32 ,1411200 ,44100 ,0x00 ,0x45 ,0xA4 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {64 ,2822400 ,44100 ,0x00 ,0x51 ,0x00 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {128 ,5644800 ,44100 ,0x00 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {256 ,11289600 ,44100 ,0x01 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {512 ,22579200 ,44100 ,0x03 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0xC0 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {32 ,1536000 ,48000 ,0x00 ,0x45 ,0xA4 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {48 ,2304000 ,48000 ,0x02 ,0x55 ,0x04 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {50 ,2400000 ,48000 ,0x00 ,0x76 ,0x01 ,0xC8 ,0x10 ,0xC2 ,0x80 ,0x00 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {64 ,3072000 ,48000 ,0x00 ,0x51 ,0x04 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {100 ,4800000 ,48000 ,0x00 ,0x46 ,0x01 ,0xD8 ,0x10 ,0xD2 ,0x80 ,0x00 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {125 ,6000000 ,48000 ,0x04 ,0x6E ,0x05 ,0xC8 ,0x10 ,0xC2 ,0x80 ,0x00 ,0x01 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {128 ,6144000 ,48000 ,0x00 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x00 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {200 ,9600000 ,48000 ,0x01 ,0x46 ,0x01 ,0xD8 ,0x10 ,0xD2 ,0x80 ,0x00 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {250 ,12000000 ,48000 ,0x04 ,0x76 ,0x01 ,0xC8 ,0x10 ,0xC2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {256 ,12288000 ,48000 ,0x01 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {384 ,18432000 ,48000 ,0x02 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x40 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {400 ,19200000 ,48000 ,0x03 ,0x46 ,0x01 ,0xD8 ,0x10 ,0xD2 ,0x80 ,0x40 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {500 ,24000000 ,48000 ,0x04 ,0x46 ,0x01 ,0xD8 ,0x10 ,0xD2 ,0x80 ,0xC0 ,0x00 ,0x18 ,0x95 ,0xD0 ,0xC0 ,0x63 ,0x95 ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {512 ,24576000 ,48000 ,0x03 ,0x41 ,0x04 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0xC0 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {800 ,38400000 ,48000 ,0x18 ,0x45 ,0x04 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0xC0 ,0x00 ,0x1F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x00 ,0x12 ,0x00 ,0x35 ,0x91 ,0x28}, {128 ,11289600 ,88200 ,0x00 ,0x50 ,0x00 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0x40 ,0x00 ,0x9F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x80 ,0x12 ,0xC0 ,0x32 ,0x89 ,0x25}, {64 ,6144000 ,96000 ,0x00 ,0x41 ,0x00 ,0xD0 ,0x10 ,0xD1 ,0x80 ,0x00 ,0x00 ,0x9F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x80 ,0x12 ,0xC0 ,0x35 ,0x91 ,0x28}, {256 ,24576000 ,96000 ,0x00 ,0x40 ,0x00 ,0xC0 ,0x10 ,0xC1 ,0x80 ,0xC0 ,0x00 ,0x9F ,0x7F ,0xBF ,0xC0 ,0x7F ,0x7F ,0x80 ,0x12 ,0xC0 ,0x35 ,0x91 ,0x28}, {128 ,24576000 ,192000 ,0x00 ,0x50 ,0x00 ,0xC0 ,0x18 ,0xC1 ,0x81 ,0xC0 ,0x00 ,0x8F ,0x7F ,0xEF ,0xC0 ,0x3F ,0x7F ,0x80 ,0x12 ,0xC0 ,0x3F ,0xF9 ,0x3F}, {50 ,400000 ,8000 ,0x00 ,0x75 ,0x05 ,0xC8 ,0x01 ,0xC1 ,0x90 ,0x10 ,0x00 ,0x18 ,0xC7 ,0xD0 ,0xC0 ,0x8F ,0xC7 ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {600 ,4800000 ,8000 ,0x05 ,0x65 ,0x25 ,0xF9 ,0x00 ,0xD1 ,0x90 ,0x10 ,0x00 ,0x18 ,0xC7 ,0xD0 ,0xC0 ,0x8F ,0xC7 ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {1500 ,12000000 ,8000 ,0x0E ,0x25 ,0x25 ,0xE8 ,0x00 ,0xD1 ,0x90 ,0x40 ,0x00 ,0x31 ,0xC7 ,0xC5 ,0x00 ,0x8F ,0xC7 ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {2400 ,19200000 ,8000 ,0x0B ,0x01 ,0x00 ,0xD0 ,0x00 ,0xD1 ,0x80 ,0x90 ,0x00 ,0x31 ,0xC7 ,0xC5 ,0x00 ,0xC7 ,0xC7 ,0x00 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {3000 ,24000000 ,8000 ,0x0E ,0x24 ,0x05 ,0xD0 ,0x00 ,0xC2 ,0x80 ,0xC0 ,0x00 ,0x31 ,0xC7 ,0xC5 ,0x00 ,0x8F ,0xC7 ,0x01 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, {3250 ,26000000 ,8000 ,0x40 ,0x05 ,0xA4 ,0xC0 ,0x00 ,0xD1 ,0x80 ,0xD0 ,0x00 ,0x31 ,0xC7 ,0xC5 ,0x00 ,0xC7 ,0xC7 ,0x00 ,0x12 ,0x00 ,0x09 ,0x19 ,0x07}, }; static const esp_codec_dev_vol_range_t vol_range = { .min_vol = { .vol = 0x0, .db_value = -95.5, }, .max_vol = { .vol = 0xFF, .db_value = 32.0, }, }; static int es8389_write_reg(audio_codec_es8389_t *codec, int reg, int value) { return codec->cfg.ctrl_if->write_reg(codec->cfg.ctrl_if, reg, 1, &value, 1); } static int es8389_read_reg(audio_codec_es8389_t *codec, int reg, int *value) { *value = 0; return codec->cfg.ctrl_if->read_reg(codec->cfg.ctrl_if, reg, 1, value, 1); } static int es8389_update_bits(audio_codec_es8389_t *codec, uint8_t reg_addr, uint8_t mask, uint8_t val) { int regval = 0; es8389_read_reg(codec, reg_addr, ®val); regval &= ~mask; regval |= (val & mask); return es8389_write_reg(codec, reg_addr, regval); } int es8389_set_bias_standby(audio_codec_es8389_t *codec) { int ret = es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, 0x03, 0x03); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0xD4); vTaskDelay(pdMS_TO_TICKS(70)); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x61, 0x59); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x64, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x03, 0x00); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x7E); ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, 0x03, 0x00); return ret; } int es8389_set_bias_on(audio_codec_es8389_t *codec) { int ret = es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x4D, 0x02); ret |= es8389_update_bits(codec, ES8389_ANALOG_CONTROL_REG0x69, 0x20, 0x20); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x61, 0xD9); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x64, 0x8F); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0xE4); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x01); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x03, 0xC3); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x24, 0x6A); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x25, (uint8_t)(0x0A + (0 << 6) + (0 << 5))); return ret; } static int es8389_config_fmt(audio_codec_es8389_t *codec, es_i2s_fmt_t fmt) { int ret = ESP_CODEC_DEV_OK; int state = 0 ; switch (fmt) { case ES_I2S_NORMAL: ESP_LOGD(TAG, "es8389 in I2S Format"); state |= ES8389_DAIFMT_I2S; ret |= es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x0C, 0xE0, 0x00); break; case ES_I2S_LEFT: case ES_I2S_RIGHT: ESP_LOGD(TAG, "es8389 in LJ Format"); state |= ES8389_DAIFMT_LEFT_J; ret |= es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x0C, 0xE0, 0x40); break; case ES_I2S_DSP: ESP_LOGD(TAG, "es8389 in DSP-A Format"); state |= ES8389_DAIFMT_DSP_A; ret |= es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x0C, 0xE0, 0x80); break; default: ESP_LOGD(TAG, "es8389 in DSP-B Format"); state |= ES8389_DAIFMT_DSP_B; ret |= es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x0C, 0xE0, 0xA0); break; } ret |= es8389_update_bits(codec, ES8389_ADC_SP_CONTROL_REG0x20, ES8389_MASK_DAIFMT, state); ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, ES8389_MASK_DAIFMT, state); return ret; } static int es8389_set_bits_per_sample(audio_codec_es8389_t *codec, int bits) { int ret = ESP_CODEC_DEV_OK; int state = 0 ; switch (bits) { case 16: default: state |= ES8389_S16_LE; break; case 18: state |= ES8389_S18_LE; break; case 20: state |= ES8389_S20_LE; break; case 24: state |= ES8389_S24_LE; break; case 32: state |= ES8389_S32_LE; break; } ret |= es8389_update_bits(codec, ES8389_ADC_SP_CONTROL_REG0x20, ES8389_MASK_DATALEN, state); ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, ES8389_MASK_DATALEN, state); return ret; } static int get_coeff(uint32_t mclk, uint32_t rate) { for (int i = 0; i < (sizeof(coeff_div) / sizeof(coeff_div[0])); i++) { if(coeff_div[i].Ratio == rate && coeff_div[i].MCLK == mclk) { return i; } } return ESP_CODEC_DEV_NOT_FOUND; } static int es8389_suspend(audio_codec_es8389_t *codec) { int ret = ESP_CODEC_DEV_OK; ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, 0x03, 0x03); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0xD4); vTaskDelay(pdMS_TO_TICKS(70)); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x61, 0x59); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x64, 0x00); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x63, 0x00); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x7E); ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x40, 0x03, 0x00); ret |= es8389_write_reg(codec, ES8389_MISC_CONTROL_REG0x01, 0x28); ret |= es8389_update_bits(codec, ES8389_ANALOG_CONTROL_REG0x69, 0x20, 0x00); ret |= es8389_write_reg(codec, ES8389_VMID_CONTROL_REG0x60, 0x00); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0xCC); vTaskDelay(pdMS_TO_TICKS(500)); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0x00); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x61, 0x08); ret |= es8389_write_reg(codec, ES8389_ISOLATION_CONTROL_REG0xF3, 0xC1); ret |= es8389_write_reg(codec, ES8389_PULL_DOWN_CONTROL_REG0xF2, 0x00); return ret; } static int es8389_start(audio_codec_es8389_t *codec) { int ret = ESP_CODEC_DEV_OK; ret |= es8389_set_bias_on(codec); return ret; } static int es8389_set_mute(const audio_codec_if_t *h, bool mute) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL || codec->is_open == false) { return ESP_CODEC_DEV_INVALID_ARG; } int regv; int ret = es8389_read_reg(codec, ES8389_ADC_SP_CONTROL_REG0x20, ®v); regv &= 0xFC; if (mute) { regv |= 0x03; } es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x20, regv); return ret; } static int es8389_set_vol(const audio_codec_if_t *h, float db_value) { int ret = ESP_CODEC_DEV_OK; audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open == false) { return ESP_CODEC_DEV_WRONG_STATE; } db_value -= codec->hw_gain; int reg = esp_codec_dev_vol_calc_reg(&vol_range, db_value); ESP_LOGD(TAG, "Set volume reg:%x db:%d", reg, (int) db_value); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x46, (uint8_t) reg); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x47, (uint8_t) reg); return ret; } static int es8389_set_mic_gain(const audio_codec_if_t *h, float db) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *)h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open == false) { return ESP_CODEC_DEV_WRONG_STATE; } es8389_mic_gain_t gain_db = ES8389_MIC_GAIN_0DB; if (db < 6) { gain_db = ES8389_MIC_GAIN_3_5DB; } else if (db < 9) { gain_db = ES8389_MIC_GAIN_6_5DB; } else if (db < 12) { gain_db = ES8389_MIC_GAIN_9_5DB; } else if (db < 15) { gain_db = ES8389_MIC_GAIN_12_5DB; } else if (db < 18) { gain_db = ES8389_MIC_GAIN_15_5DB; } else if (db < 21) { gain_db = ES8389_MIC_GAIN_18_5DB; } else if (db < 24) { gain_db = ES8389_MIC_GAIN_21_5DB; } else if (db < 27) { gain_db = ES8389_MIC_GAIN_24_5DB; } else if (db < 30) { gain_db = ES8389_MIC_GAIN_27_5DB; } else if (db < 33) { gain_db = ES8389_MIC_GAIN_30_5DB; } else if (db < 36) { gain_db = ES8389_MIC_GAIN_33_5DB; } else { gain_db = ES8389_MIC_GAIN_36_5DB; } int ret = es8389_write_reg(codec, ES8389_PGA1_GAIN_CONTROL_REG0x72, gain_db | (3 << 4)); // MIC gain scale return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_WRITE_FAIL; } static void es8389_pa_power(audio_codec_es8389_t *codec, es_pa_setting_t pa_setting) { int16_t pa_pin = codec->cfg.pa_pin; if (pa_pin == -1 || codec->cfg.gpio_if == NULL) { return; } if (pa_setting & ES_PA_SETUP) { codec->cfg.gpio_if->setup(pa_pin, AUDIO_GPIO_DIR_OUT, AUDIO_GPIO_MODE_FLOAT); } if (pa_setting & ES_PA_ENABLE) { codec->cfg.gpio_if->set(pa_pin, codec->cfg.pa_reverted ? false : true); } if (pa_setting & ES_PA_DISABLE) { codec->cfg.gpio_if->set(pa_pin, codec->cfg.pa_reverted ? true : false); } } static int es8389_config_sample(audio_codec_es8389_t *codec, int sample_rate, int bits) { int ret = ESP_CODEC_DEV_OK; int mclk_fre = sample_rate * bits * 2; int rate = mclk_fre / sample_rate; int coeff = get_coeff(mclk_fre, rate); if (coeff < 0) { ESP_LOGE(TAG, "Unable to configure sample rate %dHz with %dHz MCLK", sample_rate, mclk_fre); return ESP_CODEC_DEV_NOT_SUPPORT; } else { ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x04, coeff_div[coeff].Reg0x04); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x05, coeff_div[coeff].Reg0x05); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x06, coeff_div[coeff].Reg0x06); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x07, coeff_div[coeff].Reg0x07); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x08, coeff_div[coeff].Reg0x08); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x09, coeff_div[coeff].Reg0x09); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0A, coeff_div[coeff].Reg0x0A); ret |= es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x0F, 0xC0, coeff_div[coeff].Reg0x0F); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x11, coeff_div[coeff].Reg0x11); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x21, coeff_div[coeff].Reg0x21); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x22, coeff_div[coeff].Reg0x22); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x26, coeff_div[coeff].Reg0x26); ret |= es8389_update_bits(codec, 0x30, 0xC0, coeff_div[coeff].Reg0x30); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x41, coeff_div[coeff].Reg0x41); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x42, coeff_div[coeff].Reg0x42); ret |= es8389_update_bits(codec, ES8389_DAC_CONTROL_REG0x43, 0x81, coeff_div[coeff].Reg0x43); ret |= es8389_update_bits(codec, ES8389_CHIP_MISC_CONTROL_REG0xF0, 0x73, coeff_div[coeff].Reg0xF0); ret |= es8389_write_reg(codec, ES8389_CSM_STATE_REG0xF1, coeff_div[coeff].Reg0xF1); ret |= es8389_write_reg(codec, 0x16, coeff_div[coeff].Reg0x16); ret |= es8389_write_reg(codec, 0x18, coeff_div[coeff].Reg0x18); ret |= es8389_write_reg(codec, 0x19, coeff_div[coeff].Reg0x19); } return ret == 0 ? ESP_CODEC_DEV_OK : ESP_CODEC_DEV_WRITE_FAIL; } static int es8389_open(const audio_codec_if_t *h, void *cfg, int cfg_size) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *)h; es8389_codec_cfg_t *codec_cfg = (es8389_codec_cfg_t *)cfg; if (codec == NULL || codec_cfg == NULL || codec_cfg->ctrl_if == NULL || cfg_size != sizeof(es8389_codec_cfg_t)) { return ESP_CODEC_DEV_INVALID_ARG; } memcpy(&codec->cfg, cfg, sizeof(es8389_codec_cfg_t)); if (codec->cfg.mclk_div == 0) { codec->cfg.mclk_div = MCLK_DEFAULT_DIV; } int ret = ESP_CODEC_DEV_OK; ret |= es8389_write_reg(codec, ES8389_ISOLATION_CONTROL_REG0xF3, 0x00); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x7E); ret |= es8389_write_reg(codec, ES8389_ISOLATION_CONTROL_REG0xF3, 0x38); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x24, 0x64); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x25, (int)(0x04 + (0 << 6) + (0 << 5))); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x45, (int)(0x03 + (0 << 6) + (0 << 5))); ret |= es8389_write_reg(codec, ES8389_VMID_CONTROL_REG0x60, 0x2A); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x61, 0xC9); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x62, 0x4F); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x63, 0x06); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6B, 0x00); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6D, (int)(0x16 + (0 & 0xC0))); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6E, 0xAA); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6F, 0x66); ret |= es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x70, 0x99); if (ES8389_Analog_DriveSel == ES8389_DriveSel_LowPower) { es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6B, 0x80); es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x6C, 0x0F); es8389_write_reg(codec, ES8389_ANALOG_CONTROL_REG0x70, 0x66); } ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x23, (int)(0x00 + (0 & 0xC0) + (0 << 2) + (0 & 0x03))); ret |= es8389_write_reg(codec, ES8389_PGA1_GAIN_CONTROL_REG0x72, (int)((1 << 4) + 0)); ret |= es8389_write_reg(codec, ES8389_PGA1_GAIN_CONTROL_REG0x73, (int)((1 << 4) + 0)); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x10, 0xC4); ret |= es8389_write_reg(codec, ES8389_MISC_CONTROL_REG0x01, (int)(0x08 + (0 << 7) + (0 << 6) + (0 << 5) + (0 << 0))); ret |= es8389_write_reg(codec, ES8389_CSM_STATE_REG0xF1, 0x00); ret |= es8389_write_reg(codec, 0x12, 0x01); ret |= es8389_write_reg(codec, 0x13, 0x01); ret |= es8389_write_reg(codec, 0x14, 0x01); ret |= es8389_write_reg(codec, 0x15, 0x01); ret |= es8389_write_reg(codec, 0x16, 0x35); ret |= es8389_write_reg(codec, 0x17, 0x09); ret |= es8389_write_reg(codec, 0x18, 0x91); ret |= es8389_write_reg(codec, 0x19, 0x28); ret |= es8389_write_reg(codec, 0x1A, 0x01); ret |= es8389_write_reg(codec, 0x1B, 0x01); ret |= es8389_write_reg(codec, 0x1C, 0x11); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x2A, (int)(0x00 + (0 << 4))); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x20, (int)(0x00 + ES8389_S16_LE + (0 << 4) + ES8389_DAIFMT_I2S + (0 << 1) + (0 << 0))); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x40, (int)(0x00 + ES8389_S16_LE + (0 << 4) + ES8389_DAIFMT_I2S + (0 << 1) + (0 << 0))); ret |= es8389_write_reg(codec, ES8389_CHIP_MISC_CONTROL_REG0xF0, (int)(0x1 + (0 << 3) + (0 << 2))); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x02, (int)(0x00 + (0 << 6) + (0 << 1) + (0 << 0))); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x04, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x05, 0x10); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x06, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x07, 0xC0); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x08, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x09, 0xC0); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0A, 0x80); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0B, 4); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0C, (int)(256 >> 8)); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0D, (int)(256 & 0xFF)); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x0F, 0x10); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x21, 0x1F); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x22, 0x7F); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x2F, 0xC0); ret |= es8389_write_reg(codec, 0x30, 0xF4); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x31, (int)(0x00 + (0 << 7) + (0 << 6))); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x44, (int)(0x00 + (0 << 3) + (0 << 2) + (0 << 1) + (0 << 0))); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x41, 0x7F); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x42, 0x7F); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x43, 0x10); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x49, (int)(0x0F + (0 << 4))); ret |= es8389_write_reg(codec, 0x4C, 0xC0); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x00); ret |= es8389_write_reg(codec, ES8389_CLK_MANAGER_REG0x03, 0xC1); ret |= es8389_write_reg(codec, ES8389_RESET_REG0x00, 0x01); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x4D, 0x02); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x26, 191); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x27, 191); ret |= es8389_write_reg(codec, ES8389_ADC_SP_CONTROL_REG0x28, 191); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x46, 191); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x47, 191); ret |= es8389_write_reg(codec, ES8389_DAC_CONTROL_REG0x48, (int)(95 << 1)); if (codec_cfg->master_mode) { ESP_LOGI(TAG, "Work in Master mode"); es8389_update_bits(codec, ES8389_MISC_CONTROL_REG0x01, ES8389_MASK_MSModeSel, 1); } else { ESP_LOGI(TAG, "Work in Slave mode"); es8389_update_bits(codec, ES8389_MISC_CONTROL_REG0x01, ES8389_MASK_MSModeSel, 0); } // Select clock source for internal mclk if (codec_cfg->use_mclk) { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0xC0, 0 << 6); codec->use_mclk = true; } else { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0xC0, 1 << 6); codec->use_mclk = false; } // MCLK inverted or not if (codec_cfg->invert_mclk) { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0x02, 1 << 1); } else { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0x02, 0 << 1); } // Set ADC and DAC data format if (codec_cfg->no_dac_ref == false) { /* set internal reference signal (ADCL + DACR) */ ret |= es8389_write_reg(codec, ES8389_CHIP_MISC_CONTROL_REG0xF0, (int)(0x12 + (1 << 3) + (0 << 2))); ESP_LOGI(TAG, "Set internal reference signal"); } else { ret |= es8389_write_reg(codec, ES8389_CHIP_MISC_CONTROL_REG0xF0, (int)(0x12 + (0 << 3) + (0 << 2))); } // SCLK inverted or not if (codec_cfg->invert_sclk) { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0x01, 1 << 0); } else { es8389_update_bits(codec, ES8389_CLK_MANAGER_REG0x02, 0x01, 0 << 0); } if (ret != 0) { return ESP_CODEC_DEV_WRITE_FAIL; } es8389_pa_power(codec, ES_PA_SETUP | ES_PA_ENABLE); codec->is_open = true; return ESP_CODEC_DEV_OK; } static int es8389_close(const audio_codec_if_t *h) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open) { es8389_pa_power(codec, ES_PA_DISABLE); es8389_suspend(codec); codec->is_open = false; } return ESP_CODEC_DEV_OK; } static int es8389_set_fs(const audio_codec_if_t *h, esp_codec_dev_sample_info_t *fs) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL || codec->is_open == false) { return ESP_CODEC_DEV_INVALID_ARG; } if (!codec->use_mclk) { es8389_config_sample(codec, fs->sample_rate,fs->bits_per_sample); } es8389_set_bits_per_sample(codec, fs->bits_per_sample); es8389_config_fmt(codec, ES_I2S_NORMAL); es8389_set_bias_standby(codec); es8389_set_bias_on(codec); return ESP_CODEC_DEV_OK; } static int es8389_enable(const audio_codec_if_t *h, bool enable) { int ret = ESP_CODEC_DEV_OK; audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open == false) { return ESP_CODEC_DEV_WRONG_STATE; } if (enable == codec->enabled) { return ESP_CODEC_DEV_OK; } if (enable) { ret = es8389_start(codec); es8389_pa_power(codec, ES_PA_ENABLE); } else { es8389_pa_power(codec, ES_PA_DISABLE); ret = es8389_suspend(codec); } if (ret == ESP_CODEC_DEV_OK) { codec->enabled = enable; ESP_LOGD(TAG, "Codec is %s", enable ? "enabled" : "disabled"); } return ret; } static int es8389_set_reg(const audio_codec_if_t *h, int reg, int value) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open == false) { return ESP_CODEC_DEV_WRONG_STATE; } return es8389_write_reg(codec, reg, value); } static int es8389_get_reg(const audio_codec_if_t *h, int reg, int *value) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL) { return ESP_CODEC_DEV_INVALID_ARG; } if (codec->is_open == false) { return ESP_CODEC_DEV_WRONG_STATE; } return es8389_read_reg(codec, reg, value); } static void es8389_dump(const audio_codec_if_t *h) { audio_codec_es8389_t *codec = (audio_codec_es8389_t *) h; if (codec == NULL || codec->is_open == false) { return; } for (int i = 0; i < ES8389_MAX_REGISTER; i++) { int value = 0; int ret = es8389_read_reg(codec, i, &value); if (ret != ESP_CODEC_DEV_OK) { break; } ESP_LOGI(TAG, "%02x: %02x", i, value); } } const audio_codec_if_t *es8389_codec_new(es8389_codec_cfg_t *codec_cfg) { if (codec_cfg == NULL || codec_cfg->ctrl_if == NULL) { ESP_LOGE(TAG, "Wrong codec config"); return NULL; } if (codec_cfg->ctrl_if->is_open(codec_cfg->ctrl_if) == false) { ESP_LOGE(TAG, "Control interface not open yet"); return NULL; } audio_codec_es8389_t *codec = (audio_codec_es8389_t *) calloc(1, sizeof(audio_codec_es8389_t)); if (codec == NULL) { CODEC_MEM_CHECK(codec); return NULL; } codec->base.open = es8389_open; codec->base.enable = es8389_enable; codec->base.set_fs = es8389_set_fs; codec->base.set_vol = es8389_set_vol; codec->base.set_mic_gain = es8389_set_mic_gain; codec->base.mute = es8389_set_mute; codec->base.set_reg = es8389_set_reg; codec->base.get_reg = es8389_get_reg; codec->base.dump_reg = es8389_dump; codec->base.close = es8389_close; codec->hw_gain = esp_codec_dev_col_calc_hw_gain(&codec_cfg->hw_gain); do { int ret = codec->base.open(&codec->base, codec_cfg, sizeof(es8389_codec_cfg_t)); if (ret != 0) { ESP_LOGE(TAG, "Open fail"); break; } return &codec->base; } while (0); if (codec) { free(codec); } return NULL; }