marimba-codec.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. /* Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/module.h>
  14. #include <linux/delay.h>
  15. #include <linux/err.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/mfd/msm-adie-codec.h>
  18. #include <linux/mfd/marimba.h>
  19. #include <linux/debugfs.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/string.h>
  22. #define MARIMBA_CDC_RX_CTL 0x81
  23. #define MARIMBA_CDC_RX_CTL_ST_EN_MASK 0x20
  24. #define MARIMBA_CDC_RX_CTL_ST_EN_SHFT 0x5
  25. #define MARIMBA_CODEC_CDC_LRXG 0x84
  26. #define MARIMBA_CODEC_CDC_RRXG 0x85
  27. #define MARIMBA_CODEC_CDC_LTXG 0x86
  28. #define MARIMBA_CODEC_CDC_RTXG 0x87
  29. #define MAX_MDELAY_US 2000
  30. #define MIN_MDELAY_US 1000
  31. struct adie_codec_path {
  32. struct adie_codec_dev_profile *profile;
  33. struct adie_codec_register_image img;
  34. u32 hwsetting_idx;
  35. u32 stage_idx;
  36. u32 curr_stage;
  37. };
  38. static struct adie_codec_register adie_codec_tx_regs[] = {
  39. { 0x04, 0xc0, 0x8C },
  40. { 0x0D, 0xFF, 0x00 },
  41. { 0x0E, 0xFF, 0x00 },
  42. { 0x0F, 0xFF, 0x00 },
  43. { 0x10, 0xF8, 0x68 },
  44. { 0x11, 0xFE, 0x00 },
  45. { 0x12, 0xFE, 0x00 },
  46. { 0x13, 0xFF, 0x58 },
  47. { 0x14, 0xFF, 0x00 },
  48. { 0x15, 0xFE, 0x00 },
  49. { 0x16, 0xFF, 0x00 },
  50. { 0x1A, 0xFF, 0x00 },
  51. { 0x80, 0x01, 0x00 },
  52. { 0x82, 0x7F, 0x18 },
  53. { 0x83, 0x1C, 0x00 },
  54. { 0x86, 0xFF, 0xAC },
  55. { 0x87, 0xFF, 0xAC },
  56. { 0x89, 0xFF, 0xFF },
  57. { 0x8A, 0xF0, 0x30 }
  58. };
  59. static struct adie_codec_register adie_codec_rx_regs[] = {
  60. { 0x23, 0xF8, 0x00 },
  61. { 0x24, 0x6F, 0x00 },
  62. { 0x25, 0x7F, 0x00 },
  63. { 0x26, 0xFC, 0x00 },
  64. { 0x28, 0xFE, 0x00 },
  65. { 0x29, 0xFE, 0x00 },
  66. { 0x33, 0xFF, 0x00 },
  67. { 0x34, 0xFF, 0x00 },
  68. { 0x35, 0xFC, 0x00 },
  69. { 0x36, 0xFE, 0x00 },
  70. { 0x37, 0xFE, 0x00 },
  71. { 0x38, 0xFE, 0x00 },
  72. { 0x39, 0xF0, 0x00 },
  73. { 0x3A, 0xFF, 0x0A },
  74. { 0x3B, 0xFC, 0xAC },
  75. { 0x3C, 0xFC, 0xAC },
  76. { 0x3D, 0xFF, 0x55 },
  77. { 0x3E, 0xFF, 0x55 },
  78. { 0x3F, 0xCF, 0x00 },
  79. { 0x40, 0x3F, 0x00 },
  80. { 0x41, 0x3F, 0x00 },
  81. { 0x42, 0xFF, 0x00 },
  82. { 0x43, 0xF7, 0x00 },
  83. { 0x43, 0xF7, 0x00 },
  84. { 0x43, 0xF7, 0x00 },
  85. { 0x43, 0xF7, 0x00 },
  86. { 0x44, 0xF7, 0x00 },
  87. { 0x45, 0xFF, 0x00 },
  88. { 0x46, 0xFF, 0x00 },
  89. { 0x47, 0xF7, 0x00 },
  90. { 0x48, 0xF7, 0x00 },
  91. { 0x49, 0xFF, 0x00 },
  92. { 0x4A, 0xFF, 0x00 },
  93. { 0x80, 0x02, 0x00 },
  94. { 0x81, 0xFF, 0x4C },
  95. { 0x83, 0x23, 0x00 },
  96. { 0x84, 0xFF, 0xAC },
  97. { 0x85, 0xFF, 0xAC },
  98. { 0x88, 0xFF, 0xFF },
  99. { 0x8A, 0x0F, 0x03 },
  100. { 0x8B, 0xFF, 0xAC },
  101. { 0x8C, 0x03, 0x01 },
  102. { 0x8D, 0xFF, 0x00 },
  103. { 0x8E, 0xFF, 0x00 }
  104. };
  105. static struct adie_codec_register adie_codec_lb_regs[] = {
  106. { 0x2B, 0x8F, 0x02 },
  107. { 0x2C, 0x8F, 0x02 }
  108. };
  109. struct adie_codec_state {
  110. struct adie_codec_path path[ADIE_CODEC_MAX];
  111. u32 ref_cnt;
  112. struct marimba *pdrv_ptr;
  113. struct marimba_codec_platform_data *codec_pdata;
  114. struct mutex lock;
  115. };
  116. static struct adie_codec_state adie_codec;
  117. /* Array containing write details of Tx and RX Digital Volume
  118. Tx and Rx and both the left and right channel use the same data
  119. */
  120. u8 adie_codec_rx_tx_dig_vol_data[] = {
  121. 0x81, 0x82, 0x83, 0x84,
  122. 0x85, 0x86, 0x87, 0x88,
  123. 0x89, 0x8a, 0x8b, 0x8c,
  124. 0x8d, 0x8e, 0x8f, 0x90,
  125. 0x91, 0x92, 0x93, 0x94,
  126. 0x95, 0x96, 0x97, 0x98,
  127. 0x99, 0x9a, 0x9b, 0x9c,
  128. 0x9d, 0x9e, 0x9f, 0xa0,
  129. 0xa1, 0xa2, 0xa3, 0xa4,
  130. 0xa5, 0xa6, 0xa7, 0xa8,
  131. 0xa9, 0xaa, 0xab, 0xac,
  132. 0xad, 0xae, 0xaf, 0xb0,
  133. 0xb1, 0xb2, 0xb3, 0xb4,
  134. 0xb5, 0xb6, 0xb7, 0xb8,
  135. 0xb9, 0xba, 0xbb, 0xbc,
  136. 0xbd, 0xbe, 0xbf, 0xc0,
  137. 0xc1, 0xc2, 0xc3, 0xc4,
  138. 0xc5, 0xc6, 0xc7, 0xc8,
  139. 0xc9, 0xca, 0xcb, 0xcc,
  140. 0xcd, 0xce, 0xcf, 0xd0,
  141. 0xd1, 0xd2, 0xd3, 0xd4,
  142. 0xd5, 0xd6, 0xd7, 0xd8,
  143. 0xd9, 0xda, 0xdb, 0xdc,
  144. 0xdd, 0xde, 0xdf, 0xe0,
  145. 0xe1, 0xe2, 0xe3, 0xe4,
  146. 0xe5, 0xe6, 0xe7, 0xe8,
  147. 0xe9, 0xea, 0xeb, 0xec,
  148. 0xed, 0xee, 0xf0, 0xf1,
  149. 0xf2, 0xf3, 0xf4, 0xf5,
  150. 0xf6, 0xf7, 0xf8, 0xf9,
  151. 0xfa, 0xfb, 0xfc, 0xfd,
  152. 0xfe, 0xff, 0x00, 0x01,
  153. 0x02, 0x03, 0x04, 0x05,
  154. 0x06, 0x07, 0x08, 0x09,
  155. 0x0a, 0x0b, 0x0c, 0x0d,
  156. 0x0e, 0x0f, 0x10, 0x11,
  157. 0x12, 0x13, 0x14, 0x15,
  158. 0x16, 0x17, 0x18, 0x19,
  159. 0x1a, 0x1b, 0x1c, 0x1d,
  160. 0x1e, 0x1f, 0x20, 0x21,
  161. 0x22, 0x23, 0x24, 0x25,
  162. 0x26, 0x27, 0x28, 0x29,
  163. 0x2a, 0x2b, 0x2c, 0x2d,
  164. 0x2e, 0x2f, 0x30, 0x31,
  165. 0x32, 0x33, 0x34, 0x35,
  166. 0x36, 0x37, 0x38, 0x39,
  167. 0x3a, 0x3b, 0x3c, 0x3d,
  168. 0x3e, 0x3f, 0x40, 0x41,
  169. 0x42, 0x43, 0x44, 0x45,
  170. 0x46, 0x47, 0x48, 0x49,
  171. 0x4a, 0x4b, 0x4c, 0x4d,
  172. 0x4e, 0x4f, 0x50, 0x51,
  173. 0x52, 0x53, 0x54, 0x55,
  174. 0x56, 0x57, 0x58, 0x59,
  175. 0x5a, 0x5b, 0x5c, 0x5d,
  176. 0x5e, 0x5f, 0x60, 0x61,
  177. 0x62, 0x63, 0x64, 0x65,
  178. 0x66, 0x67, 0x68, 0x69,
  179. 0x6a, 0x6b, 0x6c, 0x6d,
  180. 0x6e, 0x6f, 0x70, 0x71,
  181. 0x72, 0x73, 0x74, 0x75,
  182. 0x76, 0x77, 0x78, 0x79,
  183. 0x7a, 0x7b, 0x7c, 0x7d,
  184. 0x7e, 0x7f
  185. };
  186. enum adie_vol_type {
  187. ADIE_CODEC_RX_DIG_VOL,
  188. ADIE_CODEC_TX_DIG_VOL,
  189. ADIE_CODEC_VOL_TYPE_MAX
  190. };
  191. struct adie_codec_ch_vol_cntrl {
  192. u8 codec_reg;
  193. u8 codec_mask;
  194. u8 *vol_cntrl_data;
  195. };
  196. struct adie_codec_vol_cntrl_data {
  197. enum adie_vol_type vol_type;
  198. /* Jump length used while doing writes in incremental fashion */
  199. u32 jump_length;
  200. s32 min_mb; /* Min Db applicable to the vol control */
  201. s32 max_mb; /* Max Db applicable to the vol control */
  202. u32 step_in_mb;
  203. u32 steps; /* No of steps allowed for this vol type */
  204. struct adie_codec_ch_vol_cntrl *ch_vol_cntrl_info;
  205. };
  206. static struct adie_codec_ch_vol_cntrl adie_codec_rx_vol_cntrl[] = {
  207. {MARIMBA_CODEC_CDC_LRXG, 0xff, adie_codec_rx_tx_dig_vol_data},
  208. {MARIMBA_CODEC_CDC_RRXG, 0xff, adie_codec_rx_tx_dig_vol_data}
  209. };
  210. static struct adie_codec_ch_vol_cntrl adie_codec_tx_vol_cntrl[] = {
  211. {MARIMBA_CODEC_CDC_LTXG, 0xff, adie_codec_rx_tx_dig_vol_data},
  212. {MARIMBA_CODEC_CDC_RTXG, 0xff, adie_codec_rx_tx_dig_vol_data}
  213. };
  214. static struct adie_codec_vol_cntrl_data adie_codec_vol_cntrl[] = {
  215. {ADIE_CODEC_RX_DIG_VOL, 5100, -12700, 12700, 100, 255,
  216. adie_codec_rx_vol_cntrl},
  217. {ADIE_CODEC_TX_DIG_VOL, 5100, -12700, 12700, 100, 255,
  218. adie_codec_tx_vol_cntrl}
  219. };
  220. static int adie_codec_write(u8 reg, u8 mask, u8 val)
  221. {
  222. int rc;
  223. rc = marimba_write_bit_mask(adie_codec.pdrv_ptr, reg, &val, 1, mask);
  224. if (IS_ERR_VALUE(rc)) {
  225. pr_err("%s: fail to write reg %x\n", __func__, reg);
  226. return -EIO;
  227. }
  228. pr_debug("%s: write reg %x val %x\n", __func__, reg, val);
  229. return 0;
  230. }
  231. static int adie_codec_read(u8 reg, u8 *val)
  232. {
  233. return marimba_read(adie_codec.pdrv_ptr, reg, val, 1);
  234. }
  235. static int adie_codec_read_dig_vol(enum adie_vol_type vol_type, u32 chan_index,
  236. u32 *cur_index)
  237. {
  238. u32 counter;
  239. u32 size;
  240. u8 reg, mask, cur_val;
  241. int rc;
  242. reg =
  243. adie_codec_vol_cntrl[vol_type].
  244. ch_vol_cntrl_info[chan_index].codec_reg;
  245. mask =
  246. adie_codec_vol_cntrl[vol_type].
  247. ch_vol_cntrl_info[chan_index].codec_mask;
  248. rc = marimba_read(adie_codec.pdrv_ptr, reg, &cur_val, 1);
  249. if (IS_ERR_VALUE(rc)) {
  250. pr_err("%s: fail to read reg %x\n", __func__, reg);
  251. return -EIO;
  252. }
  253. cur_val = cur_val & mask;
  254. pr_debug("%s: reg 0x%x mask 0x%x reg_value = 0x%x"
  255. "vol_type = %d\n", __func__, reg, mask, cur_val, vol_type);
  256. size = adie_codec_vol_cntrl[vol_type].steps;
  257. for (counter = 0; counter <= size; counter++) {
  258. if (adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  259. [chan_index].vol_cntrl_data[counter] == cur_val) {
  260. *cur_index = counter;
  261. return 0;
  262. }
  263. }
  264. pr_err("%s: could not find 0x%x in reg 0x%x values array\n",
  265. __func__, cur_val, reg);
  266. return -EINVAL;;
  267. }
  268. static int adie_codec_set_dig_vol(enum adie_vol_type vol_type, u32 chan_index,
  269. u32 cur_index, u32 target_index)
  270. {
  271. u32 count;
  272. u8 reg, mask, val;
  273. u32 i;
  274. u32 index;
  275. u32 index_jump;
  276. int rc;
  277. index_jump = adie_codec_vol_cntrl[vol_type].jump_length;
  278. reg =
  279. adie_codec_vol_cntrl[vol_type].
  280. ch_vol_cntrl_info[chan_index].codec_reg;
  281. mask =
  282. adie_codec_vol_cntrl[vol_type].
  283. ch_vol_cntrl_info[chan_index].codec_mask;
  284. /* compare the target index with current index */
  285. if (cur_index < target_index) {
  286. /* Volume is being increased loop and increase it in 4-5 steps
  287. */
  288. count = ((target_index - cur_index) * 100 / index_jump);
  289. index = cur_index;
  290. for (i = 1; i <= count; i++) {
  291. index = index + (int)(index_jump / 100);
  292. val =
  293. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  294. [chan_index].vol_cntrl_data[index];
  295. pr_debug("%s: write reg %x val 0x%x\n",
  296. __func__, reg, val);
  297. rc = adie_codec_write(reg, mask, val);
  298. if (rc < 0) {
  299. pr_err("%s: write reg %x val 0x%x failed\n",
  300. __func__, reg, val);
  301. return rc;
  302. }
  303. }
  304. /*do one final write to take it to the target index level */
  305. val =
  306. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  307. [chan_index].vol_cntrl_data[target_index];
  308. pr_debug("%s: write reg %x val 0x%x\n", __func__, reg, val);
  309. rc = adie_codec_write(reg, mask, val);
  310. if (rc < 0) {
  311. pr_err("%s: write reg %x val 0x%x failed\n",
  312. __func__, reg, val);
  313. return rc;
  314. }
  315. } else {
  316. /* Volume is being decreased from the current setting */
  317. index = cur_index;
  318. /* loop and decrease it in 4-5 steps */
  319. count = ((cur_index - target_index) * 100 / index_jump);
  320. for (i = 1; i <= count; i++) {
  321. index = index - (int)(index_jump / 100);
  322. val =
  323. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  324. [chan_index].vol_cntrl_data[index];
  325. pr_debug("%s: write reg %x val 0x%x\n",
  326. __func__, reg, val);
  327. rc = adie_codec_write(reg, mask, val);
  328. if (rc < 0) {
  329. pr_err("%s: write reg %x val 0x%x failed\n",
  330. __func__, reg, val);
  331. return rc;
  332. }
  333. }
  334. /* do one final write to take it to the target index level */
  335. val =
  336. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  337. [chan_index].vol_cntrl_data[target_index];
  338. pr_debug("%s: write reg %x val 0x%x\n", __func__, reg, val);
  339. rc = adie_codec_write(reg, mask, val);
  340. if (rc < 0) {
  341. pr_err("%s: write reg %x val 0x%x failed\n",
  342. __func__, reg, val);
  343. return rc;
  344. }
  345. }
  346. return 0;
  347. }
  348. static int marimba_adie_codec_set_device_digital_volume(
  349. struct adie_codec_path *path_ptr,
  350. u32 num_channels, u32 vol_percentage /* in percentage */)
  351. {
  352. enum adie_vol_type vol_type;
  353. s32 milli_bel;
  354. u32 chan_index;
  355. u32 step_index;
  356. u32 cur_step_index = 0;
  357. if (!path_ptr || (path_ptr->curr_stage !=
  358. ADIE_CODEC_DIGITAL_ANALOG_READY)) {
  359. pr_info("%s: Marimba codec not ready for volume control\n",
  360. __func__);
  361. return -EPERM;
  362. }
  363. if (num_channels > 2) {
  364. pr_err("%s: Marimba codec only supports max two channels\n",
  365. __func__);
  366. return -EINVAL;
  367. }
  368. if (path_ptr->profile->path_type == ADIE_CODEC_RX)
  369. vol_type = ADIE_CODEC_RX_DIG_VOL;
  370. else if (path_ptr->profile->path_type == ADIE_CODEC_TX)
  371. vol_type = ADIE_CODEC_TX_DIG_VOL;
  372. else {
  373. pr_err("%s: invalid device data neither RX nor TX\n",
  374. __func__);
  375. return -EINVAL;
  376. }
  377. milli_bel = ((adie_codec_vol_cntrl[vol_type].max_mb -
  378. adie_codec_vol_cntrl[vol_type].min_mb) *
  379. vol_percentage) / 100;
  380. milli_bel = adie_codec_vol_cntrl[vol_type].min_mb + milli_bel;
  381. pr_debug("%s: milli bell = %d vol_type = %d vol_percentage = %d"
  382. " num_cha = %d \n",
  383. __func__, milli_bel, vol_type, vol_percentage, num_channels);
  384. step_index = ((milli_bel
  385. - adie_codec_vol_cntrl[vol_type].min_mb
  386. + (adie_codec_vol_cntrl[vol_type].step_in_mb / 2))
  387. / adie_codec_vol_cntrl[vol_type].step_in_mb);
  388. for (chan_index = 0; chan_index < num_channels; chan_index++) {
  389. adie_codec_read_dig_vol(vol_type, chan_index, &cur_step_index);
  390. pr_debug("%s: cur_step_index = %u current vol = 0x%x\n",
  391. __func__, cur_step_index,
  392. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  393. [chan_index].vol_cntrl_data[cur_step_index]);
  394. pr_debug("%s: step index = %u new volume = 0x%x\n",
  395. __func__, step_index,
  396. adie_codec_vol_cntrl[vol_type].ch_vol_cntrl_info
  397. [chan_index].vol_cntrl_data[step_index]);
  398. adie_codec_set_dig_vol(vol_type, chan_index, cur_step_index,
  399. step_index);
  400. }
  401. return 0;
  402. }
  403. static int marimba_adie_codec_setpath(struct adie_codec_path *path_ptr,
  404. u32 freq_plan, u32 osr)
  405. {
  406. int rc = 0;
  407. u32 i, freq_idx = 0, freq = 0;
  408. if ((path_ptr->curr_stage != ADIE_CODEC_DIGITAL_OFF) &&
  409. (path_ptr->curr_stage != ADIE_CODEC_FLASH_IMAGE)) {
  410. rc = -EBUSY;
  411. goto error;
  412. }
  413. for (i = 0; i < path_ptr->profile->setting_sz; i++) {
  414. if (path_ptr->profile->settings[i].osr == osr) {
  415. if (path_ptr->profile->settings[i].freq_plan >=
  416. freq_plan) {
  417. if (freq == 0) {
  418. freq = path_ptr->profile->settings[i].
  419. freq_plan;
  420. freq_idx = i;
  421. } else if (path_ptr->profile->settings[i].
  422. freq_plan < freq) {
  423. freq = path_ptr->profile->settings[i].
  424. freq_plan;
  425. freq_idx = i;
  426. }
  427. }
  428. }
  429. }
  430. if (freq_idx >= path_ptr->profile->setting_sz)
  431. rc = -ENODEV;
  432. else {
  433. path_ptr->hwsetting_idx = freq_idx;
  434. path_ptr->stage_idx = 0;
  435. }
  436. error:
  437. return rc;
  438. }
  439. static u32 marimba_adie_codec_freq_supported(
  440. struct adie_codec_dev_profile *profile,
  441. u32 requested_freq)
  442. {
  443. u32 i, rc = -EINVAL;
  444. for (i = 0; i < profile->setting_sz; i++) {
  445. if (profile->settings[i].freq_plan >= requested_freq) {
  446. rc = 0;
  447. break;
  448. }
  449. }
  450. return rc;
  451. }
  452. static int marimba_adie_codec_enable_sidetone(
  453. struct adie_codec_path *rx_path_ptr,
  454. u32 enable)
  455. {
  456. int rc = 0;
  457. pr_debug("%s()\n", __func__);
  458. mutex_lock(&adie_codec.lock);
  459. if (!rx_path_ptr || &adie_codec.path[ADIE_CODEC_RX] != rx_path_ptr) {
  460. pr_err("%s: invalid path pointer\n", __func__);
  461. rc = -EINVAL;
  462. goto error;
  463. } else if (rx_path_ptr->curr_stage !=
  464. ADIE_CODEC_DIGITAL_ANALOG_READY) {
  465. pr_err("%s: bad state\n", __func__);
  466. rc = -EPERM;
  467. goto error;
  468. }
  469. if (enable)
  470. rc = adie_codec_write(MARIMBA_CDC_RX_CTL,
  471. MARIMBA_CDC_RX_CTL_ST_EN_MASK,
  472. (0x1 << MARIMBA_CDC_RX_CTL_ST_EN_SHFT));
  473. else
  474. rc = adie_codec_write(MARIMBA_CDC_RX_CTL,
  475. MARIMBA_CDC_RX_CTL_ST_EN_MASK, 0);
  476. error:
  477. mutex_unlock(&adie_codec.lock);
  478. return rc;
  479. }
  480. static void adie_codec_reach_stage_action(struct adie_codec_path *path_ptr,
  481. u32 stage)
  482. {
  483. u32 iter;
  484. struct adie_codec_register *reg_info;
  485. if (stage == ADIE_CODEC_FLASH_IMAGE) {
  486. /* perform reimage */
  487. for (iter = 0; iter < path_ptr->img.img_sz; iter++) {
  488. reg_info = &path_ptr->img.regs[iter];
  489. adie_codec_write(reg_info->reg,
  490. reg_info->mask, reg_info->val);
  491. }
  492. }
  493. }
  494. static int marimba_adie_codec_proceed_stage(struct adie_codec_path *path_ptr,
  495. u32 state)
  496. {
  497. int rc = 0, loop_exit = 0;
  498. struct adie_codec_action_unit *curr_action;
  499. struct adie_codec_hwsetting_entry *setting;
  500. u8 reg, mask, val;
  501. mutex_lock(&adie_codec.lock);
  502. setting = &path_ptr->profile->settings[path_ptr->hwsetting_idx];
  503. while (!loop_exit) {
  504. curr_action = &setting->actions[path_ptr->stage_idx];
  505. switch (curr_action->type) {
  506. case ADIE_CODEC_ACTION_ENTRY:
  507. ADIE_CODEC_UNPACK_ENTRY(curr_action->action,
  508. reg, mask, val);
  509. adie_codec_write(reg, mask, val);
  510. break;
  511. case ADIE_CODEC_ACTION_DELAY_WAIT:
  512. if (curr_action->action > MAX_MDELAY_US)
  513. msleep(curr_action->action/1000);
  514. else if (curr_action->action < MIN_MDELAY_US)
  515. udelay(curr_action->action);
  516. else
  517. mdelay(curr_action->action/1000);
  518. break;
  519. case ADIE_CODEC_ACTION_STAGE_REACHED:
  520. adie_codec_reach_stage_action(path_ptr,
  521. curr_action->action);
  522. if (curr_action->action == state) {
  523. path_ptr->curr_stage = state;
  524. loop_exit = 1;
  525. }
  526. break;
  527. default:
  528. BUG();
  529. }
  530. path_ptr->stage_idx++;
  531. if (path_ptr->stage_idx == setting->action_sz)
  532. path_ptr->stage_idx = 0;
  533. }
  534. mutex_unlock(&adie_codec.lock);
  535. return rc;
  536. }
  537. static void marimba_codec_bring_up(void)
  538. {
  539. /* bring up sequence for Marimba codec core
  540. * ensure RESET_N = 0 and GDFS_CLAMP_EN=1 -
  541. * set GDFS_EN_FEW=1 then GDFS_EN_REST=1 then
  542. * GDFS_CLAMP_EN = 0 and finally RESET_N = 1
  543. * Marimba codec bring up should use the Marimba
  544. * slave address after which the codec slave
  545. * address can be used
  546. */
  547. /* Bring up codec */
  548. adie_codec_write(0xFF, 0xFF, 0x08);
  549. /* set GDFS_EN_FEW=1 */
  550. adie_codec_write(0xFF, 0xFF, 0x0a);
  551. /* set GDFS_EN_REST=1 */
  552. adie_codec_write(0xFF, 0xFF, 0x0e);
  553. /* set RESET_N=1 */
  554. adie_codec_write(0xFF, 0xFF, 0x07);
  555. adie_codec_write(0xFF, 0xFF, 0x17);
  556. /* enable band gap */
  557. adie_codec_write(0x03, 0xFF, 0x04);
  558. /* dither delay selected and dmic gain stage bypassed */
  559. adie_codec_write(0x8F, 0xFF, 0x44);
  560. }
  561. static void marimba_codec_bring_down(void)
  562. {
  563. adie_codec_write(0xFF, 0xFF, 0x07);
  564. adie_codec_write(0xFF, 0xFF, 0x06);
  565. adie_codec_write(0xFF, 0xFF, 0x0e);
  566. adie_codec_write(0xFF, 0xFF, 0x08);
  567. adie_codec_write(0x03, 0xFF, 0x00);
  568. }
  569. static int marimba_adie_codec_open(struct adie_codec_dev_profile *profile,
  570. struct adie_codec_path **path_pptr)
  571. {
  572. int rc = 0;
  573. mutex_lock(&adie_codec.lock);
  574. if (!profile || !path_pptr) {
  575. rc = -EINVAL;
  576. goto error;
  577. }
  578. if (adie_codec.path[profile->path_type].profile) {
  579. rc = -EBUSY;
  580. goto error;
  581. }
  582. if (!adie_codec.ref_cnt) {
  583. if (adie_codec.codec_pdata &&
  584. adie_codec.codec_pdata->marimba_codec_power) {
  585. rc = adie_codec.codec_pdata->marimba_codec_power(1);
  586. if (rc) {
  587. pr_err("%s: could not power up marimba "
  588. "codec\n", __func__);
  589. goto error;
  590. }
  591. }
  592. marimba_codec_bring_up();
  593. }
  594. adie_codec.path[profile->path_type].profile = profile;
  595. *path_pptr = (void *) &adie_codec.path[profile->path_type];
  596. adie_codec.ref_cnt++;
  597. adie_codec.path[profile->path_type].hwsetting_idx = 0;
  598. adie_codec.path[profile->path_type].curr_stage = ADIE_CODEC_FLASH_IMAGE;
  599. adie_codec.path[profile->path_type].stage_idx = 0;
  600. error:
  601. mutex_unlock(&adie_codec.lock);
  602. return rc;
  603. }
  604. static int marimba_adie_codec_close(struct adie_codec_path *path_ptr)
  605. {
  606. int rc = 0;
  607. mutex_lock(&adie_codec.lock);
  608. if (!path_ptr) {
  609. rc = -EINVAL;
  610. goto error;
  611. }
  612. if (path_ptr->curr_stage != ADIE_CODEC_DIGITAL_OFF)
  613. adie_codec_proceed_stage(path_ptr, ADIE_CODEC_DIGITAL_OFF);
  614. BUG_ON(!adie_codec.ref_cnt);
  615. path_ptr->profile = NULL;
  616. adie_codec.ref_cnt--;
  617. if (!adie_codec.ref_cnt) {
  618. marimba_codec_bring_down();
  619. if (adie_codec.codec_pdata &&
  620. adie_codec.codec_pdata->marimba_codec_power) {
  621. rc = adie_codec.codec_pdata->marimba_codec_power(0);
  622. if (rc) {
  623. pr_err("%s: could not power down marimba "
  624. "codec\n", __func__);
  625. goto error;
  626. }
  627. }
  628. }
  629. error:
  630. mutex_unlock(&adie_codec.lock);
  631. return rc;
  632. }
  633. static const struct adie_codec_operations marimba_adie_ops = {
  634. .codec_id = MARIMBA_ID,
  635. .codec_open = marimba_adie_codec_open,
  636. .codec_close = marimba_adie_codec_close,
  637. .codec_setpath = marimba_adie_codec_setpath,
  638. .codec_proceed_stage = marimba_adie_codec_proceed_stage,
  639. .codec_freq_supported = marimba_adie_codec_freq_supported,
  640. .codec_enable_sidetone = marimba_adie_codec_enable_sidetone,
  641. .codec_set_device_digital_volume =
  642. marimba_adie_codec_set_device_digital_volume,
  643. };
  644. #ifdef CONFIG_DEBUG_FS
  645. static struct dentry *debugfs_marimba_dent;
  646. static struct dentry *debugfs_peek;
  647. static struct dentry *debugfs_poke;
  648. static struct dentry *debugfs_power;
  649. static unsigned char read_data;
  650. static int codec_debug_open(struct inode *inode, struct file *file)
  651. {
  652. file->private_data = inode->i_private;
  653. return 0;
  654. }
  655. static int get_parameters(char *buf, long int *param1, int num_of_par)
  656. {
  657. char *token;
  658. int base, cnt;
  659. token = strsep(&buf, " ");
  660. for (cnt = 0; cnt < num_of_par; cnt++) {
  661. if (token != NULL) {
  662. if ((token[1] == 'x') || (token[1] == 'X'))
  663. base = 16;
  664. else
  665. base = 10;
  666. if (strict_strtoul(token, base, &param1[cnt]) != 0)
  667. return -EINVAL;
  668. token = strsep(&buf, " ");
  669. }
  670. else
  671. return -EINVAL;
  672. }
  673. return 0;
  674. }
  675. static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
  676. size_t count, loff_t *ppos)
  677. {
  678. char lbuf[8];
  679. snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
  680. return simple_read_from_buffer(ubuf, count, ppos, lbuf, strlen(lbuf));
  681. }
  682. static ssize_t codec_debug_write(struct file *filp,
  683. const char __user *ubuf, size_t cnt, loff_t *ppos)
  684. {
  685. char *access_str = filp->private_data;
  686. char lbuf[32];
  687. int rc;
  688. long int param[5];
  689. if (cnt > sizeof(lbuf) - 1)
  690. return -EINVAL;
  691. rc = copy_from_user(lbuf, ubuf, cnt);
  692. if (rc)
  693. return -EFAULT;
  694. lbuf[cnt] = '\0';
  695. if (!strcmp(access_str, "power")) {
  696. if (get_parameters(lbuf, param, 1) == 0) {
  697. switch (param[0]) {
  698. case 1:
  699. adie_codec.codec_pdata->marimba_codec_power(1);
  700. marimba_codec_bring_up();
  701. break;
  702. case 0:
  703. marimba_codec_bring_down();
  704. adie_codec.codec_pdata->marimba_codec_power(0);
  705. break;
  706. default:
  707. rc = -EINVAL;
  708. break;
  709. }
  710. } else
  711. rc = -EINVAL;
  712. } else if (!strcmp(access_str, "poke")) {
  713. /* write */
  714. rc = get_parameters(lbuf, param, 2);
  715. if ((param[0] <= 0xFF) && (param[1] <= 0xFF) &&
  716. (rc == 0))
  717. adie_codec_write(param[0], 0xFF, param[1]);
  718. else
  719. rc = -EINVAL;
  720. } else if (!strcmp(access_str, "peek")) {
  721. /* read */
  722. rc = get_parameters(lbuf, param, 1);
  723. if ((param[0] <= 0xFF) && (rc == 0))
  724. adie_codec_read(param[0], &read_data);
  725. else
  726. rc = -EINVAL;
  727. }
  728. if (rc == 0)
  729. rc = cnt;
  730. else
  731. pr_err("%s: rc = %d\n", __func__, rc);
  732. return rc;
  733. }
  734. static const struct file_operations codec_debug_ops = {
  735. .open = codec_debug_open,
  736. .write = codec_debug_write,
  737. .read = codec_debug_read
  738. };
  739. #endif
  740. static int marimba_codec_probe(struct platform_device *pdev)
  741. {
  742. int rc;
  743. adie_codec.pdrv_ptr = platform_get_drvdata(pdev);
  744. adie_codec.codec_pdata = pdev->dev.platform_data;
  745. if (adie_codec.codec_pdata->snddev_profile_init)
  746. adie_codec.codec_pdata->snddev_profile_init();
  747. /* Register the marimba ADIE operations */
  748. rc = adie_codec_register_codec_operations(&marimba_adie_ops);
  749. #ifdef CONFIG_DEBUG_FS
  750. debugfs_marimba_dent = debugfs_create_dir("msm_adie_codec", 0);
  751. if (!IS_ERR(debugfs_marimba_dent)) {
  752. debugfs_peek = debugfs_create_file("peek",
  753. S_IFREG | S_IRUGO, debugfs_marimba_dent,
  754. (void *) "peek", &codec_debug_ops);
  755. debugfs_poke = debugfs_create_file("poke",
  756. S_IFREG | S_IRUGO, debugfs_marimba_dent,
  757. (void *) "poke", &codec_debug_ops);
  758. debugfs_power = debugfs_create_file("power",
  759. S_IFREG | S_IRUGO, debugfs_marimba_dent,
  760. (void *) "power", &codec_debug_ops);
  761. }
  762. #endif
  763. return rc;
  764. }
  765. static struct platform_driver marimba_codec_driver = {
  766. .probe = marimba_codec_probe,
  767. .driver = {
  768. .name = "marimba_codec",
  769. .owner = THIS_MODULE,
  770. },
  771. };
  772. static int __init marimba_codec_init(void)
  773. {
  774. s32 rc;
  775. rc = platform_driver_register(&marimba_codec_driver);
  776. if (IS_ERR_VALUE(rc))
  777. goto error;
  778. adie_codec.path[ADIE_CODEC_TX].img.regs = adie_codec_tx_regs;
  779. adie_codec.path[ADIE_CODEC_TX].img.img_sz =
  780. ARRAY_SIZE(adie_codec_tx_regs);
  781. adie_codec.path[ADIE_CODEC_RX].img.regs = adie_codec_rx_regs;
  782. adie_codec.path[ADIE_CODEC_RX].img.img_sz =
  783. ARRAY_SIZE(adie_codec_rx_regs);
  784. adie_codec.path[ADIE_CODEC_LB].img.regs = adie_codec_lb_regs;
  785. adie_codec.path[ADIE_CODEC_LB].img.img_sz =
  786. ARRAY_SIZE(adie_codec_lb_regs);
  787. mutex_init(&adie_codec.lock);
  788. error:
  789. return rc;
  790. }
  791. static void __exit marimba_codec_exit(void)
  792. {
  793. #ifdef CONFIG_DEBUG_FS
  794. debugfs_remove(debugfs_peek);
  795. debugfs_remove(debugfs_poke);
  796. debugfs_remove(debugfs_power);
  797. debugfs_remove(debugfs_marimba_dent);
  798. #endif
  799. platform_driver_unregister(&marimba_codec_driver);
  800. }
  801. module_init(marimba_codec_init);
  802. module_exit(marimba_codec_exit);
  803. MODULE_DESCRIPTION("Marimba codec driver");
  804. MODULE_VERSION("1.0");
  805. MODULE_LICENSE("GPL v2");