~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/tegra/tegra210_mbdrc.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 //
  3 // tegra210_mbdrc.c - Tegra210 MBDRC driver
  4 //
  5 // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
  6 
  7 #include <linux/device.h>
  8 #include <linux/io.h>
  9 #include <linux/module.h>
 10 #include <linux/of_address.h>
 11 #include <linux/pm_runtime.h>
 12 #include <linux/regmap.h>
 13 #include <sound/core.h>
 14 #include <sound/soc.h>
 15 #include <sound/tlv.h>
 16 
 17 #include "tegra210_mbdrc.h"
 18 #include "tegra210_ope.h"
 19 
 20 #define MBDRC_FILTER_REG(reg, id)                                           \
 21         ((reg) + ((id) * TEGRA210_MBDRC_FILTER_PARAM_STRIDE))
 22 
 23 #define MBDRC_FILTER_REG_DEFAULTS(id)                                       \
 24         { MBDRC_FILTER_REG(TEGRA210_MBDRC_IIR_CFG, id), 0x00000005},        \
 25         { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_ATTACK, id), 0x3e48590c},      \
 26         { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_RELEASE, id), 0x08414e9f},     \
 27         { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_ATTACK, id), 0x7fffffff},    \
 28         { MBDRC_FILTER_REG(TEGRA210_MBDRC_IN_THRESHOLD, id), 0x06145082},   \
 29         { MBDRC_FILTER_REG(TEGRA210_MBDRC_OUT_THRESHOLD, id), 0x060d379b},  \
 30         { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_1ST, id), 0x0000a000},      \
 31         { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_2ND, id), 0x00002000},      \
 32         { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_3RD, id), 0x00000b33},      \
 33         { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_4TH, id), 0x00000800},      \
 34         { MBDRC_FILTER_REG(TEGRA210_MBDRC_RATIO_5TH, id), 0x0000019a},      \
 35         { MBDRC_FILTER_REG(TEGRA210_MBDRC_MAKEUP_GAIN, id), 0x00000002},    \
 36         { MBDRC_FILTER_REG(TEGRA210_MBDRC_INIT_GAIN, id), 0x00066666},      \
 37         { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_ATTACK, id), 0x00d9ba0e},    \
 38         { MBDRC_FILTER_REG(TEGRA210_MBDRC_GAIN_RELEASE, id), 0x3e48590c},   \
 39         { MBDRC_FILTER_REG(TEGRA210_MBDRC_FAST_RELEASE, id), 0x7ffff26a},   \
 40         { MBDRC_FILTER_REG(TEGRA210_MBDRC_CFG_RAM_CTRL, id), 0x4000}
 41 
 42 static const struct reg_default tegra210_mbdrc_reg_defaults[] = {
 43         { TEGRA210_MBDRC_CFG, 0x0030de51},
 44         { TEGRA210_MBDRC_CHANNEL_MASK, 0x00000003},
 45         { TEGRA210_MBDRC_FAST_FACTOR, 0x30000800},
 46 
 47         MBDRC_FILTER_REG_DEFAULTS(0),
 48         MBDRC_FILTER_REG_DEFAULTS(1),
 49         MBDRC_FILTER_REG_DEFAULTS(2),
 50 };
 51 
 52 /* Default MBDRC parameters */
 53 static const struct tegra210_mbdrc_config mbdrc_init_config = {
 54         .mode                   = 0, /* Bypass */
 55         .rms_off                = 48,
 56         .peak_rms_mode          = 1, /* PEAK */
 57         .filter_structure       = 0, /* All-pass tree */
 58         .shift_ctrl             = 30,
 59         .frame_size             = 32,
 60         .channel_mask           = 0x3,
 61         .fa_factor              = 2048,
 62         .fr_factor              = 14747,
 63 
 64         .band_params[MBDRC_LOW_BAND] = {
 65                 .band                   = MBDRC_LOW_BAND,
 66                 .iir_stages             = 5,
 67                 .in_attack_tc           = 1044928780,
 68                 .in_release_tc          = 138497695,
 69                 .fast_attack_tc         = 2147483647,
 70                 .in_threshold           = {130, 80, 20, 6},
 71                 .out_threshold          = {155, 55, 13, 6},
 72                 .ratio                  = {40960, 8192, 2867, 2048, 410},
 73                 .makeup_gain            = 4,
 74                 .gain_init              = 419430,
 75                 .gain_attack_tc         = 14268942,
 76                 .gain_release_tc        = 1440547090,
 77                 .fast_release_tc        = 2147480170,
 78 
 79                 .biquad_params  = {
 80                         /*
 81                          * Gains:
 82                          *
 83                          * b0, b1, a0,
 84                          * a1, a2,
 85                          */
 86 
 87                         /* Band-0 */
 88                         961046798, -2030431983, 1073741824,
 89                         2030431983, -961046798,
 90                         /* Band-1 */
 91                         1030244425, -2099481453, 1073741824,
 92                         2099481453, -1030244425,
 93                         /* Band-2 */
 94                         1067169294, -2136327263, 1073741824,
 95                         2136327263, -1067169294,
 96                         /* Band-3 */
 97                         434951949, -1306567134, 1073741824,
 98                         1306567134, -434951949,
 99                         /* Band-4 */
100                         780656019, -1605955641, 1073741824,
101                         1605955641, -780656019,
102                         /* Band-5 */
103                         1024497031, -1817128152, 1073741824,
104                         1817128152, -1024497031,
105                         /* Band-6 */
106                         1073741824, 0, 0,
107                         0, 0,
108                         /* Band-7 */
109                         1073741824, 0, 0,
110                         0, 0,
111                 }
112         },
113 
114         .band_params[MBDRC_MID_BAND] = {
115                 .band                   = MBDRC_MID_BAND,
116                 .iir_stages             = 5,
117                 .in_attack_tc           = 1581413104,
118                 .in_release_tc          = 35494783,
119                 .fast_attack_tc         = 2147483647,
120                 .in_threshold           = {130, 50, 30, 6},
121                 .out_threshold          = {106, 50, 30, 13},
122                 .ratio                  = {40960, 2867, 4096, 2867, 410},
123                 .makeup_gain            = 6,
124                 .gain_init              = 419430,
125                 .gain_attack_tc         = 4766887,
126                 .gain_release_tc        = 1044928780,
127                 .fast_release_tc        = 2147480170,
128 
129                 .biquad_params = {
130                         /*
131                          * Gains:
132                          *
133                          * b0, b1, a0,
134                          * a1, a2,
135                          */
136 
137                         /* Band-0 */
138                         -1005668963, 1073741824, 0,
139                         1005668963, 0,
140                         /* Band-1 */
141                         998437058, -2067742187, 1073741824,
142                         2067742187, -998437058,
143                         /* Band-2 */
144                         1051963422, -2121153948, 1073741824,
145                         2121153948, -1051963422,
146                         /* Band-3 */
147                         434951949, -1306567134, 1073741824,
148                         1306567134, -434951949,
149                         /* Band-4 */
150                         780656019, -1605955641, 1073741824,
151                         1605955641, -780656019,
152                         /* Band-5 */
153                         1024497031, -1817128152, 1073741824,
154                         1817128152, -1024497031,
155                         /* Band-6 */
156                         1073741824, 0, 0,
157                         0, 0,
158                         /* Band-7 */
159                         1073741824, 0, 0,
160                         0, 0,
161                 }
162         },
163 
164         .band_params[MBDRC_HIGH_BAND] = {
165                 .band                   = MBDRC_HIGH_BAND,
166                 .iir_stages             = 5,
167                 .in_attack_tc           = 2144750688,
168                 .in_release_tc          = 70402888,
169                 .fast_attack_tc         = 2147483647,
170                 .in_threshold           = {130, 50, 30, 6},
171                 .out_threshold          = {106, 50, 30, 13},
172                 .ratio                  = {40960, 2867, 4096, 2867, 410},
173                 .makeup_gain            = 6,
174                 .gain_init              = 419430,
175                 .gain_attack_tc         = 4766887,
176                 .gain_release_tc        = 1044928780,
177                 .fast_release_tc        = 2147480170,
178 
179                 .biquad_params = {
180                         /*
181                          * Gains:
182                          *
183                          * b0, b1, a0,
184                          * a1, a2,
185                          */
186 
187                         /* Band-0 */
188                         1073741824, 0, 0,
189                         0, 0,
190                         /* Band-1 */
191                         1073741824, 0, 0,
192                         0, 0,
193                         /* Band-2 */
194                         1073741824, 0, 0,
195                         0, 0,
196                         /* Band-3 */
197                         -619925131, 1073741824, 0,
198                         619925131, 0,
199                         /* Band-4 */
200                         606839335, -1455425976, 1073741824,
201                         1455425976, -606839335,
202                         /* Band-5 */
203                         917759617, -1724690840, 1073741824,
204                         1724690840, -917759617,
205                         /* Band-6 */
206                         1073741824, 0, 0,
207                         0, 0,
208                         /* Band-7 */
209                         1073741824, 0, 0,
210                         0, 0,
211                 }
212         }
213 };
214 
215 static void tegra210_mbdrc_write_ram(struct regmap *regmap, unsigned int reg_ctrl,
216                                      unsigned int reg_data, unsigned int ram_offset,
217                                      unsigned int *data, size_t size)
218 {
219         unsigned int val;
220         unsigned int i;
221 
222         val = ram_offset & TEGRA210_MBDRC_RAM_CTRL_RAM_ADDR_MASK;
223         val |= TEGRA210_MBDRC_RAM_CTRL_ADDR_INIT_EN;
224         val |= TEGRA210_MBDRC_RAM_CTRL_SEQ_ACCESS_EN;
225         val |= TEGRA210_MBDRC_RAM_CTRL_RW_WRITE;
226 
227         regmap_write(regmap, reg_ctrl, val);
228 
229         for (i = 0; i < size; i++)
230                 regmap_write(regmap, reg_data, data[i]);
231 }
232 
233 static int tegra210_mbdrc_get(struct snd_kcontrol *kcontrol,
234                               struct snd_ctl_elem_value *ucontrol)
235 {
236         struct soc_mixer_control *mc =
237                 (struct soc_mixer_control *)kcontrol->private_value;
238         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
239         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
240         unsigned int val;
241 
242         regmap_read(ope->mbdrc_regmap, mc->reg, &val);
243 
244         ucontrol->value.integer.value[0] = (val >> mc->shift) & mc->max;
245 
246         return 0;
247 }
248 
249 static int tegra210_mbdrc_put(struct snd_kcontrol *kcontrol,
250                               struct snd_ctl_elem_value *ucontrol)
251 {
252         struct soc_mixer_control *mc =
253                 (struct soc_mixer_control *)kcontrol->private_value;
254         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
255         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
256         unsigned int val = ucontrol->value.integer.value[0];
257         bool change = false;
258 
259         val = val << mc->shift;
260 
261         regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
262                                  (mc->max << mc->shift), val, &change);
263 
264         return change ? 1 : 0;
265 }
266 
267 static int tegra210_mbdrc_get_enum(struct snd_kcontrol *kcontrol,
268                                    struct snd_ctl_elem_value *ucontrol)
269 {
270         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
271         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
272         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
273         unsigned int val;
274 
275         regmap_read(ope->mbdrc_regmap, e->reg, &val);
276 
277         ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
278 
279         return 0;
280 }
281 
282 static int tegra210_mbdrc_put_enum(struct snd_kcontrol *kcontrol,
283                                    struct snd_ctl_elem_value *ucontrol)
284 {
285         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
286         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
287         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
288         bool change = false;
289         unsigned int val;
290         unsigned int mask;
291 
292         if (ucontrol->value.enumerated.item[0] > e->items - 1)
293                 return -EINVAL;
294 
295         val = ucontrol->value.enumerated.item[0] << e->shift_l;
296         mask = e->mask << e->shift_l;
297 
298         regmap_update_bits_check(ope->mbdrc_regmap, e->reg, mask, val,
299                                  &change);
300 
301         return change ? 1 : 0;
302 }
303 
304 static int tegra210_mbdrc_band_params_get(struct snd_kcontrol *kcontrol,
305                                           struct snd_ctl_elem_value *ucontrol)
306 {
307         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
308         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
309         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
310         u32 *data = (u32 *)ucontrol->value.bytes.data;
311         u32 regs = params->soc.base;
312         u32 mask = params->soc.mask;
313         u32 shift = params->shift;
314         unsigned int i;
315 
316         for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
317                 regmap_read(ope->mbdrc_regmap, regs, &data[i]);
318 
319                 data[i] = ((data[i] & mask) >> shift);
320         }
321 
322         return 0;
323 }
324 
325 static int tegra210_mbdrc_band_params_put(struct snd_kcontrol *kcontrol,
326                                           struct snd_ctl_elem_value *ucontrol)
327 {
328         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
329         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
330         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
331         u32 *data = (u32 *)ucontrol->value.bytes.data;
332         u32 regs = params->soc.base;
333         u32 mask = params->soc.mask;
334         u32 shift = params->shift;
335         bool change = false;
336         unsigned int i;
337 
338         for (i = 0; i < params->soc.num_regs; i++, regs += cmpnt->val_bytes) {
339                 bool update = false;
340 
341                 regmap_update_bits_check(ope->mbdrc_regmap, regs, mask,
342                                          data[i] << shift, &update);
343 
344                 change |= update;
345         }
346 
347         return change ? 1 : 0;
348 }
349 
350 static int tegra210_mbdrc_threshold_get(struct snd_kcontrol *kcontrol,
351                                         struct snd_ctl_elem_value *ucontrol)
352 {
353         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
354         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
355         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
356         u32 *data = (u32 *)ucontrol->value.bytes.data;
357         u32 regs = params->soc.base;
358         u32 num_regs = params->soc.num_regs;
359         u32 val;
360         unsigned int i;
361 
362         for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
363                 regmap_read(ope->mbdrc_regmap, regs, &val);
364 
365                 data[i] = (val & TEGRA210_MBDRC_THRESH_1ST_MASK) >>
366                           TEGRA210_MBDRC_THRESH_1ST_SHIFT;
367                 data[i + 1] = (val & TEGRA210_MBDRC_THRESH_2ND_MASK) >>
368                               TEGRA210_MBDRC_THRESH_2ND_SHIFT;
369                 data[i + 2] = (val & TEGRA210_MBDRC_THRESH_3RD_MASK) >>
370                               TEGRA210_MBDRC_THRESH_3RD_SHIFT;
371                 data[i + 3] = (val & TEGRA210_MBDRC_THRESH_4TH_MASK) >>
372                               TEGRA210_MBDRC_THRESH_4TH_SHIFT;
373         }
374 
375         return 0;
376 }
377 
378 static int tegra210_mbdrc_threshold_put(struct snd_kcontrol *kcontrol,
379                                         struct snd_ctl_elem_value *ucontrol)
380 {
381         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
382         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
383         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
384         u32 *data = (u32 *)ucontrol->value.bytes.data;
385         u32 regs = params->soc.base;
386         u32 num_regs = params->soc.num_regs;
387         bool change = false;
388         unsigned int i;
389 
390         for (i = 0; i < num_regs; i += 4, regs += cmpnt->val_bytes) {
391                 bool update = false;
392 
393                 data[i] = (((data[i] >> TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
394                             TEGRA210_MBDRC_THRESH_1ST_MASK) |
395                            ((data[i + 1] >> TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
396                             TEGRA210_MBDRC_THRESH_2ND_MASK) |
397                            ((data[i + 2] >> TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
398                             TEGRA210_MBDRC_THRESH_3RD_MASK) |
399                            ((data[i + 3] >> TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
400                             TEGRA210_MBDRC_THRESH_4TH_MASK));
401 
402                 regmap_update_bits_check(ope->mbdrc_regmap, regs, 0xffffffff,
403                                          data[i], &update);
404 
405                 change |= update;
406         }
407 
408         return change ? 1 : 0;
409 }
410 
411 static int tegra210_mbdrc_biquad_coeffs_get(struct snd_kcontrol *kcontrol,
412         struct snd_ctl_elem_value *ucontrol)
413 {
414         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
415         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
416         u32 *data = (u32 *)ucontrol->value.bytes.data;
417 
418         memset(data, 0, params->soc.num_regs * cmpnt->val_bytes);
419 
420         return 0;
421 }
422 
423 static int tegra210_mbdrc_biquad_coeffs_put(struct snd_kcontrol *kcontrol,
424                                             struct snd_ctl_elem_value *ucontrol)
425 {
426         struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
427         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
428         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
429         u32 reg_ctrl = params->soc.base;
430         u32 reg_data = reg_ctrl + cmpnt->val_bytes;
431         u32 *data = (u32 *)ucontrol->value.bytes.data;
432 
433         tegra210_mbdrc_write_ram(ope->mbdrc_regmap, reg_ctrl, reg_data,
434                                  params->shift, data, params->soc.num_regs);
435 
436         return 1;
437 }
438 
439 static int tegra210_mbdrc_param_info(struct snd_kcontrol *kcontrol,
440                                      struct snd_ctl_elem_info *uinfo)
441 {
442         struct soc_bytes *params = (void *)kcontrol->private_value;
443 
444         uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
445         uinfo->count = params->num_regs * sizeof(u32);
446 
447         return 0;
448 }
449 
450 static int tegra210_mbdrc_vol_get(struct snd_kcontrol *kcontrol,
451                                   struct snd_ctl_elem_value *ucontrol)
452 {
453         struct soc_mixer_control *mc =
454                 (struct soc_mixer_control *)kcontrol->private_value;
455         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
456         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
457         int val;
458 
459         regmap_read(ope->mbdrc_regmap, mc->reg, &val);
460 
461         ucontrol->value.integer.value[0] =
462                 ((val >> mc->shift) - TEGRA210_MBDRC_MASTER_VOL_MIN);
463 
464         return 0;
465 }
466 
467 static int tegra210_mbdrc_vol_put(struct snd_kcontrol *kcontrol,
468                                   struct snd_ctl_elem_value *ucontrol)
469 {
470         struct soc_mixer_control *mc =
471                 (struct soc_mixer_control *)kcontrol->private_value;
472         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
473         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
474         int val = ucontrol->value.integer.value[0];
475         bool change = false;
476 
477         val += TEGRA210_MBDRC_MASTER_VOL_MIN;
478 
479         regmap_update_bits_check(ope->mbdrc_regmap, mc->reg,
480                                  mc->max << mc->shift, val << mc->shift,
481                                  &change);
482 
483         regmap_read(ope->mbdrc_regmap, mc->reg, &val);
484 
485         return change ? 1 : 0;
486 }
487 
488 static const char * const tegra210_mbdrc_mode_text[] = {
489         "Bypass", "Fullband", "Dualband", "Multiband"
490 };
491 
492 static const struct soc_enum tegra210_mbdrc_mode_enum =
493         SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT,
494                         4, tegra210_mbdrc_mode_text);
495 
496 static const char * const tegra210_mbdrc_peak_rms_text[] = {
497         "Peak", "RMS"
498 };
499 
500 static const struct soc_enum tegra210_mbdrc_peak_rms_enum =
501         SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT,
502                         2, tegra210_mbdrc_peak_rms_text);
503 
504 static const char * const tegra210_mbdrc_filter_structure_text[] = {
505         "All-pass-tree", "Flexible"
506 };
507 
508 static const struct soc_enum tegra210_mbdrc_filter_structure_enum =
509         SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG,
510                         TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT, 2,
511                         tegra210_mbdrc_filter_structure_text);
512 
513 static const char * const tegra210_mbdrc_frame_size_text[] = {
514         "N1", "N2", "N4", "N8", "N16", "N32", "N64"
515 };
516 
517 static const struct soc_enum tegra210_mbdrc_frame_size_enum =
518         SOC_ENUM_SINGLE(TEGRA210_MBDRC_CFG, TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT,
519                         7, tegra210_mbdrc_frame_size_text);
520 
521 #define TEGRA_MBDRC_BYTES_EXT(xname, xbase, xregs, xshift, xmask, xinfo)    \
522         TEGRA_SOC_BYTES_EXT(xname, xbase, xregs, xshift, xmask,             \
523                             tegra210_mbdrc_band_params_get,                 \
524                             tegra210_mbdrc_band_params_put,                 \
525                             tegra210_mbdrc_param_info)
526 
527 #define TEGRA_MBDRC_BAND_BYTES_EXT(xname, xbase, xshift, xmask, xinfo)      \
528         TEGRA_MBDRC_BYTES_EXT(xname, xbase, TEGRA210_MBDRC_FILTER_COUNT,    \
529                               xshift, xmask, xinfo)
530 
531 static const DECLARE_TLV_DB_MINMAX(mdbrc_vol_tlv, -25600, 25500);
532 
533 static const struct snd_kcontrol_new tegra210_mbdrc_controls[] = {
534         SOC_ENUM_EXT("MBDRC Peak RMS Mode", tegra210_mbdrc_peak_rms_enum,
535                      tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
536 
537         SOC_ENUM_EXT("MBDRC Filter Structure",
538                      tegra210_mbdrc_filter_structure_enum,
539                      tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
540 
541         SOC_ENUM_EXT("MBDRC Frame Size", tegra210_mbdrc_frame_size_enum,
542                      tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
543 
544         SOC_ENUM_EXT("MBDRC Mode", tegra210_mbdrc_mode_enum,
545                      tegra210_mbdrc_get_enum, tegra210_mbdrc_put_enum),
546 
547         SOC_SINGLE_EXT("MBDRC RMS Offset", TEGRA210_MBDRC_CFG,
548                        TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT, 0x1ff, 0,
549                        tegra210_mbdrc_get, tegra210_mbdrc_put),
550 
551         SOC_SINGLE_EXT("MBDRC Shift Control", TEGRA210_MBDRC_CFG,
552                        TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT, 0x1f, 0,
553                        tegra210_mbdrc_get, tegra210_mbdrc_put),
554 
555         SOC_SINGLE_EXT("MBDRC Fast Attack Factor", TEGRA210_MBDRC_FAST_FACTOR,
556                        TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT, 0xffff, 0,
557                        tegra210_mbdrc_get, tegra210_mbdrc_put),
558 
559         SOC_SINGLE_EXT("MBDRC Fast Release Factor", TEGRA210_MBDRC_FAST_FACTOR,
560                        TEGRA210_MBDRC_FAST_FACTOR_RELEASE_SHIFT, 0xffff, 0,
561                        tegra210_mbdrc_get, tegra210_mbdrc_put),
562 
563         SOC_SINGLE_RANGE_EXT_TLV("MBDRC Master Volume",
564                                  TEGRA210_MBDRC_MASTER_VOL,
565                                  TEGRA210_MBDRC_MASTER_VOL_SHIFT,
566                                  0, 0x1ff, 0,
567                                  tegra210_mbdrc_vol_get, tegra210_mbdrc_vol_put,
568                                  mdbrc_vol_tlv),
569 
570         TEGRA_SOC_BYTES_EXT("MBDRC IIR Stages", TEGRA210_MBDRC_IIR_CFG,
571                             TEGRA210_MBDRC_FILTER_COUNT,
572                             TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT,
573                             TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
574                             tegra210_mbdrc_band_params_get,
575                             tegra210_mbdrc_band_params_put,
576                             tegra210_mbdrc_param_info),
577 
578         TEGRA_SOC_BYTES_EXT("MBDRC In Attack Time Const", TEGRA210_MBDRC_IN_ATTACK,
579                             TEGRA210_MBDRC_FILTER_COUNT,
580                             TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT,
581                             TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
582                             tegra210_mbdrc_band_params_get,
583                             tegra210_mbdrc_band_params_put,
584                             tegra210_mbdrc_param_info),
585 
586         TEGRA_SOC_BYTES_EXT("MBDRC In Release Time Const", TEGRA210_MBDRC_IN_RELEASE,
587                             TEGRA210_MBDRC_FILTER_COUNT,
588                             TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT,
589                             TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
590                             tegra210_mbdrc_band_params_get,
591                             tegra210_mbdrc_band_params_put,
592                             tegra210_mbdrc_param_info),
593 
594         TEGRA_SOC_BYTES_EXT("MBDRC Fast Attack Time Const", TEGRA210_MBDRC_FAST_ATTACK,
595                             TEGRA210_MBDRC_FILTER_COUNT,
596                             TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT,
597                             TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
598                             tegra210_mbdrc_band_params_get,
599                             tegra210_mbdrc_band_params_put,
600                             tegra210_mbdrc_param_info),
601 
602         TEGRA_SOC_BYTES_EXT("MBDRC In Threshold", TEGRA210_MBDRC_IN_THRESHOLD,
603                             TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
604                             tegra210_mbdrc_threshold_get,
605                             tegra210_mbdrc_threshold_put,
606                             tegra210_mbdrc_param_info),
607 
608         TEGRA_SOC_BYTES_EXT("MBDRC Out Threshold", TEGRA210_MBDRC_OUT_THRESHOLD,
609                             TEGRA210_MBDRC_FILTER_COUNT * 4, 0, 0xffffffff,
610                             tegra210_mbdrc_threshold_get,
611                             tegra210_mbdrc_threshold_put,
612                             tegra210_mbdrc_param_info),
613 
614         TEGRA_SOC_BYTES_EXT("MBDRC Ratio", TEGRA210_MBDRC_RATIO_1ST,
615                             TEGRA210_MBDRC_FILTER_COUNT * 5,
616                             TEGRA210_MBDRC_RATIO_1ST_SHIFT, TEGRA210_MBDRC_RATIO_1ST_MASK,
617                             tegra210_mbdrc_band_params_get,
618                             tegra210_mbdrc_band_params_put,
619                             tegra210_mbdrc_param_info),
620 
621         TEGRA_SOC_BYTES_EXT("MBDRC Makeup Gain", TEGRA210_MBDRC_MAKEUP_GAIN,
622                             TEGRA210_MBDRC_FILTER_COUNT,
623                             TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT,
624                             TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
625                             tegra210_mbdrc_band_params_get,
626                             tegra210_mbdrc_band_params_put,
627                             tegra210_mbdrc_param_info),
628 
629         TEGRA_SOC_BYTES_EXT("MBDRC Init Gain", TEGRA210_MBDRC_INIT_GAIN,
630                             TEGRA210_MBDRC_FILTER_COUNT,
631                             TEGRA210_MBDRC_INIT_GAIN_SHIFT,
632                             TEGRA210_MBDRC_INIT_GAIN_MASK,
633                             tegra210_mbdrc_band_params_get,
634                             tegra210_mbdrc_band_params_put,
635                             tegra210_mbdrc_param_info),
636 
637         TEGRA_SOC_BYTES_EXT("MBDRC Attack Gain", TEGRA210_MBDRC_GAIN_ATTACK,
638                             TEGRA210_MBDRC_FILTER_COUNT,
639                             TEGRA210_MBDRC_GAIN_ATTACK_SHIFT,
640                             TEGRA210_MBDRC_GAIN_ATTACK_MASK,
641                             tegra210_mbdrc_band_params_get,
642                             tegra210_mbdrc_band_params_put,
643                             tegra210_mbdrc_param_info),
644 
645         TEGRA_SOC_BYTES_EXT("MBDRC Release Gain", TEGRA210_MBDRC_GAIN_RELEASE,
646                             TEGRA210_MBDRC_FILTER_COUNT,
647                             TEGRA210_MBDRC_GAIN_RELEASE_SHIFT,
648                             TEGRA210_MBDRC_GAIN_RELEASE_MASK,
649                             tegra210_mbdrc_band_params_get,
650                             tegra210_mbdrc_band_params_put,
651                             tegra210_mbdrc_param_info),
652 
653         TEGRA_SOC_BYTES_EXT("MBDRC Fast Release Gain",
654                             TEGRA210_MBDRC_FAST_RELEASE,
655                             TEGRA210_MBDRC_FILTER_COUNT,
656                             TEGRA210_MBDRC_FAST_RELEASE_SHIFT,
657                             TEGRA210_MBDRC_FAST_RELEASE_MASK,
658                             tegra210_mbdrc_band_params_get,
659                             tegra210_mbdrc_band_params_put,
660                             tegra210_mbdrc_param_info),
661 
662         TEGRA_SOC_BYTES_EXT("MBDRC Low Band Biquad Coeffs",
663                             TEGRA210_MBDRC_CFG_RAM_CTRL,
664                             TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
665                             tegra210_mbdrc_biquad_coeffs_get,
666                             tegra210_mbdrc_biquad_coeffs_put,
667                             tegra210_mbdrc_param_info),
668 
669         TEGRA_SOC_BYTES_EXT("MBDRC Mid Band Biquad Coeffs",
670                             TEGRA210_MBDRC_CFG_RAM_CTRL +
671                                 TEGRA210_MBDRC_FILTER_PARAM_STRIDE,
672                             TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
673                             tegra210_mbdrc_biquad_coeffs_get,
674                             tegra210_mbdrc_biquad_coeffs_put,
675                             tegra210_mbdrc_param_info),
676 
677         TEGRA_SOC_BYTES_EXT("MBDRC High Band Biquad Coeffs",
678                             TEGRA210_MBDRC_CFG_RAM_CTRL +
679                                 (TEGRA210_MBDRC_FILTER_PARAM_STRIDE * 2),
680                             TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5, 0, 0xffffffff,
681                             tegra210_mbdrc_biquad_coeffs_get,
682                             tegra210_mbdrc_biquad_coeffs_put,
683                             tegra210_mbdrc_param_info),
684 };
685 
686 static bool tegra210_mbdrc_wr_reg(struct device *dev, unsigned int reg)
687 {
688         if (reg >= TEGRA210_MBDRC_IIR_CFG)
689                 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
690                         (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
691                          TEGRA210_MBDRC_FILTER_COUNT));
692 
693         switch (reg) {
694         case TEGRA210_MBDRC_SOFT_RESET:
695         case TEGRA210_MBDRC_CG:
696         case TEGRA210_MBDRC_CFG ... TEGRA210_MBDRC_CFG_RAM_DATA:
697                 return true;
698         default:
699                 return false;
700         }
701 }
702 
703 static bool tegra210_mbdrc_rd_reg(struct device *dev, unsigned int reg)
704 {
705         if (tegra210_mbdrc_wr_reg(dev, reg))
706                 return true;
707 
708         if (reg >= TEGRA210_MBDRC_IIR_CFG)
709                 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
710                         (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
711                          TEGRA210_MBDRC_FILTER_COUNT));
712 
713         switch (reg) {
714         case TEGRA210_MBDRC_STATUS:
715                 return true;
716         default:
717                 return false;
718         }
719 }
720 
721 static bool tegra210_mbdrc_volatile_reg(struct device *dev, unsigned int reg)
722 {
723         if (reg >= TEGRA210_MBDRC_IIR_CFG)
724                 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
725                         (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
726                          TEGRA210_MBDRC_FILTER_COUNT));
727 
728         switch (reg) {
729         case TEGRA210_MBDRC_SOFT_RESET:
730         case TEGRA210_MBDRC_STATUS:
731         case TEGRA210_MBDRC_CFG_RAM_CTRL:
732         case TEGRA210_MBDRC_CFG_RAM_DATA:
733                 return true;
734         default:
735                 return false;
736         }
737 }
738 
739 static bool tegra210_mbdrc_precious_reg(struct device *dev, unsigned int reg)
740 {
741         if (reg >= TEGRA210_MBDRC_IIR_CFG)
742                 reg -= ((reg - TEGRA210_MBDRC_IIR_CFG) %
743                         (TEGRA210_MBDRC_FILTER_PARAM_STRIDE *
744                          TEGRA210_MBDRC_FILTER_COUNT));
745 
746         switch (reg) {
747         case TEGRA210_MBDRC_CFG_RAM_DATA:
748                 return true;
749         default:
750                 return false;
751         }
752 }
753 
754 static const struct regmap_config tegra210_mbdrc_regmap_cfg = {
755         .name                   = "mbdrc",
756         .reg_bits               = 32,
757         .reg_stride             = 4,
758         .val_bits               = 32,
759         .max_register           = TEGRA210_MBDRC_MAX_REG,
760         .writeable_reg          = tegra210_mbdrc_wr_reg,
761         .readable_reg           = tegra210_mbdrc_rd_reg,
762         .volatile_reg           = tegra210_mbdrc_volatile_reg,
763         .precious_reg           = tegra210_mbdrc_precious_reg,
764         .reg_defaults           = tegra210_mbdrc_reg_defaults,
765         .num_reg_defaults       = ARRAY_SIZE(tegra210_mbdrc_reg_defaults),
766         .cache_type             = REGCACHE_FLAT,
767 };
768 
769 int tegra210_mbdrc_hw_params(struct snd_soc_component *cmpnt)
770 {
771         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
772         const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
773         u32 val = 0;
774         unsigned int i;
775 
776         regmap_read(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG, &val);
777 
778         val &= TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK;
779 
780         if (val == TEGRA210_MBDRC_CFG_MBDRC_MODE_BYPASS)
781                 return 0;
782 
783         for (i = 0; i < MBDRC_NUM_BAND; i++) {
784                 const struct tegra210_mbdrc_band_params *params =
785                         &conf->band_params[i];
786 
787                 u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
788 
789                 tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
790                                          reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
791                                          reg_off + TEGRA210_MBDRC_CFG_RAM_DATA,
792                                          0, (u32 *)&params->biquad_params[0],
793                                          TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
794         }
795         return 0;
796 }
797 
798 int tegra210_mbdrc_component_init(struct snd_soc_component *cmpnt)
799 {
800         struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
801         const struct tegra210_mbdrc_config *conf = &mbdrc_init_config;
802         unsigned int i;
803         u32 val;
804 
805         pm_runtime_get_sync(cmpnt->dev);
806 
807         /* Initialize MBDRC registers and AHUB RAM with default params */
808         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
809                 TEGRA210_MBDRC_CFG_MBDRC_MODE_MASK,
810                 conf->mode << TEGRA210_MBDRC_CFG_MBDRC_MODE_SHIFT);
811 
812         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
813                 TEGRA210_MBDRC_CFG_RMS_OFFSET_MASK,
814                 conf->rms_off << TEGRA210_MBDRC_CFG_RMS_OFFSET_SHIFT);
815 
816         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
817                 TEGRA210_MBDRC_CFG_PEAK_RMS_MASK,
818                 conf->peak_rms_mode << TEGRA210_MBDRC_CFG_PEAK_RMS_SHIFT);
819 
820         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
821                 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_MASK,
822                 conf->filter_structure <<
823                 TEGRA210_MBDRC_CFG_FILTER_STRUCTURE_SHIFT);
824 
825         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
826                 TEGRA210_MBDRC_CFG_SHIFT_CTRL_MASK,
827                 conf->shift_ctrl << TEGRA210_MBDRC_CFG_SHIFT_CTRL_SHIFT);
828 
829         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CFG,
830                 TEGRA210_MBDRC_CFG_FRAME_SIZE_MASK,
831                 __ffs(conf->frame_size) <<
832                 TEGRA210_MBDRC_CFG_FRAME_SIZE_SHIFT);
833 
834         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_CHANNEL_MASK,
835                 TEGRA210_MBDRC_CHANNEL_MASK_MASK,
836                 conf->channel_mask << TEGRA210_MBDRC_CHANNEL_MASK_SHIFT);
837 
838         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
839                 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
840                 conf->fa_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
841 
842         regmap_update_bits(ope->mbdrc_regmap, TEGRA210_MBDRC_FAST_FACTOR,
843                 TEGRA210_MBDRC_FAST_FACTOR_ATTACK_MASK,
844                 conf->fr_factor << TEGRA210_MBDRC_FAST_FACTOR_ATTACK_SHIFT);
845 
846         for (i = 0; i < MBDRC_NUM_BAND; i++) {
847                 const struct tegra210_mbdrc_band_params *params =
848                                                 &conf->band_params[i];
849                 u32 reg_off = i * TEGRA210_MBDRC_FILTER_PARAM_STRIDE;
850 
851                 regmap_update_bits(ope->mbdrc_regmap,
852                         reg_off + TEGRA210_MBDRC_IIR_CFG,
853                         TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_MASK,
854                         params->iir_stages <<
855                                 TEGRA210_MBDRC_IIR_CFG_NUM_STAGES_SHIFT);
856 
857                 regmap_update_bits(ope->mbdrc_regmap,
858                         reg_off + TEGRA210_MBDRC_IN_ATTACK,
859                         TEGRA210_MBDRC_IN_ATTACK_TC_MASK,
860                         params->in_attack_tc <<
861                                 TEGRA210_MBDRC_IN_ATTACK_TC_SHIFT);
862 
863                 regmap_update_bits(ope->mbdrc_regmap,
864                         reg_off + TEGRA210_MBDRC_IN_RELEASE,
865                         TEGRA210_MBDRC_IN_RELEASE_TC_MASK,
866                         params->in_release_tc <<
867                                 TEGRA210_MBDRC_IN_RELEASE_TC_SHIFT);
868 
869                 regmap_update_bits(ope->mbdrc_regmap,
870                         reg_off + TEGRA210_MBDRC_FAST_ATTACK,
871                         TEGRA210_MBDRC_FAST_ATTACK_TC_MASK,
872                         params->fast_attack_tc <<
873                                 TEGRA210_MBDRC_FAST_ATTACK_TC_SHIFT);
874 
875                 val = (((params->in_threshold[0] >>
876                          TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
877                         TEGRA210_MBDRC_THRESH_1ST_MASK) |
878                         ((params->in_threshold[1] >>
879                           TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
880                          TEGRA210_MBDRC_THRESH_2ND_MASK) |
881                         ((params->in_threshold[2] >>
882                           TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
883                          TEGRA210_MBDRC_THRESH_3RD_MASK) |
884                         ((params->in_threshold[3] >>
885                           TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
886                          TEGRA210_MBDRC_THRESH_4TH_MASK));
887 
888                 regmap_update_bits(ope->mbdrc_regmap,
889                                    reg_off + TEGRA210_MBDRC_IN_THRESHOLD,
890                                    0xffffffff, val);
891 
892                 val = (((params->out_threshold[0] >>
893                          TEGRA210_MBDRC_THRESH_1ST_SHIFT) &
894                         TEGRA210_MBDRC_THRESH_1ST_MASK) |
895                         ((params->out_threshold[1] >>
896                           TEGRA210_MBDRC_THRESH_2ND_SHIFT) &
897                          TEGRA210_MBDRC_THRESH_2ND_MASK) |
898                         ((params->out_threshold[2] >>
899                           TEGRA210_MBDRC_THRESH_3RD_SHIFT) &
900                          TEGRA210_MBDRC_THRESH_3RD_MASK) |
901                         ((params->out_threshold[3] >>
902                           TEGRA210_MBDRC_THRESH_4TH_SHIFT) &
903                          TEGRA210_MBDRC_THRESH_4TH_MASK));
904 
905                 regmap_update_bits(ope->mbdrc_regmap,
906                         reg_off + TEGRA210_MBDRC_OUT_THRESHOLD,
907                         0xffffffff, val);
908 
909                 regmap_update_bits(ope->mbdrc_regmap,
910                         reg_off + TEGRA210_MBDRC_RATIO_1ST,
911                         TEGRA210_MBDRC_RATIO_1ST_MASK,
912                         params->ratio[0] << TEGRA210_MBDRC_RATIO_1ST_SHIFT);
913 
914                 regmap_update_bits(ope->mbdrc_regmap,
915                         reg_off + TEGRA210_MBDRC_RATIO_2ND,
916                         TEGRA210_MBDRC_RATIO_2ND_MASK,
917                         params->ratio[1] << TEGRA210_MBDRC_RATIO_2ND_SHIFT);
918 
919                 regmap_update_bits(ope->mbdrc_regmap,
920                         reg_off + TEGRA210_MBDRC_RATIO_3RD,
921                         TEGRA210_MBDRC_RATIO_3RD_MASK,
922                         params->ratio[2] << TEGRA210_MBDRC_RATIO_3RD_SHIFT);
923 
924                 regmap_update_bits(ope->mbdrc_regmap,
925                         reg_off + TEGRA210_MBDRC_RATIO_4TH,
926                         TEGRA210_MBDRC_RATIO_4TH_MASK,
927                         params->ratio[3] << TEGRA210_MBDRC_RATIO_4TH_SHIFT);
928 
929                 regmap_update_bits(ope->mbdrc_regmap,
930                         reg_off + TEGRA210_MBDRC_RATIO_5TH,
931                         TEGRA210_MBDRC_RATIO_5TH_MASK,
932                         params->ratio[4] << TEGRA210_MBDRC_RATIO_5TH_SHIFT);
933 
934                 regmap_update_bits(ope->mbdrc_regmap,
935                         reg_off + TEGRA210_MBDRC_MAKEUP_GAIN,
936                         TEGRA210_MBDRC_MAKEUP_GAIN_MASK,
937                         params->makeup_gain <<
938                                 TEGRA210_MBDRC_MAKEUP_GAIN_SHIFT);
939 
940                 regmap_update_bits(ope->mbdrc_regmap,
941                         reg_off + TEGRA210_MBDRC_INIT_GAIN,
942                         TEGRA210_MBDRC_INIT_GAIN_MASK,
943                         params->gain_init <<
944                                 TEGRA210_MBDRC_INIT_GAIN_SHIFT);
945 
946                 regmap_update_bits(ope->mbdrc_regmap,
947                         reg_off + TEGRA210_MBDRC_GAIN_ATTACK,
948                         TEGRA210_MBDRC_GAIN_ATTACK_MASK,
949                         params->gain_attack_tc <<
950                                 TEGRA210_MBDRC_GAIN_ATTACK_SHIFT);
951 
952                 regmap_update_bits(ope->mbdrc_regmap,
953                         reg_off + TEGRA210_MBDRC_GAIN_RELEASE,
954                         TEGRA210_MBDRC_GAIN_RELEASE_MASK,
955                         params->gain_release_tc <<
956                                 TEGRA210_MBDRC_GAIN_RELEASE_SHIFT);
957 
958                 regmap_update_bits(ope->mbdrc_regmap,
959                         reg_off + TEGRA210_MBDRC_FAST_RELEASE,
960                         TEGRA210_MBDRC_FAST_RELEASE_MASK,
961                         params->fast_release_tc <<
962                                 TEGRA210_MBDRC_FAST_RELEASE_SHIFT);
963 
964                 tegra210_mbdrc_write_ram(ope->mbdrc_regmap,
965                         reg_off + TEGRA210_MBDRC_CFG_RAM_CTRL,
966                         reg_off + TEGRA210_MBDRC_CFG_RAM_DATA, 0,
967                         (u32 *)&params->biquad_params[0],
968                         TEGRA210_MBDRC_MAX_BIQUAD_STAGES * 5);
969         }
970 
971         pm_runtime_put_sync(cmpnt->dev);
972 
973         snd_soc_add_component_controls(cmpnt, tegra210_mbdrc_controls,
974                                        ARRAY_SIZE(tegra210_mbdrc_controls));
975 
976         return 0;
977 }
978 
979 int tegra210_mbdrc_regmap_init(struct platform_device *pdev)
980 {
981         struct device *dev = &pdev->dev;
982         struct tegra210_ope *ope = dev_get_drvdata(dev);
983         struct device_node *child;
984         struct resource mem;
985         void __iomem *regs;
986         int err;
987 
988         child = of_get_child_by_name(dev->of_node, "dynamic-range-compressor");
989         if (!child)
990                 return -ENODEV;
991 
992         err = of_address_to_resource(child, 0, &mem);
993         of_node_put(child);
994         if (err < 0) {
995                 dev_err(dev, "fail to get MBDRC resource\n");
996                 return err;
997         }
998 
999         mem.flags = IORESOURCE_MEM;
1000         regs = devm_ioremap_resource(dev, &mem);
1001         if (IS_ERR(regs))
1002                 return PTR_ERR(regs);
1003 
1004         ope->mbdrc_regmap = devm_regmap_init_mmio(dev, regs,
1005                                                   &tegra210_mbdrc_regmap_cfg);
1006         if (IS_ERR(ope->mbdrc_regmap)) {
1007                 dev_err(dev, "regmap init failed\n");
1008                 return PTR_ERR(ope->mbdrc_regmap);
1009         }
1010 
1011         regcache_cache_only(ope->mbdrc_regmap, true);
1012 
1013         return 0;
1014 }
1015 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php