blob: 63b0f31d1fb50efdd9e62fccf0ba49124737fd65
1 | /* |
2 | * sound/soc/amlogic/auge/effect_hw_v2.c |
3 | * |
4 | * Copyright (C) 2018 Amlogic, Inc. All rights reserved. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | * more details. |
15 | * |
16 | */ |
17 | #include <linux/kernel.h> |
18 | |
19 | #include "effects_hw_v2.h" |
20 | #include "regs.h" |
21 | #include "iomap.h" |
22 | |
23 | #include "tdm_hw.h" |
24 | #include "spdif_hw.h" |
25 | |
26 | void aed_set_ram_coeff(int add, int len, unsigned int *params) |
27 | { |
28 | int i, ctrl_v; |
29 | unsigned int *p = params; |
30 | |
31 | for (i = 0; i < len; i++, p++) { |
32 | ctrl_v = ((add+i) << 2) | (0x1 << 1) | (0x1 << 0); |
33 | eqdrc_write(AED_COEF_RAM_DATA, *p); |
34 | eqdrc_write(AED_COEF_RAM_CNTL, ctrl_v); |
35 | } |
36 | } |
37 | |
38 | void aed_get_ram_coeff(int add, int len, unsigned int *params) |
39 | { |
40 | int i, ctrl_v; |
41 | unsigned int *p = params; |
42 | |
43 | for (i = 0; i < len; i++, p++) { |
44 | ctrl_v = ((add+i) << 2) | (0x0 << 1) | (0x1 << 0); |
45 | eqdrc_write(AED_COEF_RAM_CNTL, ctrl_v); |
46 | *p = eqdrc_read(AED_COEF_RAM_DATA); |
47 | //pr_info("%s, params[%d] = %8.8x\n", __func__, i, *p); |
48 | } |
49 | } |
50 | |
51 | void aed_set_multiband_drc_coeff(int len, int *params) |
52 | { |
53 | int band_len = len / 3, i, j; |
54 | int offset = AED_MDRC_RMS_COEF10 - AED_MDRC_RMS_COEF00; |
55 | int reg = AED_MDRC_RMS_COEF00; |
56 | |
57 | for (i = 0; i < 3; i++) |
58 | for (j = 0; j < band_len; j++) |
59 | eqdrc_write(reg + i * offset + j, |
60 | params[i * band_len + j]); |
61 | |
62 | eqdrc_write(AED_MDRC_THD0, 0xf6000000); |
63 | eqdrc_write(AED_MDRC_K0, 0x20000); |
64 | eqdrc_write(AED_MDRC_OFFSET0, 0x200); |
65 | eqdrc_write(AED_MDRC_LOW_GAIN, 0x40000); |
66 | |
67 | eqdrc_write(AED_MDRC_THD1, 0xfb000000); |
68 | eqdrc_write(AED_MDRC_K1, 0x26666); |
69 | eqdrc_write(AED_MDRC_OFFSET1, 0x200); |
70 | eqdrc_write(AED_MDRC_MID_GAIN, 0x40000); |
71 | |
72 | eqdrc_write(AED_MDRC_THD2, 0xf1000000); |
73 | eqdrc_write(AED_MDRC_K2, 0x2cccc); |
74 | eqdrc_write(AED_MDRC_OFFSET2, 0x200); |
75 | eqdrc_write(AED_MDRC_HIGH_GAIN, 0x40000); |
76 | } |
77 | |
78 | void aed_set_fullband_drc_coeff(int len, int *params) |
79 | { |
80 | int i; |
81 | |
82 | for (i = 0; i < len; i++) |
83 | eqdrc_write(AED_DRC_RELEASE_COEF00 + i, |
84 | params[i]); |
85 | |
86 | eqdrc_write(AED_DRC_RMS_COEF0, 0x34ebb); |
87 | eqdrc_write(AED_DRC_RMS_COEF1, 0x7cb145); |
88 | eqdrc_write(AED_DRC_THD0, 0xf7000000); |
89 | eqdrc_write(AED_DRC_THD1, 0xf6000000); |
90 | eqdrc_write(AED_DRC_THD2, 0xec000000); |
91 | eqdrc_write(AED_DRC_THD3, 0xe2000000); |
92 | eqdrc_write(AED_DRC_THD4, 0xce000000); |
93 | eqdrc_write(AED_DRC_K0, 0x20000); |
94 | eqdrc_write(AED_DRC_K1, 0x46666); |
95 | eqdrc_write(AED_DRC_K2, 0x40000); |
96 | eqdrc_write(AED_DRC_K3, 0x39999); |
97 | eqdrc_write(AED_DRC_K4, 0x33333); |
98 | eqdrc_write(AED_DRC_K5, 0x4cccc); |
99 | eqdrc_write(AED_DRC_THD_OUT0, 0xf5e66667); |
100 | eqdrc_write(AED_DRC_THD_OUT1, 0xebe66667); |
101 | eqdrc_write(AED_DRC_THD_OUT2, 0xe2e66667); |
102 | eqdrc_write(AED_DRC_THD_OUT3, 0xd2e66667); |
103 | eqdrc_write(AED_DRC_OFFSET, 0x100); |
104 | eqdrc_write(AED_DRC_LOOPBACK_CNTL, (144 << 0)); |
105 | } |
106 | |
107 | void aed_set_mixer_params(void) |
108 | { |
109 | eqdrc_write(AED_MIX0_LL, 0x40000); |
110 | eqdrc_write(AED_MIX0_RL, 0x0); |
111 | eqdrc_write(AED_MIX0_LR, 0x0); |
112 | eqdrc_write(AED_MIX0_RR, 0x40000); |
113 | eqdrc_write(AED_CLIP_THD, 0x7fffff); |
114 | } |
115 | |
116 | void aed_dc_enable(bool enable) |
117 | { |
118 | eqdrc_write(AED_DC_EN, enable << 0); |
119 | } |
120 | |
121 | void aed_nd_enable(bool enable) |
122 | { |
123 | if (enable) { |
124 | eqdrc_write(AED_ND_LOW_THD, 0x100); |
125 | eqdrc_write(AED_ND_HIGH_THD, 0x200); |
126 | eqdrc_write(AED_ND_CNT_THD, 0x100); |
127 | eqdrc_write(AED_ND_SUM_NUM, 0x200); |
128 | eqdrc_write(AED_ND_CZ_NUM, 0x800); |
129 | eqdrc_write(AED_ND_SUM_THD0, 0x20000); |
130 | eqdrc_write(AED_ND_SUM_THD1, 0x30000); |
131 | eqdrc_write(AED_ND_CZ_THD0, 0x200); |
132 | eqdrc_write(AED_ND_CZ_THD1, 0x100); |
133 | eqdrc_write(AED_ND_COND_CNTL, 0x3f); |
134 | eqdrc_write(AED_ND_RELEASE_COEF0, 0x3263a); |
135 | eqdrc_write(AED_ND_RELEASE_COEF1, 0x7cd9c6); |
136 | eqdrc_write(AED_ND_ATTACK_COEF0, 0x5188); |
137 | eqdrc_write(AED_ND_ATTACK_COEF1, 0x7fae78); |
138 | } |
139 | |
140 | eqdrc_write(AED_ND_CNTL, (enable << 0)|(3 << 1)); |
141 | } |
142 | |
143 | void aed_eq_enable(int idx, bool enable) |
144 | { |
145 | eqdrc_update_bits(AED_EQ_EN, 0x1 << idx, enable << idx); |
146 | } |
147 | |
148 | void aed_eq_taps(unsigned int eq1_taps) |
149 | { |
150 | if (eq1_taps > 20) { |
151 | pr_err("Error EQ1_Tap = %d\n", eq1_taps); |
152 | return; |
153 | } |
154 | eqdrc_update_bits(AED_EQ_TAP_CNTL, 0x1f, eq1_taps); |
155 | eqdrc_update_bits(AED_EQ_TAP_CNTL, 0x1f << 5, (20 - eq1_taps) << 5); |
156 | } |
157 | |
158 | void aed_multiband_drc_enable(bool enable) |
159 | { |
160 | eqdrc_write(AED_MDRC_CNTL, |
161 | (1 << 16) | /* mdrc_pow_sel */ |
162 | (enable << 8) | /* mdrc_all_en */ |
163 | (7 << 3) | /* mdrc_rms_mode[2:0] */ |
164 | (7 << 0) /* mdrc_en[2:0] */ |
165 | ); |
166 | } |
167 | |
168 | void aed_fullband_drc_enable(bool enable) |
169 | { |
170 | eqdrc_write(AED_DRC_CNTL, |
171 | (5 << 3) | /* drc_tap */ |
172 | (enable << 0) /* drc_en */ |
173 | ); |
174 | } |
175 | |
176 | void aed_set_volume( |
177 | unsigned int master_vol, |
178 | unsigned int Lch_vol, |
179 | unsigned int Rch_vol) |
180 | { |
181 | eqdrc_write(AED_EQ_VOLUME, |
182 | (0 << 30) | /* volume step: 0.125dB */ |
183 | (master_vol << 16) | /* master volume: 0dB */ |
184 | (Rch_vol << 8) | /* channel 2 volume: 0dB */ |
185 | (Lch_vol << 0) /* channel 1 volume: 0dB */ |
186 | ); |
187 | eqdrc_write(AED_EQ_VOLUME_SLEW_CNT, 0x2); /*40ms from -120dB~0dB*/ |
188 | eqdrc_write(AED_MUTE, 0); |
189 | } |
190 | |
191 | void aed_set_lane_and_channels(int lane_mask, int ch_mask) |
192 | { |
193 | int ch_num = 0, i = 0; |
194 | int val = ch_mask & 0xff; |
195 | |
196 | eqdrc_update_bits(AED_TOP_CTL, |
197 | 0xff << 18 | 0xf << 14, |
198 | ch_mask << 18 | lane_mask << 14); |
199 | |
200 | for (i = 0; i < 8; i++) { |
201 | if ((val & 0x1) == 0x1) |
202 | ch_num++; |
203 | val >>= 1; |
204 | } |
205 | |
206 | eqdrc_update_bits(AED_TOP_REQ_CTL, |
207 | 0xff << 12, (ch_num - 1) << 12); |
208 | } |
209 | |
210 | void aed_set_ctrl(bool enable, int sel, enum frddr_dest module) |
211 | { |
212 | int mask = 0, val = 0; |
213 | |
214 | switch (sel) { |
215 | case 0: /* REQ_SEL0 */ |
216 | mask = 0xf << 0; |
217 | val = 0x1 << 3 | module << 0; |
218 | break; |
219 | case 1: /* REQ_SEL1 */ |
220 | mask = 0xf << 4; |
221 | val = 0x1 << 7 | module << 4; |
222 | break; |
223 | case 2: /* REQ_SEL2 */ |
224 | mask = 0xf << 8; |
225 | val = 0x1 << 11 | module << 8; |
226 | break; |
227 | default: |
228 | pr_err("unknown AED req_sel:%d, module:%d\n", |
229 | sel, module); |
230 | return; |
231 | } |
232 | |
233 | eqdrc_update_bits(AED_TOP_REQ_CTL, mask, val); |
234 | |
235 | /* Effect Module */ |
236 | if (module <= TDMOUT_C && module >= TDMOUT_A) { |
237 | /* TDMOUT A/B/C */ |
238 | aml_tdmout_select_aed(enable, module); |
239 | } else { |
240 | /* SPDIFOUT A/B */ |
241 | aml_spdifout_select_aed(enable, module - SPDIFOUT_A); |
242 | } |
243 | |
244 | } |
245 | |
246 | void aed_set_format(int msb, enum ddr_types frddr_type, enum ddr_num source) |
247 | { |
248 | eqdrc_update_bits(AED_TOP_CTL, |
249 | 0x7 << 11 | 0x1f << 6 | 0x3 << 4, |
250 | frddr_type << 11 | msb << 6 | source << 4); |
251 | } |
252 | |
253 | void aed_enable(bool enable) |
254 | { |
255 | if (enable) { |
256 | eqdrc_write(AED_ED_CNTL, 0x1); |
257 | eqdrc_write(AED_ED_CNTL, 0x0); |
258 | |
259 | eqdrc_update_bits(AED_TOP_CTL, 0x1 << 1, 0x1 << 1); |
260 | eqdrc_update_bits(AED_TOP_CTL, 0x1 << 2, 0x1 << 2); |
261 | } else |
262 | eqdrc_update_bits(AED_TOP_CTL, 0x3 << 1, 0x0 << 1); |
263 | |
264 | eqdrc_update_bits(AED_TOP_CTL, 0x1 << 0, enable << 0); |
265 | |
266 | /* start en */ |
267 | if (enable) |
268 | eqdrc_update_bits(AED_TOP_CTL, 0x1 << 31, 0x1 << 31); |
269 | } |
270 | |
271 |