• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <hi_types_base.h>
17 #include <hi_time.h>
18 #include <hi_i2c.h>
19 #include "es8311_codec.h"
20 
21 #define CODEC_DEBUG
22 #ifdef CODEC_DEBUG
23 #define codec_print(ftm...) do {printf(ftm);printf("\r\n");} while (0);
24 #else
25 #define codec_print(ftm...)
26 #endif
27 
codec_write_reg(hi_u8 reg,hi_u8 val)28 hi_u32 codec_write_reg(hi_u8 reg, hi_u8 val)
29 {
30     hi_i2c_data i2c_data;
31     hi_u8 send_data[2] = { reg, val }; /* size 2 */
32 
33     i2c_data.send_buf = send_data;
34     i2c_data.send_len = 2;             /* send_len is 2 */
35 
36     return hi_i2c_write(HI_I2C_IDX_1, CODEC_DEVICE_ADDR, &i2c_data);
37 }
38 
codec_read_reg(hi_u8 reg,hi_u8 * val)39 hi_u32 codec_read_reg(hi_u8 reg, hi_u8 *val)
40 {
41     hi_i2c_data i2c_data;
42 
43     i2c_data.send_buf = (hi_u8*)&reg;
44     i2c_data.send_len = 1;
45     i2c_data.receive_len = 1;
46     i2c_data.receive_buf = val;
47     return hi_i2c_writeread(HI_I2C_IDX_1, CODEC_DEVICE_ADDR, &i2c_data);
48 }
49 
codec_set_gain(hi_void)50 static hi_u32 codec_set_gain(hi_void)
51 {
52     hi_u32 ret = HI_ERR_SUCCESS;
53     /* set low or normal power mode */
54     ret |= codec_write_reg(ES8311_SYSTEM_REG0E, 0x02);  /* enable analog pga/adc modulator */
55     /* normal power mode */
56     ret |= codec_write_reg(ES8311_SYSTEM_REG0F, 0x44);
57     /* set adc */
58     ret |= codec_write_reg(ES8311_ADC_REG15, 0x40);     /* set softramp->00 */
59     ret |= codec_write_reg(ES8311_ADC_REG1B, 0x0A);     /* set adc hpf */
60     ret |= codec_write_reg(ES8311_ADC_REG1C, 0x6A);     /* set adc hpf,ADC_EQ bypass */
61     ret |= codec_write_reg(ES8311_ADC_REG17, 0xBF);     /* set adc digtal vol */
62     /* set dac */
63     ret |= codec_write_reg(ES8311_DAC_REG37, 0x48);     /* set dac softramp,disable DAC_EQ */
64     ret |= codec_write_reg(ES8311_DAC_REG32, 0xBF);
65 
66     /* only set adc alc funtion for amic record */
67     ret |= codec_write_reg(ES8311_ADC_REG16, 0x22);     /* set adc gain scale up */
68     ret |= codec_write_reg(ES8311_ADC_REG17, 0xDF);     /* set adc alc maxgain */
69     ret |= codec_write_reg(ES8311_ADC_REG18, 0x87);     /* adc alc enable,alc_winsize  ->00 */
70     ret |= codec_write_reg(ES8311_ADC_REG19, 0xFB);     /* set alc target level */
71     ret |= codec_write_reg(ES8311_ADC_REG1A, 0x03);     /* set adc_automute noise gate */
72     ret |= codec_write_reg(ES8311_ADC_REG1B, 0xEA);     /* set adc_automute vol */
73 
74     return ret;
75 }
76 
hi_codec_init(const hi_codec_attribute * codec_attr)77 hi_u32 hi_codec_init(const hi_codec_attribute *codec_attr)
78 {
79     if (codec_attr == HI_NULL) {
80         return HI_ERR_FAILURE;
81     }
82 
83     hi_u32 ret;
84 
85     /* set adc/dac data form */
86     codec_write_reg(ES8311_GPIO_REG44, 0x08);    /* adc to dac disable,ADCDATA=ADC(L)+ADC(R) */
87     hi_udelay(5000);  /* 5000us */
88 
89     ret = codec_write_reg(ES8311_DAC_REG31, 0x40);      /* mute DAC state machine */
90     ret |= codec_write_reg(ES8311_RESET_REG00, 0x1F);   /* Reset the clock and slave mode. */
91 
92     ret |= codec_write_reg(ES8311_GP_REG45, 0x00);      /* Pull up the BCLK/LRCK. */
93 
94     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG01, 0x30);     /* MCLK and BCLK are enabled. */
95 
96     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG02, 0x10);     /* Time required for completing AD/DA conversion: 0x10
97                                                                    dig_mclk = mclk_prediv*4 */
98 
99     if (codec_attr->sample_rate == HI_CODEC_SAMPLE_RATE_8K) {
100         ret |= codec_write_reg(ES8311_CLK_MANAGER_REG02, 0xA0);     /* 0 - dig_mclk=mclk_prediv*1 (default) */
101     } else if (codec_attr->sample_rate == HI_CODEC_SAMPLE_RATE_16K) {
102         ret |= codec_write_reg(ES8311_CLK_MANAGER_REG02, 0x40);     /* 0 - dig_mclk=mclk_prediv*1 (default) */
103     } else if (codec_attr->sample_rate == HI_CODEC_SAMPLE_RATE_32K) {
104         ret |= codec_write_reg(ES8311_CLK_MANAGER_REG02, 0x48);     /* 0 - dig_mclk=mclk_prediv*1 (default) */
105     } else if (codec_attr->sample_rate == HI_CODEC_SAMPLE_RATE_48K) {
106         ret |= codec_write_reg(ES8311_CLK_MANAGER_REG02, 0x00);     /* 0 - dig_mclk=mclk_prediv*1 (default) */
107     }
108 
109     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG03, 0x10);     /* 16 - 64 * fs(ss) / 32 * fs(ds) (default) */
110 
111     ret |= codec_write_reg(ES8311_ADC_REG16, 0x24);             /* ADC gain 4 - 24dB (default) */
112     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG04, 0x10);     /* DAC over sample rate : 16 - 64 * fs (default) */
113     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG05, 0x00);     /* Frequency division coefficient of the ADC and
114                                          DAC clocks, which determines the working frequencies of the ADC and DAC */
115 
116     ret |= codec_write_reg(ES8311_SYSTEM_REG0B, 0x00);  /* Determines the power-up duration. */
117     ret |= codec_write_reg(ES8311_SYSTEM_REG0C, 0x00);  /* Determines the power-up duration. */
118     ret |= codec_write_reg(ES8311_SYSTEM_REG10, 0x1F);  /* Bias setting */
119     ret |= codec_write_reg(ES8311_SYSTEM_REG11, 0x7F);  /* internal use */
120 
121     /*
122      * Set Codec in Slave mode
123      */
124     ret |= codec_write_reg(ES8311_RESET_REG00, 0x80);   /* csm power on */
125 
126     hi_udelay(50000);  /* 50000us */
127 
128     ret |= codec_write_reg(ES8311_SYSTEM_REG0D, 0x01);  /*  1 - start up vmid normal speed charge */
129     /*
130      * select clock source for internal mclk
131      */
132     ret |= codec_write_reg(ES8311_CLK_MANAGER_REG01, 0x3F);     /* Starts the sampling working clock. */
133 
134     /* Selects mic channel 1, select Mic1p-Mic1n ; ADC PGA gain:4 - 12dB */
135     ret |= codec_write_reg(ES8311_SYSTEM_REG14, 0x18);
136     /* set dac */
137     ret |= codec_write_reg(ES8311_SYSTEM_REG12, 0x00);  /*   0 - enable DAC */
138     /* enable HP drive */
139     ret |= codec_write_reg(ES8311_SYSTEM_REG13, 0x10);  /*  1 - enable output to HP drive */
140 
141     if ((codec_attr->resolution == HI_CODEC_RESOLUTION_16BIT)) {
142         /* set adc/dac data format */
143         ret |= codec_write_reg(ES8311_SDPIN_REG09, 0x0C);   /* set dac format=16bit i2s */
144         ret |= codec_write_reg(ES8311_SDPOUT_REG0A, 0x0C);  /* set adc format=16bit i2s */
145     } else {
146         /* set adc/dac data format */
147         ret |= codec_write_reg(ES8311_SDPIN_REG09, 0x00);   /* set dac format=24bit i2s */
148         ret |= codec_write_reg(ES8311_SDPOUT_REG0A, 0x00);  /* set adc format=24bit i2s */
149     }
150 
151     ret |= codec_set_gain();
152     ret |= codec_write_reg(ES8311_DAC_REG31, 0x00);     /* unmute DAC state machine */
153 
154     return ret;
155 }
156