internal.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef WSA884X_INTERNAL_H
  7. #define WSA884X_INTERNAL_H
  8. #include <asoc/wcd-irq.h>
  9. #include "wsa884x.h"
  10. #include "wsa884x-registers.h"
  11. #ifdef CONFIG_DEBUG_FS
  12. #include <linux/debugfs.h>
  13. #include <linux/uaccess.h>
  14. #define SWR_SLV_MAX_REG_ADDR 0x2009
  15. #define SWR_SLV_START_REG_ADDR 0x40
  16. #define SWR_SLV_MAX_BUF_LEN 20
  17. #define BYTES_PER_LINE 12
  18. #define SWR_SLV_RD_BUF_LEN 8
  19. #define SWR_SLV_WR_BUF_LEN 32
  20. #define SWR_SLV_MAX_DEVICES 2
  21. #endif /* CONFIG_DEBUG_FS */
  22. #define WSA884X_DRV_NAME "wsa884x-codec"
  23. #define WSA884X_NUM_RETRY 5
  24. #define WSA884X_VERSION_ENTRY_SIZE 32
  25. #define WSA884X_VARIANT_ENTRY_SIZE 32
  26. #define WSA884X_VERSION_1_0 0
  27. enum {
  28. G_21_DB = 0,
  29. G_19P5_DB,
  30. G_18_DB,
  31. G_16P5_DB,
  32. G_15_DB,
  33. G_13P5_DB,
  34. G_12_DB,
  35. G_10P5_DB,
  36. G_9_DB,
  37. G_7P5_DB,
  38. G_6_DB,
  39. G_4P5_DB,
  40. G_3_DB,
  41. G_1P5_DB,
  42. G_0_DB,
  43. G_M1P5_DB,
  44. G_M3_DB,
  45. G_M4P5_DB,
  46. G_M6_DB,
  47. G_MAX_DB,
  48. };
  49. enum {
  50. PA_AUX_DISABLE = 0,
  51. PA_AUX_M6_DB = 3,
  52. PA_AUX_M4P5_DB = 4,
  53. PA_AUX_M3_DB = 5,
  54. PA_AUX_M1P5_DB = 6,
  55. PA_AUX_0_DB = 7,
  56. PA_AUX_7P5_DB = 8,
  57. PA_AUX_12_DB = 9,
  58. PA_AUX_18_DB = 0xA,
  59. };
  60. enum {
  61. ISENSE_6_DB = 0,
  62. ISENSE_12_DB,
  63. ISENSE_15_DB,
  64. ISENSE_18_DB
  65. };
  66. enum {
  67. VSENSE_M12_DB = 0,
  68. VSENSE_M15_DB,
  69. VSENSE_M18_DB,
  70. VSENSE_M21_DB,
  71. VSENSE_M24_DB
  72. };
  73. enum {
  74. DISABLE = 0,
  75. ENABLE,
  76. };
  77. enum {
  78. SPEAKER,
  79. RECEIVER,
  80. MAX_DEV_MODE
  81. };
  82. enum {
  83. SWR_DAC_PORT = 0,
  84. SWR_COMP_PORT,
  85. SWR_BOOST_PORT,
  86. SWR_PBR_PORT,
  87. SWR_VISENSE_PORT,
  88. SWR_CPS_PORT
  89. };
  90. enum {
  91. EXT_ABOVE_3S,
  92. CONFIG_1S,
  93. CONFIG_2S,
  94. CONFIG_3S,
  95. EXT_1S,
  96. EXT_2S,
  97. EXT_3S,
  98. CONFIG_MAX,
  99. };
  100. enum {
  101. WSA_4_OHMS = 0,
  102. WSA_6_OHMS,
  103. WSA_8_OHMS,
  104. WSA_32_OHMS,
  105. WSA_MAX_OHMS,
  106. };
  107. struct wsa_ctrl_platform_data {
  108. void *handle;
  109. int (*update_wsa_event)(void *handle, u16 event, u32 data);
  110. int (*register_notifier)(void *handle, struct notifier_block *nblock,
  111. bool enable);
  112. };
  113. struct swr_port {
  114. u8 port_id;
  115. u8 ch_mask;
  116. u32 ch_rate;
  117. u8 num_ch;
  118. u8 port_type;
  119. };
  120. extern struct regmap_config wsa884x_regmap_config;
  121. /* Aux gain from system gain */
  122. static const u8 pa_aux_no_comp[G_MAX_DB] = {
  123. PA_AUX_18_DB, /* G_21_DB */
  124. PA_AUX_18_DB, /* G_19P5_DB */
  125. PA_AUX_18_DB, /* G_18_DB */
  126. PA_AUX_18_DB, /* G_16P5_DB */
  127. PA_AUX_18_DB, /* G_15_DB */
  128. PA_AUX_12_DB, /* G_13P5_DB */
  129. PA_AUX_12_DB, /* G_12_DB */
  130. PA_AUX_12_DB, /* G_10P5_DB */
  131. PA_AUX_7P5_DB, /* G_9_DB */
  132. PA_AUX_7P5_DB, /* G_7P5_DB */
  133. PA_AUX_7P5_DB, /* G_6_DB */
  134. PA_AUX_7P5_DB, /* G_4P5_DB */
  135. PA_AUX_0_DB, /* G_3_DB */
  136. PA_AUX_0_DB, /* G_1P5_DB */
  137. PA_AUX_0_DB, /* G_0_DB */
  138. PA_AUX_M1P5_DB,/* G_M1P5_DB */
  139. PA_AUX_M3_DB, /* G_M3_DB */
  140. PA_AUX_M4P5_DB,/* G_M4P5_DB */
  141. PA_AUX_M6_DB /* G_M6_DB */
  142. };
  143. /*
  144. * Isense data indexed by system_gain and rload
  145. * WSA_4_OHMS, WSA_6_OHMS, WSA_8_OHMS, WSA_32_OHMS
  146. */
  147. static const u8 isense_gain_data[G_MAX_DB][WSA_MAX_OHMS] = {
  148. {ISENSE_6_DB, ISENSE_6_DB, ISENSE_12_DB, ISENSE_18_DB}, /*G_21_DB */
  149. {ISENSE_6_DB, ISENSE_6_DB, ISENSE_12_DB, ISENSE_18_DB}, /*G_19P5_DB */
  150. {ISENSE_6_DB, ISENSE_6_DB, ISENSE_15_DB, ISENSE_18_DB}, /*G_18_DB */
  151. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_15_DB, ISENSE_18_DB}, /*G_16P5_DB */
  152. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_15_DB */
  153. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_13P5_DB */
  154. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_12_DB */
  155. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_10P5_DB */
  156. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_9_DB */
  157. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_7P5_DB */
  158. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_6_DB */
  159. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_4P5_DB */
  160. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_3_DB */
  161. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_1P5_DB */
  162. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_0_DB */
  163. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M1P5_DB */
  164. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M3_DB */
  165. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M4P5_DB */
  166. {ISENSE_12_DB, ISENSE_12_DB, ISENSE_18_DB, ISENSE_18_DB}, /*G_M6_DB */
  167. };
  168. /* Vsense gain from system gain */
  169. static const u8 vsense_gain_data[G_MAX_DB] = {
  170. VSENSE_M24_DB, /* G_21_DB */
  171. VSENSE_M24_DB, /* G_19P5_DB */
  172. VSENSE_M21_DB, /* G_18_DB */
  173. VSENSE_M21_DB, /* G_16P5_DB */
  174. VSENSE_M18_DB, /* G_15_DB */
  175. VSENSE_M18_DB, /* G_13P5_DB */
  176. VSENSE_M15_DB, /* G_12_DB */
  177. VSENSE_M15_DB, /* G_10P5_DB */
  178. VSENSE_M12_DB, /* G_9_DB */
  179. VSENSE_M12_DB, /* G_7P5_DB */
  180. VSENSE_M12_DB, /* G_6_DB */
  181. VSENSE_M12_DB, /* G_4P5_DB */
  182. VSENSE_M12_DB, /* G_3_DB */
  183. VSENSE_M12_DB, /* G_1P5_DB */
  184. VSENSE_M12_DB, /* G_0_DB */
  185. VSENSE_M12_DB, /* G_M1P5_DB */
  186. VSENSE_M12_DB, /* G_M3_DB */
  187. VSENSE_M12_DB, /* G_M4P5_DB */
  188. VSENSE_M12_DB /* G_M6_DB */
  189. };
  190. /*
  191. * PBR Thresholds from system_gain, bat_cfg, and rload
  192. * EXT_ABOVE_3S: WSA_4_OHMS, WSA_6_OHMS, WSA_8_OHMS, WSA_32_OHMS, CONFIG_1S: ...
  193. * Values are X100 to avoid 'float' issues, divided in WSA884X_VTH_TO_REG macro
  194. */
  195. static const int pbr_vth1_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  196. /* G_21_DB */
  197. {
  198. {0, 0, 0, 0}, {2000, 2000, 863, 0},
  199. {2000, 2000, 1098, 0}, {2000, 2000, 1404, 0}
  200. },
  201. /* G_19P5_DB */
  202. {
  203. {0, 0, 0, 0}, {2000, 769, 2000, 0},
  204. {2000, 957, 2000, 0}, {2000, 1216, 2000, 0}
  205. },
  206. /* G_18_DB */
  207. {
  208. {0, 0, 0, 0}, {643, 2000, 2000, 0},
  209. {808, 2000, 2000, 0}, {1027, 2000, 2000, 0}
  210. },
  211. /* G_16P5_DB */
  212. {
  213. {0, 0, 0, 0}, {1575, 1575, 1575, 0},
  214. {1575, 1575, 1575, 0}, {1575, 1575, 1575, 0}
  215. },
  216. /* G_15_DB */
  217. {
  218. {0, 0, 0, 0}, {1400, 1400, 1400, 0},
  219. {1400, 1400, 1400, 0}, {1400, 1400, 1400, 0}
  220. },
  221. /* G_13P5_DB */
  222. {
  223. {0, 0, 0, 0}, {1200, 1200, 1200, 0},
  224. {1200, 1200, 1200, 0}, {1200, 1200, 1200, 0}
  225. },
  226. /* G_12_DB */
  227. {
  228. {0, 0, 0, 0}, {1050, 1050, 1050, 0},
  229. {1050, 1050, 1050, 0}, {1050, 1050, 1050, 0}
  230. },
  231. };
  232. static const int pbr_vth2_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  233. { {0, 0, 0, 0}, {0, 0, 918, 0}, {0, 0, 1161, 0}, {0, 0, 1443, 0} }, /* G_21_DB */
  234. { {0, 0, 0, 0}, {0, 824, 0, 0}, {0, 988, 0, 0}, {0, 1231, 0, 0} }, /* G_19P5_DB */
  235. { {0, 0, 0, 0}, {667, 0, 0, 0}, {839, 0, 0, 0}, {1035, 0, 0, 0} }, /* G_18_DB */
  236. };
  237. static const int pbr_vth3_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  238. { {0, 0, 0, 0}, {0, 0, 980, 0}, {0, 0, 1224, 0}, {0, 0, 1482, 0} }, /* G_21_DB */
  239. { {0, 0, 0, 0}, {0, 878, 0, 0}, {0, 1051, 0, 0}, {0, 1278, 0, 0} }, /* G_19P5_DB */
  240. { {0, 0, 0, 0}, {722, 0, 0, 0}, {894, 0, 0, 0}, {1075, 0, 0, 0} }, /* G_18_DB */
  241. };
  242. static const int pbr_vth4_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  243. { {0, 0, 0, 0}, {0, 0, 1043, 0}, {0, 0, 1278, 0}, {0, 0, 1522, 0} }, /* G_21_DB */
  244. { {0, 0, 0, 0}, {0, 933, 0, 0}, {0, 1082, 0, 0}, {0, 1294, 0, 0} }, /* G_19P5_DB */
  245. { {0, 0, 0, 0}, {753, 0, 0, 0}, {925, 0, 0, 0}, {1090, 0, 0, 0} }, /* G_18_DB */
  246. };
  247. static const int pbr_vth5_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  248. { {0, 0, 0, 0}, {0, 0, 1098, 0}, {0, 0, 1341, 0}, {0, 0, 1561, 0} }, /* G_21_DB */
  249. { {0, 0, 0, 0}, {0, 988, 0, 0}, {0, 1137, 0, 0}, {0, 1333, 0, 0} }, /* G_19P5_DB */
  250. { {0, 0, 0, 0}, {800, 0, 0, 0}, {973, 0, 0, 0}, {1129, 0, 0, 0} }, /* G_18_DB */
  251. };
  252. static const int pbr_vth6_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  253. { {0, 0, 0, 0}, {0, 0, 1137, 0}, {0, 0, 1380, 0}, {0, 0, 1584, 0} }, /* G_21_DB */
  254. { {0, 0, 0, 0}, {0, 1027, 0, 0}, {0, 1176, 0, 0}, {0, 1349, 0, 0} }, /* G_19P5_DB */
  255. { {0, 0, 0, 0}, {831, 0, 0, 0}, {996, 0, 0, 0}, {1137, 0, 0, 0} }, /* G_18_DB */
  256. };
  257. static const int pbr_vth7_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  258. { {0, 0, 0, 0}, {0, 0, 1184, 0}, {0, 0, 1420, 0}, {0, 0, 1600, 0} }, /* G_21_DB */
  259. { {0, 0, 0, 0}, {0, 1059, 0, 0}, {0, 1208, 0, 0}, {0, 1365, 0, 0} }, /* G_19P5_DB */
  260. { {0, 0, 0, 0}, {918, 0, 0, 0}, {1051, 0, 0, 0}, {1153, 0, 0, 0} }, /* G_18_DB */
  261. };
  262. static const int pbr_vth8_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  263. { {0, 0, 0, 0}, {0, 0, 1239, 0}, {0, 0, 1482, 0}, {0, 0, 1639, 0} }, /* G_21_DB */
  264. { {0, 0, 0, 0}, {0, 1114, 0, 0}, {0, 1263, 0, 0}, {0, 1380, 0, 0} }, /* G_19P5_DB */
  265. { {0, 0, 0, 0}, {988, 0, 0, 0}, {1114, 0, 0, 0}, {1192, 0, 0, 0} }, /* G_18_DB */
  266. };
  267. static const int pbr_vth9_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  268. { {0, 0, 0, 0}, {0, 0, 1278, 0}, {0, 0, 1522, 0}, {0, 0, 1663, 0} }, /* G_21_DB */
  269. { {0, 0, 0, 0}, {0, 1192, 0, 0}, {0, 1302, 0, 0}, {0, 1420, 0, 0} }, /* G_19P5_DB */
  270. { {0, 0, 0, 0}, {1051, 0, 0, 0}, {1184, 0, 0, 0}, {1224, 0, 0, 0} }, /* G_18_DB */
  271. };
  272. static const int pbr_vth10_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  273. { {0, 0, 0, 0}, {0, 0, 1380, 0}, {0, 0, 1600, 0}, {0, 0, 1686, 0} }, /* G_21_DB */
  274. { {0, 0, 0, 0}, {0, 1286, 0, 0}, {0, 1404, 0, 0}, {0, 1459, 0, 0} }, /* G_19P5_DB */
  275. { {0, 0, 0, 0}, {1145, 0, 0, 0}, {1255, 0, 0, 0}, {1278, 0, 0, 0} }, /* G_18_DB */
  276. };
  277. static const int pbr_vth11_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  278. { {0, 0, 0, 0}, {0, 0, 1482, 0}, {0, 0, 1686, 0}, {0, 0, 1725, 0} }, /* G_21_DB */
  279. { {0, 0, 0, 0}, {0, 1357, 0, 0}, {0, 1498, 0, 0}, {0, 1498, 0, 0} }, /* G_19P5_DB */
  280. { {0, 0, 0, 0}, {1208, 0, 0, 0}, {1318, 0, 0, 0}, {1341, 0, 0, 0} }, /* G_18_DB */
  281. };
  282. static const int pbr_vth12_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  283. { {0, 0, 0, 0}, {0, 0, 1584, 0}, {0, 0, 1765, 0}, {0, 0, 1780, 0} }, /* G_21_DB */
  284. { {0, 0, 0, 0}, {0, 1514, 0, 0}, {0, 1600, 0, 0}, {0, 1529, 0, 0} }, /* G_19P5_DB */
  285. { {0, 0, 0, 0}, {1427, 0, 0, 0}, {1467, 0, 0, 0}, {1404, 0, 0, 0} }, /* G_18_DB */
  286. };
  287. static const int pbr_vth13_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  288. { {0, 0, 0, 0}, {0, 0, 1663, 0}, {0, 0, 1843, 0}, {0, 0, 1867, 0} }, /* G_21_DB */
  289. { {0, 0, 0, 0}, {0, 1671, 0, 0}, {0, 1702, 0, 0}, {0, 1569, 0, 0} }, /* G_19P5_DB */
  290. { {0, 0, 0, 0}, {1561, 0, 0, 0}, {1616, 0, 0, 0}, {1475, 0, 0, 0} }, /* G_18_DB */
  291. };
  292. static const int pbr_vth14_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  293. { {0, 0, 0, 0}, {0, 0, 1780, 0}, {0, 0, 1922, 0}, {0, 0, 1945, 0} }, /* G_21_DB */
  294. { {0, 0, 0, 0}, {0, 1827, 0, 0}, {0, 1835, 0, 0}, {0, 1631, 0, 0} }, /* G_19P5_DB */
  295. { {0, 0, 0, 0}, {1741, 0, 0, 0}, {1788, 0, 0, 0}, {1537, 0, 0, 0} }, /* G_18_DB */
  296. };
  297. static const int pbr_vth15_data[G_MAX_DB][CONFIG_MAX][WSA_MAX_OHMS] = {
  298. { {0, 0, 0, 0}, {0, 0, 2000, 0}, {0, 0, 2000, 0}, {0, 0, 2000, 0} }, /* G_21_DB */
  299. { {0, 0, 0, 0}, {0, 2000, 0, 0}, {0, 2000, 0, 0}, {0, 1686, 0, 0} }, /* G_19P5_DB */
  300. { {0, 0, 0, 0}, {2000, 0, 0, 0}, {2000, 0, 0, 0}, {1600, 0, 0, 0} }, /* G_18_DB */
  301. };
  302. /*
  303. * Private data Structure for wsa884x. All parameters related to
  304. * WSA884X codec needs to be defined here.
  305. */
  306. struct wsa884x_priv {
  307. struct regmap *regmap;
  308. struct device *dev;
  309. struct swr_device *swr_slave;
  310. struct snd_soc_component *component;
  311. bool comp_enable;
  312. bool visense_enable;
  313. bool cps_enable;
  314. bool pbr_enable;
  315. bool ext_vdd_spk;
  316. bool dapm_bias_off;
  317. struct swr_port port[WSA884X_MAX_SWR_PORTS];
  318. int global_pa_cnt;
  319. int dev_mode;
  320. int comp_offset;
  321. struct mutex res_lock;
  322. struct snd_info_entry *entry;
  323. struct snd_info_entry *version_entry;
  324. struct snd_info_entry *variant_entry;
  325. struct device_node *wsa_rst_np;
  326. int pa_mute;
  327. int curr_temp;
  328. int variant;
  329. int version;
  330. u8 pa_gain;
  331. u32 bat_cfg;
  332. u32 rload;
  333. u8 system_gain;
  334. u32 sys_gains[MAX_DEV_MODE * 2];
  335. bool default_dev_mode;
  336. int min_gain;
  337. int pa_aux_gain;
  338. u8 dev_index;
  339. struct irq_domain *virq;
  340. struct wcd_irq_info irq_info;
  341. struct swr_port_params wsa_port_params[SWR_UC_MAX][WSA884X_MAX_SWR_PORTS];
  342. struct swr_dev_frame_config swr_wsa_port_params[SWR_UC_MAX];
  343. #ifdef CONFIG_DEBUG_FS
  344. struct dentry *debugfs_dent;
  345. struct dentry *debugfs_peek;
  346. struct dentry *debugfs_poke;
  347. struct dentry *debugfs_reg_dump;
  348. unsigned int read_data;
  349. #endif
  350. struct device_node *parent_np;
  351. struct device_node *macro_np;
  352. struct platform_device *parent_dev;
  353. struct platform_device *macro_dev;
  354. struct notifier_block parent_nblock;
  355. void *handle;
  356. int (*register_notifier)(void *handle,
  357. struct notifier_block *nblock, bool enable);
  358. struct cdc_regulator *regulator;
  359. int num_supplies;
  360. struct regulator_bulk_data *supplies;
  361. unsigned long status_mask;
  362. unsigned long port_status_mask;
  363. struct snd_soc_dai_driver *dai_driver;
  364. struct snd_soc_component_driver *driver;
  365. int noise_gate_mode;
  366. };
  367. #endif /* WSA884X_INTERNAL_H */