wcd9360-regmap.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/regmap.h>
  14. #include <linux/device.h>
  15. #include <asoc/wcd9360-registers.h>
  16. #include "../core.h"
  17. #include "../wcd9xxx-regmap.h"
  18. #include "wcd9360-defaults.h"
  19. static bool wcd9360_is_readable_register(struct device *dev, unsigned int reg)
  20. {
  21. u8 pg_num, reg_offset;
  22. const u8 *reg_tbl = NULL;
  23. /*
  24. * Get the page number from MSB of codec register. If its 0x80, assign
  25. * the corresponding page index PAGE_0x80.
  26. */
  27. pg_num = reg >> 8;
  28. if (pg_num == 128)
  29. pg_num = WCD9360_PAGE_128;
  30. else if (pg_num == 80)
  31. pg_num = WCD9360_PAGE_80;
  32. else if (pg_num > 15)
  33. return false;
  34. reg_tbl = wcd9360_reg[pg_num];
  35. reg_offset = reg & 0xFF;
  36. if (reg_tbl && reg_tbl[reg_offset])
  37. return true;
  38. else
  39. return false;
  40. }
  41. static bool wcd9360_is_volatile_register(struct device *dev, unsigned int reg)
  42. {
  43. u8 pg_num, reg_offset;
  44. const u8 *reg_tbl = NULL;
  45. pg_num = reg >> 8;
  46. if (pg_num == 1 || pg_num == 2 ||
  47. pg_num == 6 || pg_num == 7)
  48. return true;
  49. else if (pg_num == 128)
  50. pg_num = WCD9360_PAGE_128;
  51. else if (pg_num == 80)
  52. pg_num = WCD9360_PAGE_80;
  53. else if (pg_num > 15)
  54. return false;
  55. reg_tbl = wcd9360_reg[pg_num];
  56. reg_offset = reg & 0xFF;
  57. if (reg_tbl && reg_tbl[reg_offset] == WCD9360_RO)
  58. return true;
  59. if ((reg >= WCD9360_CODEC_RPM_RST_CTL) &&
  60. (reg <= WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN))
  61. return true;
  62. if ((reg >= WCD9360_CDC_ANC0_IIR_COEFF_1_CTL) &&
  63. (reg <= WCD9360_CDC_ANC0_FB_GAIN_CTL))
  64. return true;
  65. if ((reg >= WCD9360_CODEC_CPR_WR_DATA_0) &&
  66. (reg <= WCD9360_CODEC_CPR_RD_DATA_3))
  67. return true;
  68. /*
  69. * Need to mark volatile for registers that are writable but
  70. * only few bits are read-only
  71. */
  72. switch (reg) {
  73. case WCD9360_CODEC_RPM_CLK_BYPASS:
  74. case WCD9360_CODEC_RPM_CLK_GATE:
  75. case WCD9360_CODEC_RPM_CLK_MCLK_CFG:
  76. case WCD9360_CODEC_CPR_SVS_CX_VDD:
  77. case WCD9360_CODEC_CPR_SVS2_CX_VDD:
  78. case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL:
  79. case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL:
  80. return true;
  81. }
  82. return false;
  83. }
  84. struct regmap_config wcd9360_regmap_config = {
  85. .reg_bits = 16,
  86. .val_bits = 8,
  87. .cache_type = REGCACHE_RBTREE,
  88. .reg_defaults = wcd9360_defaults,
  89. .num_reg_defaults = ARRAY_SIZE(wcd9360_defaults),
  90. .max_register = WCD9360_MAX_REGISTER,
  91. .volatile_reg = wcd9360_is_volatile_register,
  92. .readable_reg = wcd9360_is_readable_register,
  93. .can_multi_write = true,
  94. };