tegra210_mbdrc.c 31 KB

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