123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Date Author Notes
- * 2019-07-31 Zero-Free first implementation
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #include "drv_es8388.h"
- /* ES8388 address */
- #define ES8388_ADDR 0x10 /*0x11:CE=1;0x10:CE=0*/
- struct es8388_device
- {
- struct rt_i2c_bus_device *i2c;
- rt_uint16_t pin;
- };
- static struct es8388_device es_dev = {0};
- static rt_uint16_t reg_read(rt_uint8_t addr)
- {
- struct rt_i2c_msg msg[2] = {0};
- rt_uint8_t val = 0xff;
- RT_ASSERT(es_dev.i2c != RT_NULL);
- msg[0].addr = ES8388_ADDR;
- msg[0].flags = RT_I2C_WR;
- msg[0].len = 1;
- msg[0].buf = &addr;
- msg[1].addr = ES8388_ADDR;
- msg[1].flags = RT_I2C_RD;
- msg[1].len = 1;
- msg[1].buf = &val;
- if (rt_i2c_transfer(es_dev.i2c, msg, 2) != 2)
- {
- rt_kprintf("I2C read data failed, reg = 0x%02x. \n", addr);
- return 0xff;
- }
- return val;
- }
- static void reg_write(rt_uint8_t addr, rt_uint8_t val)
- {
- struct rt_i2c_msg msgs[1] = {0};
- rt_uint8_t buff[2] = {0};
- RT_ASSERT(es_dev.i2c != RT_NULL);
- buff[0] = addr;
- buff[1] = val;
- msgs[0].addr = ES8388_ADDR;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = buff;
- msgs[0].len = 2;
- if (rt_i2c_transfer(es_dev.i2c, msgs, 1) != 1)
- {
- rt_kprintf("I2C write data failed, reg = 0x%2x. \n", addr);
- return;
- }
- }
- static int es8388_set_adc_dac_volume(int mode, int volume, int dot)
- {
- int res = 0;
- if (volume < -96 || volume > 0)
- {
- if (volume < -96)
- volume = -96;
- else
- volume = 0;
- }
- dot = (dot >= 5 ? 1 : 0);
- volume = (-volume << 1) + dot;
- if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
- {
- reg_write(ES8388_ADCCONTROL8, volume);
- reg_write(ES8388_ADCCONTROL9, volume); //ADC Right Volume=0db
- }
- if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
- {
- reg_write(ES8388_DACCONTROL5, volume);
- reg_write(ES8388_DACCONTROL4, volume);
- }
- return res;
- }
- void es8388_set_voice_mute(rt_bool_t enable)
- {
- rt_uint8_t reg = 0;
- reg = reg_read(ES8388_DACCONTROL3);
- reg = reg & 0xFB;
- reg_write(ES8388_DACCONTROL3, reg | (((int)enable) << 2));
- }
- rt_err_t es8388_init(const char *i2c_name, rt_uint16_t pin)
- {
- es_dev.i2c = rt_i2c_bus_device_find(i2c_name);
- if (es_dev.i2c == RT_NULL)
- {
- rt_kprintf("%s bus not found\n", i2c_name);
- return -RT_ERROR;
- }
- es_dev.pin = pin;
- reg_write(ES8388_DACCONTROL3, 0x04); // 0x04 mute/0x00 unmute&ramp;DAC unmute and disabled digital volume control soft ramp
- /* Chip Control and Power Management */
- reg_write(ES8388_CONTROL2, 0x50);
- reg_write(ES8388_CHIPPOWER, 0x00); //normal all and power up all
- reg_write(ES8388_MASTERMODE, 0x00); //TODO:CODEC IN I2S SLAVE MODE
- /* dac */
- reg_write(ES8388_DACPOWER, 0xC0); //disable DAC and disable Lout/Rout/1/2
- reg_write(ES8388_CONTROL1, 0x12); //Enfr=0,Play&Record Mode,(0x17-both of mic&paly)
- // reg_write(ES8388_CONTROL2, 0); //LPVrefBuf=0,Pdn_ana=0
- reg_write(ES8388_DACCONTROL1, 0x18);//1a 0x18:16bit iis , 0x00:24
- reg_write(ES8388_DACCONTROL2, 0x02); //DACFsMode,SINGLE SPEED; DACFsRatio,256
- reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
- reg_write(ES8388_DACCONTROL17, 0x9C); // only left DAC to left mixer enable 0db
- reg_write(ES8388_DACCONTROL20, 0x9C); // only right DAC to right mixer enable 0db
- reg_write(ES8388_DACCONTROL21, 0x80); //set internal ADC and DAC use the same LRCK clock, ADC LRCK as internal LRCK
- reg_write(ES8388_DACCONTROL23, 0x00); //vroi=0
- es8388_set_adc_dac_volume(ES_MODE_DAC, 0, 0); // 0db
- reg_write(ES8388_DACPOWER, 0x3c); //0x3c Enable DAC and Enable Lout/Rout/1/2
- /* adc */
- reg_write(ES8388_ADCPOWER, 0xFF);
- reg_write(ES8388_ADCCONTROL1, 0xbb); // MIC Left and Right channel PGA gain
- reg_write(ES8388_ADCCONTROL2, 0x00); //0x00 LINSEL & RINSEL, LIN1/RIN1 as ADC Input; DSSEL,use one DS Reg11; DSR, LINPUT1-RINPUT1
- reg_write(ES8388_ADCCONTROL3, 0x02);
- reg_write(ES8388_ADCCONTROL4, 0x0d); // Left/Right data, Left/Right justified mode, Bits length, I2S format
- reg_write(ES8388_ADCCONTROL5, 0x02); //ADCFsMode,singel SPEED,RATIO=256
- //ALC for Microphone
- es8388_set_adc_dac_volume(ES_MODE_ADC, 0, 0); // 0db
- reg_write(ES8388_ADCPOWER, 0x09); //Power on ADC, Enable LIN&RIN, Power off MICBIAS, set int1lp to low power mode
- /* enable es8388 PA */
- es8388_pa_power(RT_TRUE);
- reg_write(ES8388_DACCONTROL24, 0x1E); // LOUT1VOL balanced noise: 0x18
- reg_write(ES8388_DACCONTROL25, 0x1E); // ROUT1VOL balanced noise: 0x18
- return RT_EOK;
- }
- rt_err_t es8388_start(enum es8388_mode mode)
- {
- int res = 0;
- rt_uint8_t prev_data = 0, data = 0;
- prev_data = reg_read(ES8388_DACCONTROL21);
- if (mode == ES_MODE_LINE)
- {
- reg_write(ES8388_DACCONTROL16, 0x09); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2 by pass enable
- reg_write(ES8388_DACCONTROL17, 0x50); // left DAC to left mixer enable and LIN signal to left mixer enable 0db : bupass enable
- reg_write(ES8388_DACCONTROL20, 0x50); // right DAC to right mixer enable and LIN signal to right mixer enable 0db : bupass enable
- reg_write(ES8388_DACCONTROL21, 0xC0); //enable adc
- }
- else
- {
- reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
- }
- data = reg_read(ES8388_DACCONTROL21);
- if (prev_data != data)
- {
- reg_write(ES8388_CHIPPOWER, 0xF0); //start state machine
- // reg_write(ES8388_ADDR, ES8388_CONTROL1, 0x16);
- // reg_write(ES8388_ADDR, ES8388_CONTROL2, 0x50);
- reg_write(ES8388_CHIPPOWER, 0x00); //start state machine
- }
- if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
- {
- reg_write(ES8388_ADCPOWER, 0x00); //power up adc and line in
- }
- if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC || mode == ES_MODE_LINE)
- {
- reg_write(ES8388_DACPOWER, 0x3c); //power up dac and line out
- es8388_set_voice_mute(RT_FALSE);
- }
- return res;
- }
- rt_err_t es8388_stop(enum es8388_mode mode)
- {
- int res = 0;
- if (mode == ES_MODE_LINE)
- {
- reg_write(ES8388_DACCONTROL21, 0x80); //enable dac
- reg_write(ES8388_DACCONTROL16, 0x00); // 0x00 audio on LIN1&RIN1, 0x09 LIN2&RIN2
- reg_write(ES8388_DACCONTROL17, 0x90); // only left DAC to left mixer enable 0db
- reg_write(ES8388_DACCONTROL20, 0x90); // only right DAC to right mixer enable 0db
- return res;
- }
- if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
- {
- reg_write(ES8388_DACPOWER, 0x00);
- es8388_set_voice_mute(RT_TRUE); //res |= Es8388SetAdcDacVolume(ES_MODULE_DAC, -96, 5); // 0db
- // reg_write(ES8388_ADDR, ES8388_DACPOWER, 0xC0); //power down dac and line out
- }
- if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
- {
- // Es8388SetAdcDacVolume(ES_MODULE_ADC, -96, 5); // 0db
- reg_write(ES8388_ADCPOWER, 0xFF); //power down adc and line in
- }
- if (mode == ES_MODE_DAC_ADC)
- {
- reg_write(ES8388_DACCONTROL21, 0x9C); //disable mclk
- // reg_write(ES8388_CONTROL1, 0x00);
- // reg_write(ES8388_CONTROL2, 0x58);
- // reg_write(ES8388_CHIPPOWER, 0xF3); //stop state machine
- }
- return RT_EOK;
- }
- rt_err_t es8388_fmt_set(enum es8388_mode mode, enum es8388_format fmt)
- {
- rt_uint8_t reg = 0;
- if (mode == ES_MODE_ADC || mode == ES_MODE_DAC_ADC)
- {
- reg = reg_read(ES8388_ADCCONTROL4);
- reg = reg & 0xfc;
- reg_write(ES8388_ADCCONTROL4, reg | fmt);
- }
- if (mode == ES_MODE_DAC || mode == ES_MODE_DAC_ADC)
- {
- reg = reg_read(ES8388_DACCONTROL1);
- reg = reg & 0xf9;
- reg_write(ES8388_DACCONTROL1, reg | (fmt << 1));
- }
- return RT_EOK;
- }
- void es8388_volume_set(rt_uint8_t volume)
- {
- uint32_t real_vol = 0;
- volume = 100 - volume;
- if (volume > 100)
- volume = 100;
- real_vol = 192 * volume / 100;
- reg_write(ES8388_DACCONTROL4, (rt_uint8_t)real_vol); // DAC L
- reg_write(ES8388_DACCONTROL5, (rt_uint8_t)real_vol); // DAC R
- }
- rt_uint8_t es8388_volume_get(void)
- {
- rt_uint8_t volume;
- volume = reg_read(ES8388_DACCONTROL24);
- if (volume == 0xff)
- {
- volume = 0;
- }
- else
- {
- volume *= 3;
- if (volume == 99)
- volume = 100;
- }
- return volume;
- }
- void es8388_pa_power(rt_bool_t enable)
- {
- rt_pin_mode(es_dev.pin, PIN_MODE_OUTPUT);
- if (enable)
- {
- rt_pin_write(es_dev.pin, PIN_HIGH);
- }
- else
- {
- rt_pin_write(es_dev.pin, PIN_LOW);
- }
- }
- void estest()
- {
- // reg_write(ES8388_DACCONTROL24, volume);
- reg_write(ES8388_ADCCONTROL1, 0x88); /* R9,左右通道PGA增益设置 */
- reg_write(ES8388_ADCCONTROL2, 0x10); // 使用板载麦克风
- // reg_write(ES8388_ADCCONTROL2,0x50); // 使用耳机麦克风
- // reg_write(ES8388_ADCCONTROL3, 0xC0);
- reg_write(ES8388_ADCCONTROL8, 0x00); // LADCVOL
- reg_write(ES8388_ADCCONTROL9, 0x00); // RADCVOL
- reg_write(ES8388_DACCONTROL16, 0x1B); // LMIXSEL RMIXSEL
- reg_write(ES8388_DACCONTROL17, 0x40); // LI2LOVOL
- reg_write(ES8388_DACCONTROL24, 0x21); // LOUT1VOL
- reg_write(ES8388_DACCONTROL25, 0x21); // ROUT1VOL
- reg_write(ES8388_DACCONTROL24, 33); // LOUT1VOL balanced noise: 0x18
- reg_write(ES8388_DACCONTROL25, 33); // ROUT1VOL balanced noise: 0x18
- }
- MSH_CMD_EXPORT(estest, test mic loop)
|