summaryrefslogtreecommitdiff
path: root/sound/soc/amlogic/auge/effects_hw_v2.c (plain)
blob: e6b22ab331feedfbff80909065cdb56704d56ba8
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
26void 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
38void 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
51void 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
78void 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
107void 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
116void aed_dc_enable(bool enable)
117{
118 eqdrc_write(AED_DC_EN, enable << 0);
119}
120
121void 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
143void aed_eq_enable(int idx, bool enable)
144{
145 eqdrc_update_bits(AED_EQ_EN, 0x1 << idx, enable << idx);
146}
147
148void 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
158void 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
168void 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
176void 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, 0x200); /*10ms*/
188 eqdrc_write(AED_MUTE, 0);
189}
190
191void 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
210void 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
246void 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
253void 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