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*)®
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