tegra210_peq.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. //
  3. // tegra210_peq.c - Tegra210 PEQ driver
  4. //
  5. // Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
  6. #include <linux/clk.h>
  7. #include <linux/device.h>
  8. #include <linux/io.h>
  9. #include <linux/module.h>
  10. #include <linux/of.h>
  11. #include <linux/of_address.h>
  12. #include <linux/of_device.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/pm_runtime.h>
  15. #include <linux/regmap.h>
  16. #include <sound/core.h>
  17. #include <sound/pcm.h>
  18. #include <sound/pcm_params.h>
  19. #include <sound/soc.h>
  20. #include "tegra210_ope.h"
  21. #include "tegra210_peq.h"
  22. static const struct reg_default tegra210_peq_reg_defaults[] = {
  23. { TEGRA210_PEQ_CFG, 0x00000013},
  24. { TEGRA210_PEQ_CFG_RAM_CTRL, 0x00004000},
  25. { TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, 0x00004000},
  26. };
  27. static const u32 biquad_init_gains[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH] = {
  28. 1495012349, /* Pre-gain */
  29. /* Gains : b0, b1, a0, a1, a2 */
  30. 536870912, -1073741824, 536870912, 2143508246, -1069773768, /* Band-0 */
  31. 134217728, -265414508, 131766272, 2140402222, -1071252997, /* Band-1 */
  32. 268435456, -233515765, -33935948, 1839817267, -773826124, /* Band-2 */
  33. 536870912, -672537913, 139851540, 1886437554, -824433167, /* Band-3 */
  34. 268435456, -114439279, 173723964, 205743566, 278809729, /* Band-4 */
  35. 1, 0, 0, 0, 0, /* Band-5 */
  36. 1, 0, 0, 0, 0, /* Band-6 */
  37. 1, 0, 0, 0, 0, /* Band-7 */
  38. 1, 0, 0, 0, 0, /* Band-8 */
  39. 1, 0, 0, 0, 0, /* Band-9 */
  40. 1, 0, 0, 0, 0, /* Band-10 */
  41. 1, 0, 0, 0, 0, /* Band-11 */
  42. 963423114, /* Post-gain */
  43. };
  44. static const u32 biquad_init_shifts[TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH] = {
  45. 23, /* Pre-shift */
  46. 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, /* Shift for bands */
  47. 28, /* Post-shift */
  48. };
  49. static s32 biquad_coeff_buffer[TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH];
  50. static void tegra210_peq_read_ram(struct regmap *regmap, unsigned int reg_ctrl,
  51. unsigned int reg_data, unsigned int ram_offset,
  52. unsigned int *data, size_t size)
  53. {
  54. unsigned int val;
  55. unsigned int i;
  56. val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK;
  57. val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN;
  58. val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN;
  59. val |= TEGRA210_PEQ_RAM_CTRL_RW_READ;
  60. regmap_write(regmap, reg_ctrl, val);
  61. /*
  62. * Since all ahub non-io modules work under same ahub clock it is not
  63. * necessary to check ahub read busy bit after every read.
  64. */
  65. for (i = 0; i < size; i++)
  66. regmap_read(regmap, reg_data, &data[i]);
  67. }
  68. static void tegra210_peq_write_ram(struct regmap *regmap, unsigned int reg_ctrl,
  69. unsigned int reg_data, unsigned int ram_offset,
  70. unsigned int *data, size_t size)
  71. {
  72. unsigned int val;
  73. unsigned int i;
  74. val = ram_offset & TEGRA210_PEQ_RAM_CTRL_RAM_ADDR_MASK;
  75. val |= TEGRA210_PEQ_RAM_CTRL_ADDR_INIT_EN;
  76. val |= TEGRA210_PEQ_RAM_CTRL_SEQ_ACCESS_EN;
  77. val |= TEGRA210_PEQ_RAM_CTRL_RW_WRITE;
  78. regmap_write(regmap, reg_ctrl, val);
  79. for (i = 0; i < size; i++)
  80. regmap_write(regmap, reg_data, data[i]);
  81. }
  82. static int tegra210_peq_get(struct snd_kcontrol *kcontrol,
  83. struct snd_ctl_elem_value *ucontrol)
  84. {
  85. struct soc_mixer_control *mc =
  86. (struct soc_mixer_control *)kcontrol->private_value;
  87. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  88. struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
  89. unsigned int mask = (1 << fls(mc->max)) - 1;
  90. unsigned int val;
  91. regmap_read(ope->peq_regmap, mc->reg, &val);
  92. ucontrol->value.integer.value[0] = (val >> mc->shift) & mask;
  93. if (!mc->invert)
  94. return 0;
  95. ucontrol->value.integer.value[0] =
  96. mc->max - ucontrol->value.integer.value[0];
  97. return 0;
  98. }
  99. static int tegra210_peq_put(struct snd_kcontrol *kcontrol,
  100. struct snd_ctl_elem_value *ucontrol)
  101. {
  102. struct soc_mixer_control *mc =
  103. (struct soc_mixer_control *)kcontrol->private_value;
  104. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  105. struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
  106. unsigned int mask = (1 << fls(mc->max)) - 1;
  107. bool change = false;
  108. unsigned int val;
  109. val = (ucontrol->value.integer.value[0] & mask);
  110. if (mc->invert)
  111. val = mc->max - val;
  112. val = val << mc->shift;
  113. regmap_update_bits_check(ope->peq_regmap, mc->reg, (mask << mc->shift),
  114. val, &change);
  115. return change ? 1 : 0;
  116. }
  117. static int tegra210_peq_ram_get(struct snd_kcontrol *kcontrol,
  118. struct snd_ctl_elem_value *ucontrol)
  119. {
  120. struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
  121. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  122. struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
  123. u32 i, reg_ctrl = params->soc.base;
  124. u32 reg_data = reg_ctrl + cmpnt->val_bytes;
  125. s32 *data = (s32 *)biquad_coeff_buffer;
  126. pm_runtime_get_sync(cmpnt->dev);
  127. tegra210_peq_read_ram(ope->peq_regmap, reg_ctrl, reg_data,
  128. params->shift, data, params->soc.num_regs);
  129. pm_runtime_put_sync(cmpnt->dev);
  130. for (i = 0; i < params->soc.num_regs; i++)
  131. ucontrol->value.integer.value[i] = (long)data[i];
  132. return 0;
  133. }
  134. static int tegra210_peq_ram_put(struct snd_kcontrol *kcontrol,
  135. struct snd_ctl_elem_value *ucontrol)
  136. {
  137. struct tegra_soc_bytes *params = (void *)kcontrol->private_value;
  138. struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
  139. struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
  140. u32 i, reg_ctrl = params->soc.base;
  141. u32 reg_data = reg_ctrl + cmpnt->val_bytes;
  142. s32 *data = (s32 *)biquad_coeff_buffer;
  143. for (i = 0; i < params->soc.num_regs; i++)
  144. data[i] = (s32)ucontrol->value.integer.value[i];
  145. pm_runtime_get_sync(cmpnt->dev);
  146. tegra210_peq_write_ram(ope->peq_regmap, reg_ctrl, reg_data,
  147. params->shift, data, params->soc.num_regs);
  148. pm_runtime_put_sync(cmpnt->dev);
  149. return 1;
  150. }
  151. static int tegra210_peq_param_info(struct snd_kcontrol *kcontrol,
  152. struct snd_ctl_elem_info *uinfo)
  153. {
  154. struct soc_bytes *params = (void *)kcontrol->private_value;
  155. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  156. uinfo->value.integer.min = INT_MIN;
  157. uinfo->value.integer.max = INT_MAX;
  158. uinfo->count = params->num_regs;
  159. return 0;
  160. }
  161. #define TEGRA210_PEQ_GAIN_PARAMS_CTRL(chan) \
  162. TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Gain Params", \
  163. TEGRA210_PEQ_CFG_RAM_CTRL, \
  164. TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH, \
  165. (TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH * chan), 0xffffffff, \
  166. tegra210_peq_ram_get, tegra210_peq_ram_put, \
  167. tegra210_peq_param_info)
  168. #define TEGRA210_PEQ_SHIFT_PARAMS_CTRL(chan) \
  169. TEGRA_SOC_BYTES_EXT("PEQ Channel-" #chan " Biquad Shift Params", \
  170. TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL, \
  171. TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH, \
  172. (TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH * chan), 0x1f, \
  173. tegra210_peq_ram_get, tegra210_peq_ram_put, \
  174. tegra210_peq_param_info)
  175. static const struct snd_kcontrol_new tegra210_peq_controls[] = {
  176. SOC_SINGLE_EXT("PEQ Active", TEGRA210_PEQ_CFG,
  177. TEGRA210_PEQ_CFG_MODE_SHIFT, 1, 0,
  178. tegra210_peq_get, tegra210_peq_put),
  179. SOC_SINGLE_EXT("PEQ Biquad Stages", TEGRA210_PEQ_CFG,
  180. TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT,
  181. TEGRA210_PEQ_MAX_BIQUAD_STAGES - 1, 0,
  182. tegra210_peq_get, tegra210_peq_put),
  183. TEGRA210_PEQ_GAIN_PARAMS_CTRL(0),
  184. TEGRA210_PEQ_GAIN_PARAMS_CTRL(1),
  185. TEGRA210_PEQ_GAIN_PARAMS_CTRL(2),
  186. TEGRA210_PEQ_GAIN_PARAMS_CTRL(3),
  187. TEGRA210_PEQ_GAIN_PARAMS_CTRL(4),
  188. TEGRA210_PEQ_GAIN_PARAMS_CTRL(5),
  189. TEGRA210_PEQ_GAIN_PARAMS_CTRL(6),
  190. TEGRA210_PEQ_GAIN_PARAMS_CTRL(7),
  191. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(0),
  192. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(1),
  193. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(2),
  194. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(3),
  195. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(4),
  196. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(5),
  197. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(6),
  198. TEGRA210_PEQ_SHIFT_PARAMS_CTRL(7),
  199. };
  200. static bool tegra210_peq_wr_reg(struct device *dev, unsigned int reg)
  201. {
  202. switch (reg) {
  203. case TEGRA210_PEQ_SOFT_RESET:
  204. case TEGRA210_PEQ_CG:
  205. case TEGRA210_PEQ_CFG ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA:
  206. return true;
  207. default:
  208. return false;
  209. }
  210. }
  211. static bool tegra210_peq_rd_reg(struct device *dev, unsigned int reg)
  212. {
  213. if (tegra210_peq_wr_reg(dev, reg))
  214. return true;
  215. switch (reg) {
  216. case TEGRA210_PEQ_STATUS:
  217. return true;
  218. default:
  219. return false;
  220. }
  221. }
  222. static bool tegra210_peq_volatile_reg(struct device *dev, unsigned int reg)
  223. {
  224. switch (reg) {
  225. case TEGRA210_PEQ_SOFT_RESET:
  226. case TEGRA210_PEQ_STATUS:
  227. case TEGRA210_PEQ_CFG_RAM_CTRL ... TEGRA210_PEQ_CFG_RAM_SHIFT_DATA:
  228. return true;
  229. default:
  230. return false;
  231. }
  232. }
  233. static bool tegra210_peq_precious_reg(struct device *dev, unsigned int reg)
  234. {
  235. switch (reg) {
  236. case TEGRA210_PEQ_CFG_RAM_DATA:
  237. case TEGRA210_PEQ_CFG_RAM_SHIFT_DATA:
  238. return true;
  239. default:
  240. return false;
  241. }
  242. }
  243. static const struct regmap_config tegra210_peq_regmap_config = {
  244. .name = "peq",
  245. .reg_bits = 32,
  246. .reg_stride = 4,
  247. .val_bits = 32,
  248. .max_register = TEGRA210_PEQ_CFG_RAM_SHIFT_DATA,
  249. .writeable_reg = tegra210_peq_wr_reg,
  250. .readable_reg = tegra210_peq_rd_reg,
  251. .volatile_reg = tegra210_peq_volatile_reg,
  252. .precious_reg = tegra210_peq_precious_reg,
  253. .reg_defaults = tegra210_peq_reg_defaults,
  254. .num_reg_defaults = ARRAY_SIZE(tegra210_peq_reg_defaults),
  255. .cache_type = REGCACHE_FLAT,
  256. };
  257. void tegra210_peq_restore(struct regmap *regmap, u32 *biquad_gains,
  258. u32 *biquad_shifts)
  259. {
  260. unsigned int i;
  261. for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) {
  262. tegra210_peq_write_ram(regmap, TEGRA210_PEQ_CFG_RAM_CTRL,
  263. TEGRA210_PEQ_CFG_RAM_DATA,
  264. (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH),
  265. biquad_gains,
  266. TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH);
  267. tegra210_peq_write_ram(regmap,
  268. TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL,
  269. TEGRA210_PEQ_CFG_RAM_SHIFT_DATA,
  270. (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH),
  271. biquad_shifts,
  272. TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH);
  273. }
  274. }
  275. void tegra210_peq_save(struct regmap *regmap, u32 *biquad_gains,
  276. u32 *biquad_shifts)
  277. {
  278. unsigned int i;
  279. for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) {
  280. tegra210_peq_read_ram(regmap,
  281. TEGRA210_PEQ_CFG_RAM_CTRL,
  282. TEGRA210_PEQ_CFG_RAM_DATA,
  283. (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH),
  284. biquad_gains,
  285. TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH);
  286. tegra210_peq_read_ram(regmap,
  287. TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL,
  288. TEGRA210_PEQ_CFG_RAM_SHIFT_DATA,
  289. (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH),
  290. biquad_shifts,
  291. TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH);
  292. }
  293. }
  294. int tegra210_peq_component_init(struct snd_soc_component *cmpnt)
  295. {
  296. struct tegra210_ope *ope = snd_soc_component_get_drvdata(cmpnt);
  297. unsigned int i;
  298. pm_runtime_get_sync(cmpnt->dev);
  299. regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG,
  300. TEGRA210_PEQ_CFG_MODE_MASK,
  301. 0 << TEGRA210_PEQ_CFG_MODE_SHIFT);
  302. regmap_update_bits(ope->peq_regmap, TEGRA210_PEQ_CFG,
  303. TEGRA210_PEQ_CFG_BIQUAD_STAGES_MASK,
  304. (TEGRA210_PEQ_BIQUAD_INIT_STAGE - 1) <<
  305. TEGRA210_PEQ_CFG_BIQUAD_STAGES_SHIFT);
  306. /* Initialize PEQ AHUB RAM with default params */
  307. for (i = 0; i < TEGRA210_PEQ_MAX_CHANNELS; i++) {
  308. /* Set default gain params */
  309. tegra210_peq_write_ram(ope->peq_regmap,
  310. TEGRA210_PEQ_CFG_RAM_CTRL,
  311. TEGRA210_PEQ_CFG_RAM_DATA,
  312. (i * TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH),
  313. (u32 *)&biquad_init_gains,
  314. TEGRA210_PEQ_GAIN_PARAM_SIZE_PER_CH);
  315. /* Set default shift params */
  316. tegra210_peq_write_ram(ope->peq_regmap,
  317. TEGRA210_PEQ_CFG_RAM_SHIFT_CTRL,
  318. TEGRA210_PEQ_CFG_RAM_SHIFT_DATA,
  319. (i * TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH),
  320. (u32 *)&biquad_init_shifts,
  321. TEGRA210_PEQ_SHIFT_PARAM_SIZE_PER_CH);
  322. }
  323. pm_runtime_put_sync(cmpnt->dev);
  324. snd_soc_add_component_controls(cmpnt, tegra210_peq_controls,
  325. ARRAY_SIZE(tegra210_peq_controls));
  326. return 0;
  327. }
  328. int tegra210_peq_regmap_init(struct platform_device *pdev)
  329. {
  330. struct device *dev = &pdev->dev;
  331. struct tegra210_ope *ope = dev_get_drvdata(dev);
  332. struct device_node *child;
  333. struct resource mem;
  334. void __iomem *regs;
  335. int err;
  336. child = of_get_child_by_name(dev->of_node, "equalizer");
  337. if (!child)
  338. return -ENODEV;
  339. err = of_address_to_resource(child, 0, &mem);
  340. of_node_put(child);
  341. if (err < 0) {
  342. dev_err(dev, "fail to get PEQ resource\n");
  343. return err;
  344. }
  345. mem.flags = IORESOURCE_MEM;
  346. regs = devm_ioremap_resource(dev, &mem);
  347. if (IS_ERR(regs))
  348. return PTR_ERR(regs);
  349. ope->peq_regmap = devm_regmap_init_mmio(dev, regs,
  350. &tegra210_peq_regmap_config);
  351. if (IS_ERR(ope->peq_regmap)) {
  352. dev_err(dev, "regmap init failed\n");
  353. return PTR_ERR(ope->peq_regmap);
  354. }
  355. regcache_cache_only(ope->peq_regmap, true);
  356. return 0;
  357. }