Files
kunlun/dtest/kl2_aec_test/es7210.c.bak
2024-09-28 14:24:04 +08:00

1114 lines
46 KiB
C
Raw Blame History

/*
* ES7210 adc driver
*
* Author: David Yang, <yangxiaohua@everest-semi.com>
* Copyright: (C) 2018 Everest Semiconductor Co Ltd.,
*
* Based on sound/soc/codecs/es7243.c by David Yang
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Notes:
* ES7210 is a 4-ch ADC of Everest
*
*
*/
#include "os_types.h"
#include "dbg_io.h"
#include "iot_io_api.h"
#include "es7210.h"
#define ENABLE 1
#define DISABLE 0
#define MIC_CHN_16 16
#define MIC_CHN_14 14
#define MIC_CHN_12 12
#define MIC_CHN_10 10
#define MIC_CHN_8 8
#define MIC_CHN_6 6
#define MIC_CHN_4 4
#define MIC_CHN_2 2
#define ES7210_TDM_ENABLE ENABLE
#define ES7210_CHANNELS_MAX MIC_CHN_8
#if ES7210_CHANNELS_MAX == MIC_CHN_2
#define ADC_DEV_MAXNUM 1
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_4
#define ADC_DEV_MAXNUM 1
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_6
#define ADC_DEV_MAXNUM 2
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_8
#define ADC_DEV_MAXNUM 2
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_10
#define ADC_DEV_MAXNUM 3
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_12
#define ADC_DEV_MAXNUM 3
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_14
#define ADC_DEV_MAXNUM 4
#endif
#if ES7210_CHANNELS_MAX == MIC_CHN_16
#define ADC_DEV_MAXNUM 4
#endif
#define ES7210_TDM_1LRCK_DSPA 0
#define ES7210_TDM_1LRCK_DSPB 1
#define ES7210_TDM_1LRCK_I2S 2
#define ES7210_TDM_1LRCK_LJ 3
#define ES7210_TDM_NLRCK_DSPA 4
#define ES7210_TDM_NLRCK_DSPB 5
#define ES7210_TDM_NLRCK_I2S 6
#define ES7210_TDM_NLRCK_LJ 7
#define ES7210_NORMAL_I2S 8
#define ES7210_NORMAL_LJ 9
#define ES7210_NORMAL_DSPA 10
#define ES7210_NORMAL_DSPB 11
#define SDP_16BIT_LENGTH 0
#define SDP_18BIT_LENGTH 1
#define SDP_20BIT_LENGTH 2
#define SDP_24BIT_LENGTH 3
#define SDP_32BIT_LENGTH 4
#define MASTER 0
#define SLAVE 1
#define ES7210_WORK_MODE_MASTER ES7210_TDM_1LRCK_I2S | (MASTER << 7) | (SDP_16BIT_LENGTH << 4)
#define ES7210_WORK_MODE_SLAVE ES7210_TDM_1LRCK_I2S | (SLAVE << 7) | (SDP_16BIT_LENGTH << 4)
#define CPU_I2S_MODE SLAVE
/* codec private data */
struct es7210_priv {
//uint32_t adc_num; // the number of ES7210 in tdm link
int mclk; //the frequency of MCLK clock
int lrck; // the frequency of LRCK clock
uint32_t tdm_mic_ch; //microphone number
uint32_t i2c_chip_id[ADC_DEV_MAXNUM]; // i2c address of es7210 devices
uint32_t tdm_mode[ADC_DEV_MAXNUM]; //tdm_mode[0] for adc0, tdm_mode[1] for adc1
//tdm_mode[2] for adc2, tdm_mode[3] for adc3
} ;
struct es7210_priv es7210_private;
/*
* clock coefficient structor
*/
struct _clock_coeff {
int32_t mclk; //the frequency on MCLK pad
int32_t lrck; //the frequency on LRCK pad
uint32_t ds_ss_speed; //double speed = 1, single speed = 0
uint32_t clk_adc_div; //clk_adc_div in register.bit[4:0]
uint32_t dll_bypass; // dll_bypass in register.bit7
uint32_t doubler_enable; //CLKDBL_VALID in register.bit6
uint32_t osr; //ADC_OSR in regisrer0x07
uint32_t mclk_sel; //MSTCLK_SRCSEL in register 0x03
uint32_t lrck_div_h; //M_LRCK_DIVH/DIVL in register0x4&0X05
uint32_t lrck_div_l;
};
static const struct _clock_coeff es7210_normal_clock_coeff[] = {
//mclk , lrck, ss_ds, clk_adc_div, dll_bypass, doubler_enable, osr, mclk_src, lrckh, lrckl
{12288000, 96000, 1, 1, 1, 1, 32, 0, 0x00, 0x80},
{12288000, 48000, 0, 1, 1, 1, 32, 0, 0x01, 0x00},
{12288000, 32000, 0, 3, 0, 0, 32, 0, 0x01, 0x80},
{12288000, 24000, 0, 1, 1, 0, 32, 0, 0x02, 0x00},
{12288000, 16000, 0, 3, 1, 1, 32, 0, 0x03, 0x00},
{12288000, 12000, 0, 2, 1, 0, 32, 0, 0x04, 0x00},
{12288000, 8000 , 0, 3, 1, 0, 32, 0, 0x06, 0x00},
{11298600, 88200, 1, 1, 1, 1, 32, 0, 0x00, 0x80},
{11298600, 44100, 0, 1, 1, 1, 32, 0, 0x01, 0x00},
{11298600, 22050, 0, 1, 1, 0, 32, 0, 0x02, 0x00},
{11298600, 11025, 0, 2, 1, 0, 32, 0, 0x04, 0x00},
{16384000, 64000, 1, 1, 1, 0, 32, 0, 0x01, 0x00},
{16384000, 32000, 0, 1, 1, 0, 32, 0, 0x02, 0x00},
{16384000, 16000, 0, 2, 1, 0, 32, 0, 0x04, 0x00},
{16384000, 8000 , 0, 4, 1, 0, 32, 0, 0x08, 0x00},
{19200000, 96000, 1, 5, 0, 1, 40, 0, 0x00, 0xc8},
{19200000, 64000, 0, 5, 0, 1, 30, 0, 0x01, 0x2c},
{19200000, 48000, 0, 5, 0, 1, 40, 0, 0x01, 0x90},
{19200000, 32000, 0, 5, 0, 0, 30, 0, 0x02, 0x58},
{19200000, 24000, 0, 10, 0, 1, 40, 0, 0x03, 0x20},
{19200000, 16000, 0, 10, 0, 0, 30, 0, 0x04, 0x80},
{19200000, 12000, 0, 20, 0, 1, 40, 0, 0x06, 0x40},
{19200000, 8000 , 0, 30, 0, 1, 40, 0, 0x09, 0x60},
{4096000 , 16000, 0, 1, 1, 1, 32, 0, 0x01, 0x00},
{4096000 , 8000 , 0, 1, 1, 0, 32, 0, 0x02, 0x00},
};
uint32_t coeff_div = sizeof(es7210_normal_clock_coeff) / sizeof(struct _clock_coeff);
/*
* default register configuration structor
*/
struct es7210_reg_config {
unsigned char reg_addr;
unsigned char reg_v;
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg1[] = {
{ 0x00, 0xFF },
{ 0x00, 0x32 },
{ 0x01, 0x21 },
{ 0x09, 0x30 },
{ 0x0A, 0x30 },
{ 0x23, 0x2A },
{ 0x22, 0x0A },
{ 0x21, 0x2A },
{ 0x20, 0x0A },
};
const struct es7210_reg_config es7210_tdm_reg_fmt_cfg[] = {
{ 0x11, 0x63 },
{ 0x12, 0x01 },
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg2[] = {
{ 0x40, 0xC3 },
{ 0x41, 0x70 },
{ 0x42, 0x70 },
{ 0x43, 0x1E },
{ 0x44, 0x1E },
{ 0x45, 0x1E },
{ 0x46, 0x1E },
{ 0x47, 0x08 },
{ 0x48, 0x08 },
{ 0x49, 0x08 },
{ 0x4A, 0x08 },
{ 0x07, 0x20 },
};
const struct es7210_reg_config es7210_tdm_reg_mclk_cfg[] = {
{ 0x02, 0xC1 },
};
static const struct es7210_reg_config es7210_tdm_reg_common_cfg3[] = {
{ 0x04, 0x01 },
{ 0x05, 0x00 },
{ 0x06, 0x04 },
{ 0x4B, 0x0F },
{ 0x4C, 0x0F },
{ 0x00, 0x71 },
{ 0x00, 0x41 },
};
/*
* es7210_read(), read the register of es7210
*
* uint32_t reg, the register address
* uint32_t *rt_value, the value of register
* uint32_t i2c_chip_addr, the i2c chip address of es7210 device
*
* return
* 0, success, 1, fail
*/
uint8_t i2c_master_recv(uint32_t addr, uint32_t reg, uint32_t *val, uint32_t);
static int es7210_read(uint32_t reg, uint32_t *rt_value, uint32_t i2c_chip_addr)
{
int8_t ret;
ret = i2c_master_recv(i2c_chip_addr, reg, rt_value, 1);
if (ret != 0) {
iot_printf("es7210_read error, ret = %d.\n", ret);
return 1;
}
return 0;
}
/*
* es7210_write(), write the register of es7210
*
* uint32_t reg, the register address
* uint32_t value, the value of register
* uint32_t i2c_chip_addr, the i2c chip address of es7210 device
*
* return
* 0, success, 1, fail
*/
uint8_t i2c_master_send(uint32_t addr, uint32_t reg, uint32_t val);
static int es7210_write(uint32_t reg, uint32_t value, uint32_t i2c_chip_addr)
{
int8_t ret = 0;
ret = i2c_master_send(i2c_chip_addr, reg, value);
if (ret != 0) {
iot_printf("es7210_write error->[REG-0x%02x,val-0x%02x]\n",reg,value);
return 1;
}
return 0;
}
/*
* es7210_update_bits(), update the specific bit of register
*
* uint32_t reg, the register address
* uint32_t mask, the mask of bitmap
* uint32_t value, the value of register
* uint32_t i2c_chip_addr, the i2c chip address of es7210 device
*
* return
* 0, success, 1, fail
*/
static int es7210_update_bits(uint32_t reg, uint32_t mask, uint32_t value, uint32_t i2c_chip_addr)
{
uint32_t val_old,val_new;
es7210_read(reg, &val_old, i2c_chip_addr);
val_new = (val_old & ~mask) | (value & mask);
if(val_new != val_old){
es7210_write(reg, val_new, i2c_chip_addr);
}
return 0;
}
/*
static int es7210_multi_chips_read(uint8_t reg, unsigned char *rt_value)
{
uint8_t i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_read(reg, rt_value++, i2c_clt1[i]);
}
return 0;
}
*/
/*
* es7210_multi_chips_write(), write the same of register address of multiple es7210 chips
*
* uint32_t reg, the register address
* uint32_t value, the value of register
*
* return
* 0, success, 1, fail
*/
static uint32_t es7210_multi_chips_write(uint8_t reg, uint8_t value)
{
uint8_t i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_write(reg, value, es7210_private.i2c_chip_id[i]);
}
return 0;
}
/*
* es7210_multi_chips_update_bits(), update the same of register bits of multiple es7210 chips
*
* uint32_t reg, the register address
* uint32_t value, the value of register
*
* return
* 0, success, 1, fail
*/
static int es7210_multi_chips_update_bits(uint8_t reg, uint8_t mask, uint8_t value)
{
uint8_t i;
for(i=0; i< ADC_DEV_MAXNUM; i++){
es7210_update_bits(reg, mask, value, es7210_private.i2c_chip_id[i]);
}
return 0;
}
/*
* es7210_mute(), set es7210 in mute or unmute
*
* uint32_t mute, = 1, mute
* = 0, unmute
* return
* 0, success, 1, fail
*/
static int es7210_mute(uint32_t mute)
{
iot_printf("enter into %s, mute = %d\n", __func__, mute);
if (mute) {
es7210_multi_chips_update_bits(ES7210_ADC34_MUTE_REG14, 0x03, 0x03);
es7210_multi_chips_update_bits(ES7210_ADC12_MUTE_REG15, 0x03, 0x03);
} else {
es7210_multi_chips_update_bits(ES7210_ADC34_MUTE_REG14, 0x03, 0x00);
es7210_multi_chips_update_bits(ES7210_ADC12_MUTE_REG15, 0x03, 0x00);
}
return 0;
}
/*
* es7210_micboost1_setting_set(), to set the mic gain for mic1
* es7210_micboost2_setting_set(), to set the mic gain for mic2
* es7210_micboost3_setting_set(), to set the mic gain for mic3
* es7210_micboost4_setting_set(), to set the mic gain for mic4
* es7210_micboost5_setting_set(), to set the mic gain for mic5
* es7210_micboost6_setting_set(), to set the mic gain for mic6
* es7210_micboost7_setting_set(), to set the mic gain for mic7
* es7210_micboost8_setting_set(), to set the mic gain for mic8
* es7210_micboost9_setting_set(), to set the mic gain for mic9
* es7210_micboost10_setting_set(), to set the mic gain for mic10
* es7210_micboost11_setting_set(), to set the mic gain for mic11
* es7210_micboost12_setting_set(), to set the mic gain for mic12
* es7210_micboost13_setting_set(), to set the mic gain for mic13
* es7210_micboost14_setting_set(), to set the mic gain for mic14
* es7210_micboost15_setting_set(), to set the mic gain for mic15
* es7210_micboost16_setting_set(), to set the mic gain for mic16
*
* uint32_t gain, the pag gain setting
* = 0, 0db
* = 1, 3db
* = 2, 6db
* = 3, 9db
* .........
* = 10, 30db
* = 11, 33db
* = 12, 34.5db
* = 13, 36db
* = 14, 37.5db
* return
* 0, success, 1, fail
*/
#if ES7210_CHANNELS_MAX > 0
int es7210_micboost1_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x43, 0x0F, gain, es7210_private.i2c_chip_id[0]);
return 0;
}
int es7210_micboost2_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x44, 0x0F, gain, es7210_private.i2c_chip_id[0]);
return 0;
}
int es7210_micboost3_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x45, 0x0F, gain, es7210_private.i2c_chip_id[0]);
return 0;
}
int es7210_micboost4_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x46, 0x0F, gain, es7210_private.i2c_chip_id[0]);
return 0;
}
#endif
#if ES7210_CHANNELS_MAX > 4
int es7210_micboost5_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x43, 0x0F, gain, es7210_private.i2c_chip_id[1]);
return 0;
}
int es7210_micboost6_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x44, 0x0F, gain, es7210_private.i2c_chip_id[1]);
return 0;
}
int es7210_micboost7_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x45, 0x0F, gain, es7210_private.i2c_chip_id[1]);
return 0;
}
int es7210_micboost8_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x46, 0x0F, gain, es7210_private.i2c_chip_id[1]);
return 0;
}
#endif
#if ES7210_CHANNELS_MAX > 8
static int es7210_micboost9_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x43, 0x0F, gain, es7210_private.i2c_chip_id[2]);
return 0;
}
static int es7210_micboost10_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x44, 0x0F, gain, es7210_private.i2c_chip_id[2]);
return 0;
}
static int es7210_micboost11_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x45, 0x0F, gain, es7210_private.i2c_chip_id[2]);
return 0;
}
static int es7210_micboost12_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x46, 0x0F, gain, es7210_private.i2c_chip_id[2]);
return 0;
}
#endif
#if ES7210_CHANNELS_MAX > 12
static int es7210_micboost13_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x43, 0x0F, gain, es7210_private.i2c_chip_id[3]);
return 0;
}
static int es7210_micboost14_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x44, 0x0F, gain, es7210_private.i2c_chip_id[3]);
return 0;
}
static int es7210_micboost15_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x45, 0x0F, gain, es7210_private.i2c_chip_id[3]);
return 0;
}
static int es7210_micboost16_setting_set(uint32_t gain)
{
if(gain > 14 ) gain = 14;
es7210_update_bits(0x46, 0x0F, gain, es7210_private.i2c_chip_id[3]);
return 0;
}
#endif
/*
* es7210_clock_ratio_set(), set clock divider to get the correct clock
*/
void es7210_clock_ratio_set(void)
{
uint32_t index, cnt, sclk_div, dat_len, ntimes;
int sclk_freq, lrck_freq;
int channel = ES7210_CHANNELS_MAX;
iot_printf("enter into %s\n", __func__);
/*
* lookup in the pll_coeff_div table, match the clk_in and sample_rate
*/
for (index = 0; index < coeff_div; index++) {
if (es7210_normal_clock_coeff[index].mclk == es7210_private.mclk &&
es7210_normal_clock_coeff[index].lrck == es7210_private.lrck)
break;
}
/*
* failed to get correct configuration, return.
*/
if(index == coeff_div) return;
/*
* mute dac to avoid noise
*/
es7210_mute(1);
/*
* set clock coefficient
*/
es7210_multi_chips_update_bits(ES7210_MCLK_CTL_REG02, 0x80,
(es7210_normal_clock_coeff[index].dll_bypass << 7));
es7210_multi_chips_update_bits(ES7210_MCLK_CTL_REG02, 0x40,
(es7210_normal_clock_coeff[index].doubler_enable << 6));
es7210_multi_chips_update_bits(ES7210_MCLK_CTL_REG02, 0x1f,
es7210_normal_clock_coeff[index].clk_adc_div);
es7210_multi_chips_update_bits(ES7210_ADC_OSR_REG07, 0x3f,
es7210_normal_clock_coeff[index].osr);
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0x02,
es7210_normal_clock_coeff[index].ds_ss_speed);
/*
* if there is a ES7210 deivce working in master mode in tdm link, you must set M_SCLK_DIV and M_LRCK_DIV
* You should pay more attention on TDM_NLRCK mode, because the M_LRCK_DIV is very different from others.
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if((es7210_private.tdm_mode[cnt] & 0x80) == 0) { //master mode
iot_printf("%s, there is a master chip in tdm link!!!!\n", __func__);
switch(es7210_private.tdm_mode[0] & 0x0f) {
case ES7210_TDM_NLRCK_DSPA:
case ES7210_TDM_NLRCK_DSPB:
case ES7210_TDM_NLRCK_I2S:
case ES7210_TDM_NLRCK_LJ:
switch(channel) {
case 2:
lrck_freq = es7210_private.lrck;
break;
case 4:
lrck_freq = es7210_private.lrck * 2;
break;
case 6:
lrck_freq = es7210_private.lrck * 3;
break;
case 8:
lrck_freq = es7210_private.lrck * 4;
break;
case 10:
lrck_freq = es7210_private.lrck * 5;
break;
case 12:
lrck_freq = es7210_private.lrck * 6;
break;
case 14:
lrck_freq = es7210_private.lrck * 7;
break;
case 16:
lrck_freq = es7210_private.lrck * 8;
break;
default:
lrck_freq = es7210_private.lrck;
break;
}
break;
default:
lrck_freq = es7210_private.lrck;
break;
}
iot_printf("%s, lrck_freq = %d\n", __func__, lrck_freq);
/*
* repeat to lookup in the coffiecient table with master lrck frequency
*/
for (index = 0; index < coeff_div; index++) {
if (es7210_normal_clock_coeff[index].mclk == es7210_private.mclk &&
es7210_normal_clock_coeff[index].lrck == lrck_freq)
break;
}
/*
* set M_LRCK DIV for the chip working in master mode
*/
es7210_update_bits(ES7210_MST_CLK_CTL_REG03, 0x80, (es7210_normal_clock_coeff[index].mclk_sel << 7),
es7210_private.i2c_chip_id[cnt]);
es7210_update_bits(ES7210_MST_LRCDIVH_REG04, 0x0f, es7210_normal_clock_coeff[index].lrck_div_h,
es7210_private.i2c_chip_id[cnt]);
es7210_update_bits(ES7210_MST_LRCDIVL_REG05, 0xff, es7210_normal_clock_coeff[index].lrck_div_l,
es7210_private.i2c_chip_id[cnt]);
/*
* set M_SCLK_DIV for the chip working in master mode
*/
dat_len = (es7210_private.tdm_mode[0] & 0x70) >> 4;
switch(dat_len) {
case SDP_16BIT_LENGTH:
ntimes = 16;
break;
case SDP_18BIT_LENGTH:
ntimes = 18;
break;
case SDP_20BIT_LENGTH:
ntimes = 20;
break;
case SDP_24BIT_LENGTH:
ntimes = 24;
break;
case SDP_32BIT_LENGTH:
ntimes = 32;
break;
default:
ntimes = 16;
break;
}
iot_printf("%s, ntimes = %d\n", __func__, ntimes);
switch(es7210_private.tdm_mode[0] & 0x0f) {
case ES7210_TDM_NLRCK_DSPA:
case ES7210_TDM_NLRCK_DSPB:
case ES7210_TDM_NLRCK_I2S:
case ES7210_TDM_NLRCK_LJ:
case ES7210_TDM_1LRCK_DSPA:
case ES7210_TDM_1LRCK_DSPB:
case ES7210_TDM_1LRCK_I2S:
case ES7210_TDM_1LRCK_LJ:
sclk_freq = ((int)es7210_private.tdm_mic_ch * (int)ntimes) * es7210_private.lrck;
break;
default:
sclk_freq = (2 * (int)ntimes) * es7210_private.lrck;
break;
}
iot_printf("%s, sclk_freq = %ld\n", __func__, sclk_freq);
sclk_div = (uint32_t) (es7210_private.mclk / sclk_freq);
iot_printf("%s, sclk_div = %d\n", __func__, sclk_div);
es7210_update_bits(ES7210_MST_CLK_CTL_REG03, 0x7f, sclk_div, es7210_private.i2c_chip_id[cnt]);
}
}
/*
* unmute dac
*/
es7210_mute(0);
}
/*
* es7210_init_codec(), to initialize es7210 for tdm mode or normal mode
*
*/
static void es7210_init_codec(void)
{
int cnt, channel;
uint32_t mode, len;
iot_printf("enter into %s\n", __func__);
for(cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg1)/sizeof(es7210_tdm_reg_common_cfg1[0]); cnt++) {
es7210_multi_chips_write(es7210_tdm_reg_common_cfg1[cnt].reg_addr,
es7210_tdm_reg_common_cfg1[cnt].reg_v);
}
/*
* set ES7210 in master or slave mode
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(es7210_private.tdm_mode[cnt] & 0x80) {
//slave mode
//es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x10, es7210_private.i2c_chip_id[cnt]);
} else {
//master mode
//es7210_multi_chips_write(ES7210_MODE_CFG_REG08, 0x11, es7210_private.i2c_chip_id[cnt]);
}
}
mode = es7210_private.tdm_mode[0] & 0x0f;
switch(mode) {
case ES7210_TDM_1LRCK_DSPA:
/*
* Here to set TDM format for DSP-A mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x03);
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x01);
break;
case ES7210_TDM_1LRCK_DSPB:
/*
* Here to set TDM format for DSP-B mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x013, 0x13);
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x01);
break;
case ES7210_TDM_1LRCK_I2S:
/*
* Here to set TDM format for I2S mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x00);
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x02);
break;
case ES7210_TDM_1LRCK_LJ:
/*
* Here to set TDM format for Left Justified mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x01);
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x02);
break;
case ES7210_TDM_NLRCK_DSPA:
/*
* Here to set TDM format for DSP-A with multiple LRCK TDM mode
*/
channel = ES7210_CHANNELS_MAX;
/*
* Set the microphone numbers in array
*/
switch(channel) {
case 2:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x10);
break;
case 4:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x20);
break;
case 6:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x30);
break;
case 8:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x40);
break;
case 10:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x50);
break;
case 12:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x60);
break;
case 14:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x70);
break;
case 16:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x80);
break;
default:
break;
}
/*
* set format, dsp-a with multiple LRCK tdm mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x03);
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(cnt == 0) {
/*
* set tdm flag in the interface chip
*/
es7210_write(ES7210_SDP_CFG2_REG12, 0x07, es7210_private.i2c_chip_id[cnt]);
} else {
es7210_write(ES7210_SDP_CFG2_REG12, 0x03, es7210_private.i2c_chip_id[cnt]);
}
}
break;
case ES7210_TDM_NLRCK_DSPB:
/*
* Here to set TDM format for DSP-B with multiple LRCK TDM mode
*/
channel = ES7210_CHANNELS_MAX;
/*
* Set the microphone numbers in array
*/
switch(channel) {
case 2:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x10);
break;
case 4:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x20);
break;
case 6:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x30);
break;
case 8:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x40);
break;
case 10:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x50);
break;
case 12:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x60);
break;
case 14:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x70);
break;
case 16:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x80);
break;
default:
break;
}
/*
* set format, dsp-b with multiple LRCK tdm mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x13, 0x13);
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(cnt == 0) {
/*
* set tdm flag in the interface chip
*/
es7210_write(ES7210_SDP_CFG2_REG12, 0x07, es7210_private.i2c_chip_id[cnt]);
} else {
es7210_write(ES7210_SDP_CFG2_REG12, 0x03, es7210_private.i2c_chip_id[cnt]);
}
}
break;
case ES7210_TDM_NLRCK_I2S:
/*
* Here to set TDM format for I2S with multiple LRCK TDM mode
*/
channel = ES7210_CHANNELS_MAX;
/*
* Set the microphone numbers in array
*/
switch(channel) {
case 2:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x10);
break;
case 4:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x20);
break;
case 6:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x30);
break;
case 8:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x40);
break;
case 10:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x50);
break;
case 12:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x60);
break;
case 14:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x70);
break;
case 16:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x80);
break;
default:
break;
}
/*
* set format, I2S with multiple LRCK tdm mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x00);
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(cnt == 0) {
/*
* set tdm flag in the interface chip
*/
es7210_write(ES7210_SDP_CFG2_REG12, 0x07, es7210_private.i2c_chip_id[cnt]);
} else {
es7210_write(ES7210_SDP_CFG2_REG12, 0x03, es7210_private.i2c_chip_id[cnt]);
}
}
break;
case ES7210_TDM_NLRCK_LJ:
/*
* Here to set TDM format for left justified with multiple LRCK TDM mode
*/
channel = ES7210_CHANNELS_MAX;
/*
* Set the microphone numbers in array
*/
switch(channel) {
case 2:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x10);
break;
case 4:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x20);
break;
case 6:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x30);
break;
case 8:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x40);
break;
case 10:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x50);
break;
case 12:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x60);
break;
case 14:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x70);
break;
case 16:
es7210_multi_chips_update_bits(ES7210_MODE_CFG_REG08, 0xf0, 0x80);
break;
default:
break;
}
/*
* set format, left justified with multiple LRCK tdm mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x01);
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(cnt == 0) {
/*
* set tdm flag in the interface chip
*/
es7210_write(ES7210_SDP_CFG2_REG12, 0x07, es7210_private.i2c_chip_id[cnt]);
} else {
es7210_write(ES7210_SDP_CFG2_REG12, 0x03, es7210_private.i2c_chip_id[cnt]);
}
}
break;
case ES7210_NORMAL_I2S:
/*
* here to disable tdm and set i2s-16bit for normal mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x00); //i2s
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x00); //disable tdm
case ES7210_NORMAL_LJ:
/*
* here to disable tdm and set i2s-16bit for normal mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x01); //lj
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x00); //disable tdm
case ES7210_NORMAL_DSPA:
/*
* here to disable tdm and set i2s-16bit for normal mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x03, 0x03); //dsp-a
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x00); //disable tdm
case ES7210_NORMAL_DSPB:
/*
* here to disable tdm and set i2s-16bit for normal mode
*/
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0x13, 0x13); //dsp-b
es7210_multi_chips_write(ES7210_SDP_CFG2_REG12, 0x00); //disable tdm
break;
}
/*
* set the data length
*/
len = (es7210_private.tdm_mode[0] & 0x70) >> 4;
switch(len) {
case SDP_16BIT_LENGTH:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x60);
break;
case SDP_18BIT_LENGTH:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x40);
break;
case SDP_20BIT_LENGTH:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x20);
break;
case SDP_24BIT_LENGTH:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x00);
break;
case SDP_32BIT_LENGTH:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x80);
break;
default:
es7210_multi_chips_update_bits(ES7210_SDP_CFG1_REG11, 0xe0, 0x60); // default for 16bit
break;
}
for(cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg2)/sizeof(es7210_tdm_reg_common_cfg2[0]); cnt++) {
es7210_multi_chips_write(es7210_tdm_reg_common_cfg2[cnt].reg_addr,
es7210_tdm_reg_common_cfg2[cnt].reg_v);
}
switch(mode) {
case ES7210_TDM_1LRCK_DSPA:
case ES7210_TDM_1LRCK_DSPB:
case ES7210_TDM_1LRCK_I2S:
case ES7210_TDM_1LRCK_LJ:
/*
* to set internal mclk
* here, we assume that cpu/soc always provides 256FS i2s clock to es7210.
* dll bypassed, use clock doubler to get double frequency for internal modem which need
* 512FS clock. the clk divider ratio is 1.
* user must modify the setting of register0x02 according to FS ratio provided by CPU/SOC.
*/
es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, 0xc1);
break;
case ES7210_TDM_NLRCK_DSPA:
case ES7210_TDM_NLRCK_DSPB:
case ES7210_TDM_NLRCK_I2S:
case ES7210_TDM_NLRCK_LJ:
/*
* to set internal mclk
* here, we assume that cpu/soc always provides 256FS i2s clock to es7210 and there is four
* es7210 devices in tdm link. so the internal FS in es7210 is only FS/4;
* dll bypassed, clock doubler bypassed. the clk divider ratio is 2. so the clock of internal
* modem equals to (256FS / (FS/4) / 2) * FS = 512FS
* user must modify the setting of register0x02 according to FS ratio provided by CPU/SOC.
*/
es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, 0x82);
break;
default:
/*
* to set internal mclk for normal mode
* here, we assume that cpu/soc always provides 256FS i2s clock to es7210.
* dll bypassed, use clock doubler to get double frequency for internal modem which need
* 512FS clock. the clk divider ratio is 1.
* user must modify the setting of register0x02 according to FS ratio provided by CPU/SOC.
*/
es7210_multi_chips_write(ES7210_MCLK_CTL_REG02, 0xc1);
break;
}
for(cnt = 0; cnt < sizeof(es7210_tdm_reg_common_cfg3)/sizeof(es7210_tdm_reg_common_cfg3[0]); cnt++) {
es7210_multi_chips_write(es7210_tdm_reg_common_cfg3[cnt].reg_addr,
es7210_tdm_reg_common_cfg3[cnt].reg_v);
}
/*
* set clock coefficient
*/
es7210_clock_ratio_set();
/*
* set ES7210 master reset control bits
*/
for(cnt = 0; cnt < ADC_DEV_MAXNUM; cnt++) {
if(es7210_private.tdm_mode[cnt] & 0x80) { //slave mode
es7210_update_bits(ES7210_RESET_CTL_REG00, 0x40, 0x40, es7210_private.i2c_chip_id[cnt]);
es7210_update_bits(ES7210_CLK_ON_OFF_REG01, 0x61, 0x20, es7210_private.i2c_chip_id[cnt]);
} else { //master mode
es7210_update_bits(ES7210_RESET_CTL_REG00, 0x40, 0x00, es7210_private.i2c_chip_id[cnt]);
es7210_update_bits(ES7210_CLK_ON_OFF_REG01, 0x61, 0x40, es7210_private.i2c_chip_id[cnt]);
}
}
}
/*
* es7210_startup(), power up initialization
*
* notes<65><73>
* in this routine, we should set i2c chip address and work mode for every es7210 device in tdm link.
* if the cpu i2s port is in slave mode, we set the es7210 device0 in i2s master mode as an i2s generator, others in slave mode.
*
* return 0, success
*
*/
int es7210_startup(void)
{
uint32_t cnt;
int lrck_freq;
for(cnt =0; cnt < ADC_DEV_MAXNUM; cnt++) {
es7210_private.i2c_chip_id[cnt] = 0x40 + cnt; // set i2c chip address
#if CPU_I2S_MODE > 0 // cpu i2s in slave mode
if(cnt == 0) { // es7210 device 0 in master mode, others es7210 in slave mode
es7210_private.tdm_mode[cnt] = ES7210_WORK_MODE_MASTER;
} else {
es7210_private.tdm_mode[cnt] = ES7210_WORK_MODE_SLAVE;
}
#endif
#if CPU_I2S_MODE == 0 //cpu i2s in master mode
es7210_private.tdm_mode[cnt] = ES7210_WORK_MODE_SLAVE; // es7210 devices all in slave mode
#endif
}
es7210_private.tdm_mic_ch = ES7210_CHANNELS_MAX;
es7210_private.mclk = 4096000; //mclk = 4.096MHz
lrck_freq = 16000; //lrck = 16kHz, here the frequency must equal to the clock frequency on LRCK pad
switch(es7210_private.tdm_mode[0] & 0x0f) {
case ES7210_TDM_NLRCK_DSPA:
case ES7210_TDM_NLRCK_DSPB:
case ES7210_TDM_NLRCK_I2S:
case ES7210_TDM_NLRCK_LJ:
switch(es7210_private.tdm_mic_ch) {
case 2:
es7210_private.lrck = lrck_freq;
break;
case 4:
es7210_private.lrck = lrck_freq / 2;
break;
case 6:
es7210_private.lrck = lrck_freq / 3;
break;
case 8:
es7210_private.lrck = lrck_freq / 4;
break;
case 10:
es7210_private.lrck = lrck_freq / 5;
break;
case 12:
es7210_private.lrck = lrck_freq / 6;
break;
case 14:
es7210_private.lrck = lrck_freq / 7;
break;
case 16:
es7210_private.lrck = lrck_freq / 8;
break;
default:
es7210_private.lrck = lrck_freq;
break;
}
break;
default:
es7210_private.lrck = lrck_freq;
break;
}
es7210_init_codec();
return 0;
}