aml_audio_hw.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. #include <linux/kernel.h>
  2. #include <linux/types.h>
  3. #include <linux/errno.h>
  4. #include <linux/string.h>
  5. #include <mach/am_regs.h>
  6. #include <linux/clk.h>
  7. #ifdef CONFIG_ARCH_MESON6
  8. #include <mach/utils.h>
  9. #endif
  10. #include "aml_audio_hw.h"
  11. #ifndef MREG_AIU_958_chstat0
  12. #define AIU_958_chstat0 AIU_958_CHSTAT_L0
  13. #endif
  14. #ifndef MREG_AIU_958_chstat1
  15. #define AIU_958_chstat1 AIU_958_CHSTAT_L1
  16. #endif
  17. unsigned ENABLE_IEC958 = 1;
  18. unsigned IEC958_MODE = AIU_958_MODE_PCM16;
  19. unsigned I2S_MODE = AIU_I2S_MODE_PCM16;
  20. static unsigned dac_reset_flag = 0;
  21. int audio_in_buf_ready = 0;
  22. int audio_out_buf_ready = 0;
  23. //extern int in_error_flag;
  24. //extern int in_error;
  25. /*
  26. fIn * (M)
  27. Fout = -----------------------------
  28. (N) * (OD+1) * (XD)
  29. */
  30. #ifdef CONFIG_ARCH_MESON6
  31. int audio_clock_config_table[][12][2]=
  32. {
  33. /*{HIU Reg , XD - 1)
  34. //7.875k, 8K, 11.025k, 12k, 16k, 22.05k, 24k, 32k, 44.1k, 48k, 96k, 192k
  35. */
  36. {
  37. //256
  38. {0x0004f880, (50-1)}, // 32
  39. {0x0004cdf3, (42-1)}, // 44.1
  40. {0x0007c4e6, (23-1)}, // 48
  41. {0x0006d0a4, (13-1)}, // 96
  42. {0x0004e15a, (9 -1)}, // 192
  43. {0x0007f400, (125-1)}, // 8k
  44. {0x0006c6f6, (116-1)}, // 11.025
  45. {0x0007e47f, (86-1)}, // 12
  46. {0x0004f880, (100-1)}, // 16
  47. {0x0004c4a4, (87-1)}, // 22.05
  48. {0x0007e47f, (43-1)}, // 24
  49. {0x0007f3f0, (127-1)}, // 7875
  50. },
  51. {
  52. //384
  53. {0x0007c4e6, (23-1)}, // 32
  54. {0x0004c4a4, (29-1)}, // 44.1
  55. {0x0004cb18, (26-1)}, // 48
  56. {0x0004cb18, (13-1)}, // 96
  57. {0x0004e15a, (6 -1)}, // 192
  58. {0x0007e47f, (86-1)}, // 8k
  59. {0x0007efa5, (61-1)}, // 11.025
  60. {0x0006de98, (67-1)}, // 12
  61. {0x0007e47f, (43-1)}, // 16
  62. {0x0004c4a4, (58-1)}, // 22.05
  63. {0x0004c60e, (53-1)}, // 24
  64. {0x0007fdfa, (83-1)}, // 7875
  65. }
  66. };
  67. #else
  68. int audio_clock_config_table[][11][2]=
  69. {
  70. /*{M, N, OD, XD-1*/
  71. {
  72. //24M
  73. {(71 << 0) |(4 << 9) | (1 << 14), (26-1)},//32K
  74. {(143 << 0) |(8 << 9) | (1 << 14), (19-1)},//44.1K
  75. {(128 << 0) |(5 << 9) | (1 << 14), (25-1)},//48K
  76. {(128 << 0) |(5 << 9) | (0 << 14), (25-1)},//96K
  77. {(213 << 0) |(8 << 9) | (0 << 14), (13-1)},//192K
  78. {(71 << 0) |(8 << 9) | (1 << 14), (52-1)},// 8K
  79. {(143 << 0) |(8 << 9) | (1 << 14), (76-1)},// 11025
  80. {(32 << 0) |(5 << 9) | (1 << 14), (25-1)},// 12K
  81. {(71 << 0) |(8 << 9) | (1 << 14), (26-1)},// 16K
  82. {(143 << 0) |(8 << 9) | (1 << 14), (38-1)},// 22050
  83. {(64 << 0) |(5 << 9) | (1 << 14), (25-1)} // 24K
  84. },
  85. {
  86. //25M
  87. {(19 << 0) |(1 << 9) | (1 << 14), (29-1)},//32K
  88. {(28 << 0) |(1 << 9) | (1 << 14), (31-1)},//44.1K
  89. {(173 << 0) |(8 << 9) | (1 << 14), (22-1)},//48K
  90. {(173 << 0) |(8 << 9) | (1 << 14), (11-1)},//96K
  91. {(118 << 0) |(5 << 9) | (1 << 14), (6-1)},//192K
  92. {(19 << 0) |(4 << 9) | (1 << 14), (29-1)},// 8K
  93. {(7 << 0) |(1 << 9) | (1 << 14), (31-1)},// 11025
  94. {(173 << 0) |(8 << 9) | (1 << 14), (88-1)},// 12K
  95. {(19 << 0) |(2 << 9) | (1 << 14), (29-1)},// 16K
  96. {(14 << 0) |(1 << 9) | (1 << 14), (31-1)},// 22050
  97. {(173 << 0) |(8 << 9) | (1 << 14), (44-1)}// 24K
  98. }
  99. };
  100. #endif
  101. #if 0
  102. /*Default acodec_regbank value*/
  103. unsigned int acodec_regbank[74] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 0 - 5
  104. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 6 - 11
  105. 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, // Reg 12 - 17
  106. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 18 - 23
  107. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 24 - 29
  108. 0x00, 0x00, 0x54, 0x54, 0x28, 0x28, // Reg 30 - 35
  109. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 36 - 41
  110. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 42 - 47
  111. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 48 - 53
  112. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reg 54 - 59
  113. 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, // Reg 60 - 65
  114. 0x14, 0x14, 0x12, 0x12, 0x00, 0x00, // Reg 66 - 71
  115. 0x00, 0x00 // Reg 72 - 73
  116. };
  117. #endif
  118. void audio_set_aiubuf(u32 addr, u32 size)
  119. {
  120. WRITE_MPEG_REG(AIU_MEM_I2S_START_PTR, addr & 0xffffffc0);
  121. WRITE_MPEG_REG(AIU_MEM_I2S_RD_PTR, addr & 0xffffffc0);
  122. WRITE_MPEG_REG(AIU_MEM_I2S_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 64); //this is for 16bit 2 channel
  123. WRITE_MPEG_REG(AIU_I2S_MISC, 0x0004); // Hold I2S
  124. WRITE_MPEG_REG(AIU_I2S_MUTE_SWAP, 0x0000); // No mute, no swap
  125. // As the default amclk is 24.576MHz, set i2s and iec958 divisor appropriately so as not to exceed the maximum sample rate.
  126. WRITE_MPEG_REG(AIU_I2S_MISC, 0x0010 ); // Release hold and force audio data to left or right
  127. WRITE_MPEG_REG(AIU_MEM_I2S_MASKS, (24 << 16) | // [31:16] IRQ block.
  128. (0x3 << 8) | // [15: 8] chan_mem_mask. Each bit indicates which channels exist in memory
  129. (0x3 << 0)); // [ 7: 0] chan_rd_mask. Each bit indicates which channels are READ from memory
  130. // 16 bit PCM mode
  131. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 6, 1);
  132. // Set init high then low to initilize the I2S memory logic
  133. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 0, 1 );
  134. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 0, 1 );
  135. audio_out_buf_ready = 1;
  136. }
  137. void audio_set_958outbuf(u32 addr, u32 size)
  138. {
  139. if (ENABLE_IEC958) {
  140. WRITE_MPEG_REG(AIU_MEM_IEC958_START_PTR, addr & 0xffffffc0);
  141. WRITE_MPEG_REG(AIU_MEM_IEC958_RD_PTR, addr & 0xffffffc0);
  142. WRITE_MPEG_REG(AIU_MEM_IEC958_END_PTR, (addr & 0xffffffc0) + (size & 0xffffffc0) - 64); // this is for 16bit 2 channel
  143. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 0, 1);
  144. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 0, 1);
  145. // WRITE_MPEG_REG(AIU_MEM_IEC958_BUF_CNTL, 1 | (0 << 1));
  146. // WRITE_MPEG_REG(AIU_MEM_IEC958_BUF_CNTL, 0 | (0 << 1));
  147. }
  148. }
  149. void audio_in_i2s_set_buf(u32 addr, u32 size)
  150. {
  151. WRITE_MPEG_REG(AUDIN_FIFO0_START, addr & 0xffffffc0);
  152. WRITE_MPEG_REG(AUDIN_FIFO0_PTR, (addr&0xffffffc0));
  153. WRITE_MPEG_REG(AUDIN_FIFO0_END, (addr&0xffffffc0) + (size&0xffffffc0)-8);
  154. WRITE_MPEG_REG(AUDIN_FIFO0_CTRL, (1<<AUDIN_FIFO0_EN) // FIFO0_EN
  155. |(1<<AUDIN_FIFO0_LOAD) // load start address./* AUDIN_FIFO0_LOAD */
  156. |(1<<AUDIN_FIFO0_DIN_SEL) // DIN from i2sin./* AUDIN_FIFO0_DIN_SEL */
  157. //|(1<<6) // 32 bits data in./*AUDIN_FIFO0_D32b */
  158. //|(0<<7) // put the 24bits data to low 24 bits./* AUDIN_FIFO0_h24b */16bit
  159. |(4<<AUDIN_FIFO0_ENDIAN) // /*AUDIN_FIFO0_ENDIAN */
  160. |(2<<AUDIN_FIFO0_CHAN)//2 channel./* AUDIN_FIFO0_CHAN*/
  161. |(0<<16) //to DDR
  162. |(1<<AUDIN_FIFO0_UG) // Urgent request. DDR SDRAM urgent request enable.
  163. |(0<<17) // Overflow Interrupt mask
  164. |(0<<18) // Audio in INT
  165. //|(1<<19) //hold 0 enable
  166. |(0<<AUDIN_FIFO0_UG) // hold0 to aififo
  167. );
  168. WRITE_MPEG_REG(AUDIN_FIFO0_CTRL1, 0 << 4 // fifo0_dest_sel
  169. | 2 << 2 // fifo0_din_byte_num
  170. | 0 << 0); // fifo0_din_pos
  171. WRITE_MPEG_REG(AUDIN_I2SIN_CTRL, //(0<<I2SIN_SIZE) ///*bit8*/ 16bit
  172. (3<<I2SIN_SIZE)
  173. |(1<<I2SIN_CHAN_EN) /*bit10~13*/ //2 channel
  174. |(1<<I2SIN_POS_SYNC)
  175. //|(0<<I2SIN_POS_SYNC)
  176. |(1<<I2SIN_LRCLK_SKEW)
  177. |(1<<I2SIN_LRCLK_INVT)
  178. |(1<<I2SIN_CLK_SEL)
  179. |(1<<I2SIN_LRCLK_SEL)
  180. |(1<<I2SIN_DIR)
  181. );
  182. audio_in_buf_ready = 1;
  183. //in_error_flag = 0;
  184. //in_error = 0;
  185. }
  186. void audio_in_spdif_set_buf(u32 addr, u32 size)
  187. {
  188. }
  189. //extern void audio_in_enabled(int flag);
  190. void audio_in_i2s_enable(int flag)
  191. {
  192. int rd = 0, start=0;
  193. reset_again:
  194. WRITE_MPEG_REG_BITS(AUDIN_FIFO0_CTRL, 1, 1, 1); // reset FIFO 0
  195. WRITE_MPEG_REG(AUDIN_FIFO0_PTR, 0);
  196. rd = READ_MPEG_REG(AUDIN_FIFO0_PTR);
  197. start = READ_MPEG_REG(AUDIN_FIFO0_START);
  198. if(rd != start){
  199. printk("error %08x, %08x !!!!!!!!!!!!!!!!!!!!!!!!\n", rd, start);
  200. goto reset_again;
  201. }
  202. if(flag){
  203. WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 1, I2SIN_EN, 1);
  204. }else{
  205. WRITE_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, 0, I2SIN_EN, 1);
  206. }
  207. //in_error_flag = 0;
  208. //in_error = 0;
  209. //audio_in_enabled(flag);
  210. }
  211. int if_audio_in_i2s_enable()
  212. {
  213. return READ_MPEG_REG_BITS(AUDIN_I2SIN_CTRL, I2SIN_EN, 1);
  214. }
  215. void audio_in_spdif_enable(int flag)
  216. {
  217. WRITE_MPEG_REG_BITS(AUDIN_FIFO1_CTRL, 1, 1, 1); // reset FIFO 1
  218. if(flag){
  219. }else{
  220. }
  221. }
  222. unsigned int audio_in_i2s_rd_ptr(void)
  223. {
  224. unsigned int val;
  225. val = READ_MPEG_REG(AUDIN_FIFO0_RDPTR);
  226. printk("audio in i2s rd ptr: %x\n", val);
  227. return val;
  228. }
  229. unsigned int audio_in_i2s_wr_ptr(void)
  230. {
  231. unsigned int val;
  232. WRITE_MPEG_REG(AUDIN_FIFO0_PTR, 1);
  233. val = READ_MPEG_REG(AUDIN_FIFO0_PTR);
  234. return (val)&(~0x3F);
  235. //return val&(~0x7);
  236. }
  237. void audio_in_i2s_set_wrptr(unsigned int val)
  238. {
  239. WRITE_MPEG_REG(AUDIN_FIFO0_RDPTR, val);
  240. }
  241. void audio_set_i2s_mode(u32 mode)
  242. {
  243. const unsigned short mask[4] = {
  244. 0x303, /* 2x16 */
  245. 0x303, /* 2x24 */
  246. 0x303, /* 8x24 */
  247. 0x303, /* 2x32 */
  248. };
  249. if (mode < sizeof(mask)/ sizeof(unsigned short)) {
  250. /* four two channels stream */
  251. WRITE_MPEG_REG(AIU_I2S_SOURCE_DESC, 1);
  252. if (mode == AIU_I2S_MODE_PCM16) {
  253. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 6, 1);
  254. WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 0, 5, 1);
  255. } else if(mode == AIU_I2S_MODE_PCM32){
  256. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 6, 1);
  257. WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 1, 5, 1);
  258. }else if(mode == AIU_I2S_MODE_PCM24){
  259. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 6, 1);
  260. WRITE_MPEG_REG_BITS(AIU_I2S_SOURCE_DESC, 1, 5, 1);
  261. }
  262. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_MASKS, mask[mode], 0, 16);
  263. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 0, 1);
  264. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 0, 1);
  265. if (ENABLE_IEC958) {
  266. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_MASKS, mask[mode], 0,
  267. 16);
  268. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 0, 1);
  269. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 0, 1);
  270. }
  271. }
  272. }
  273. void audio_util_set_dac_format(unsigned format)
  274. {
  275. #ifndef CONFIG_ARCH_MESON6
  276. //WRITE_MPEG_REG(AIU_CLK_CTRL_MORE, 0x0000); // i2s_divisor_more does not take effect
  277. WRITE_MPEG_REG(AIU_CLK_CTRL_MORE, 0x0003); // i2s_divisor_more divided by 4
  278. #endif
  279. WRITE_MPEG_REG(AIU_CLK_CTRL, (0 << 12) | // 958 divisor more, if true, divided by 2, 4, 6, 8.
  280. (1 << 8) | // alrclk skew: 1=alrclk transitions on the cycle before msb is sent
  281. (1 << 6) | // invert aoclk
  282. (1 << 7) | // invert lrclk
  283. //(1 << 4) | // 958 divisor: 0=no div; 1=div by 2; 2=div by 3; 3=div by 4.
  284. //(2 << 2) | // i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
  285. (0 << 2) | // i2s divisor: 0=no div; 1=div by 2; 2=div by 4; 3=div by 8.
  286. (1 << 1) |
  287. (1 << 0)); // enable I2S clock
  288. if (format == AUDIO_ALGOUT_DAC_FORMAT_DSP) {
  289. WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 1, 8, 2);
  290. } else if (format == AUDIO_ALGOUT_DAC_FORMAT_LEFT_JUSTIFY) {
  291. WRITE_MPEG_REG_BITS(AIU_CLK_CTRL, 0, 8, 2);
  292. }
  293. WRITE_MPEG_REG(AIU_I2S_DAC_CFG, 0x000f); // Payload 24-bit, Msb first, alrclk = aoclk/64
  294. WRITE_MPEG_REG(AIU_I2S_SOURCE_DESC, 0x0001); // four 2-channel
  295. }
  296. extern unsigned int get_ddr_pll_clk(void);
  297. void audio_set_clk(unsigned freq, unsigned fs_config)
  298. {
  299. int i;
  300. struct clk *clk;
  301. int xtal = 0;
  302. int (*audio_clock_config)[2];
  303. // if (fs_config == AUDIO_CLK_256FS) {
  304. if(1){
  305. int index=0;
  306. switch(freq)
  307. {
  308. case AUDIO_CLK_FREQ_192:
  309. index=4;
  310. break;
  311. case AUDIO_CLK_FREQ_96:
  312. index=3;
  313. break;
  314. case AUDIO_CLK_FREQ_48:
  315. index=2;
  316. break;
  317. case AUDIO_CLK_FREQ_441:
  318. index=1;
  319. break;
  320. case AUDIO_CLK_FREQ_32:
  321. index=0;
  322. break;
  323. case AUDIO_CLK_FREQ_8:
  324. index = 5;
  325. break;
  326. case AUDIO_CLK_FREQ_11:
  327. index = 6;
  328. break;
  329. case AUDIO_CLK_FREQ_12:
  330. index = 7;
  331. break;
  332. case AUDIO_CLK_FREQ_16:
  333. index = 8;
  334. break;
  335. case AUDIO_CLK_FREQ_22:
  336. index = 9;
  337. break;
  338. case AUDIO_CLK_FREQ_24:
  339. index = 10;
  340. break;
  341. default:
  342. index=0;
  343. break;
  344. };
  345. #ifndef CONFIG_ARCH_MESON6
  346. // get system crystal freq
  347. clk=clk_get_sys("clk_xtal", NULL);
  348. if(!clk)
  349. {
  350. printk(KERN_ERR "can't find clk %s for AUDIO PLL SETTING!\n\n","clk_xtal");
  351. //return -1;
  352. }
  353. else
  354. {
  355. xtal=clk_get_rate(clk);
  356. xtal=xtal/1000000;
  357. if(xtal>=24 && xtal <=25)/*current only support 24,25*/
  358. {
  359. xtal-=24;
  360. }
  361. else
  362. {
  363. printk(KERN_WARNING "UNsupport xtal setting for audio xtal=%d,default to 24M\n",xtal);
  364. xtal=0;
  365. }
  366. }
  367. audio_clock_config = audio_clock_config_table[xtal];
  368. #endif
  369. #ifdef CONFIG_ARCH_MESON6
  370. if (fs_config == AUDIO_CLK_256FS) {
  371. // divide 256
  372. WRITE_MPEG_REG_BITS(AIU_CLK_CTRL_MORE, 3, 0, 5);
  373. xtal = 0;
  374. }
  375. else if (fs_config == AUDIO_CLK_384FS) {
  376. // divide 384
  377. WRITE_MPEG_REG_BITS(AIU_CLK_CTRL_MORE, 5, 0, 5);
  378. xtal = 1;
  379. }
  380. audio_clock_config = audio_clock_config_table[xtal];
  381. #endif
  382. #ifdef CONFIG_SND_AML_M3
  383. if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==516000000)&&(index=2))) // 48k
  384. {
  385. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
  386. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
  387. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
  388. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 42-1, 0, 8); // 516/42
  389. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  390. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  391. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
  392. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
  393. printk(KERN_INFO "audio 48k clock from ddr pll %dM\n", 516);
  394. return;
  395. }
  396. else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==508000000)&&(index=1))) // 44.1k
  397. {
  398. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
  399. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
  400. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
  401. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 45-1, 0, 8); // 508/45
  402. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  403. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  404. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
  405. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
  406. printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 508);
  407. return;
  408. }
  409. else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==486000000)&&(index=1))) // 44.1k
  410. {
  411. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
  412. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
  413. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
  414. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 43-1, 0, 8); // 486/42
  415. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  416. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  417. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
  418. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
  419. printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 486);
  420. return;
  421. }
  422. else if (((clk_get_rate(clk)==24000000)&&(get_ddr_pll_clk()==474000000)&&(index=1))) // 44.1k
  423. {
  424. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8)); // audio clock off
  425. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15)); // audio pll off
  426. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 4, 9, 3); // select ddr
  427. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 42-1, 0, 8); // 474/42
  428. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  429. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  430. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1<<23));// gate audac_clkpi
  431. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
  432. printk(KERN_INFO "audio 44.1k clock from ddr pll %dM\n", 474);
  433. return;
  434. }
  435. #endif
  436. // gate the clock off
  437. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 8));
  438. #ifdef CONFIG_SND_AML_M3
  439. WRITE_MPEG_REG(HHI_AUD_PLL_CNTL2, 0x065e31ff);
  440. WRITE_MPEG_REG(HHI_AUD_PLL_CNTL3, 0x9649a941);
  441. // select Audio PLL as MCLK source
  442. //WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(1 << 9));
  443. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 0, 9, 3);
  444. //WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 25-1, 0, 8);
  445. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, 13-1, 0, 8);
  446. #endif
  447. #ifndef CONFIG_ARCH_MESON6
  448. // Put the PLL to sleep
  449. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) | (1 << 15));//found
  450. #ifdef CONFIG_SND_AML_M3
  451. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  452. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  453. #endif
  454. // Bring out of reset but keep bypassed to allow to stablize
  455. //Wr( HHI_AUD_PLL_CNTL, (1 << 15) | (0 << 14) | (hiu_reg & 0x3FFF) );
  456. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, (1 << 15) | (audio_clock_config[index][0] & 0x7FFF) );//found
  457. // Set the XD value
  458. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, (READ_MPEG_REG(HHI_AUD_CLK_CNTL) & ~(0xff << 0)) | audio_clock_config[index][1]);//found
  459. // delay 5uS
  460. //udelay(5);
  461. for (i = 0; i < 500000; i++) ;
  462. // Bring the PLL out of sleep
  463. WRITE_MPEG_REG( HHI_AUD_PLL_CNTL, READ_MPEG_REG(HHI_AUD_PLL_CNTL) & ~(1 << 15));//found
  464. // gate the clock on
  465. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));//found
  466. #if ((defined CONFIG_SND_AML_M1) || (defined CONFIG_SND_AML_M2)||(defined CONFIG_SND_AML_M3))
  467. WRITE_MPEG_REG(HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) |(1<<23));// gate audac_clkpi
  468. #endif
  469. #else // endif CONFIG_ARCH_MESON6
  470. WRITE_MPEG_REG_BITS(AIU_CODEC_ADC_LRCLK_CTRL, 64-1, 0, 12);//set codec adc ratio---lrclk
  471. WRITE_MPEG_REG_BITS(AIU_CODEC_DAC_LRCLK_CTRL, 64-1, 0, 12);//set codec dac ratio---lrclk
  472. // Select Multi-Phase PLL2 as clock source
  473. WRITE_MPEG_REG_BITS( HHI_AUD_CLK_CNTL, 3, 9, 3);
  474. // Configure Multi-Phase PLL2
  475. WRITE_MPEG_REG(HHI_MPLL_CNTL9, audio_clock_config[index][0]);
  476. // Set the XD value
  477. WRITE_MPEG_REG_BITS(HHI_AUD_CLK_CNTL, audio_clock_config[index][1], 0, 8);
  478. // delay 5uS
  479. //udelay(5);
  480. for (i = 0; i < 500000; i++) ;
  481. // gate the clock on
  482. WRITE_MPEG_REG( HHI_AUD_CLK_CNTL, READ_MPEG_REG(HHI_AUD_CLK_CNTL) | (1 << 8));
  483. #endif // endif CONFIG_ARCH_MESON6
  484. // delay 2uS
  485. //udelay(2);
  486. for (i = 0; i < 200000; i++) ;
  487. } else if (fs_config == AUDIO_CLK_384FS) {
  488. }
  489. }
  490. void adac_wr_reg (unsigned long addr, unsigned long data)
  491. {
  492. WRITE_APB_REG((APB_BASE+(addr<<2)), data);
  493. //acodec_regbank[addr] = data;
  494. } /* adac_wr_reg */
  495. unsigned long adac_rd_reg (unsigned long addr)
  496. {
  497. unsigned long data;
  498. data = READ_APB_REG(APB_BASE+(addr<<2));
  499. return (data);
  500. } /* adac_rd_reg */
  501. void wr_regbank (unsigned long rstdpz,
  502. unsigned long mclksel,
  503. unsigned long i2sfsadc,
  504. unsigned long i2sfsdac,
  505. unsigned long i2ssplit,
  506. unsigned long i2smode,
  507. unsigned long pdauxdrvrz,
  508. unsigned long pdauxdrvlz,
  509. unsigned long pdhsdrvrz,
  510. unsigned long pdhsdrvlz,
  511. unsigned long pdlsdrvz,
  512. unsigned long pddacrz,
  513. unsigned long pddaclz,
  514. unsigned long pdz,
  515. unsigned long pdmbiasz,
  516. unsigned long pdvcmbufz,
  517. unsigned long pdrpgaz,
  518. unsigned long pdlpgaz,
  519. unsigned long pdadcrz,
  520. unsigned long pdadclz,
  521. unsigned long hsmute,
  522. unsigned long recmute,
  523. unsigned long micmute,
  524. unsigned long lmmute,
  525. unsigned long lsmute,
  526. unsigned long lmmix,
  527. unsigned long recmix,
  528. unsigned long ctr,
  529. unsigned long enhp,
  530. unsigned long lmvol,
  531. unsigned long hsvol,
  532. unsigned long pbmix,
  533. unsigned long lsmix,
  534. unsigned long micvol,
  535. unsigned long recvol,
  536. unsigned long recsel)
  537. {
  538. adac_wr_reg(0, (rstdpz<<1));
  539. adac_wr_reg(2, (mclksel<<0));
  540. adac_wr_reg(12, (i2sfsadc<<4) | (i2sfsdac<<0));
  541. adac_wr_reg(13, (i2ssplit<<3) | (i2smode<<0));
  542. adac_wr_reg(16, (pdauxdrvrz<<7) | (pdauxdrvlz<<6) | (pdhsdrvrz<<5) | (pdhsdrvlz<<4) | (pdlsdrvz<<2) | (pddacrz<<1) | (pddaclz<<0));
  543. adac_wr_reg(17, (pdz<<7) | (pdmbiasz<<5) | (pdvcmbufz<<4) | (pdrpgaz<<3) | (pdlpgaz<<2) | (pdadcrz<<1) | (pdadclz<<0));
  544. adac_wr_reg(24, (hsmute<<6) | (recmute<<4) | (micmute<<2) | (lmmute<<0));
  545. adac_wr_reg(25, (lsmute<<2));
  546. adac_wr_reg(26, (lmmix<<5) | (recmix<<3) | (ctr<<1) | (enhp<<0));
  547. adac_wr_reg(32, (lmvol&0xff));
  548. adac_wr_reg(33, (lmvol>>8));
  549. adac_wr_reg(34, (hsvol&0xff));
  550. adac_wr_reg(35, (hsvol>>8));
  551. adac_wr_reg(36, (pbmix&0xff));
  552. adac_wr_reg(37, (pbmix>>8));
  553. adac_wr_reg(38, (lsmix&0xff));
  554. adac_wr_reg(39, (lsmix>>8));
  555. adac_wr_reg(64, (micvol&0xff));
  556. adac_wr_reg(65, (micvol>>8));
  557. adac_wr_reg(66, (recvol&0xff));
  558. adac_wr_reg(67, (recvol>>8));
  559. adac_wr_reg(72, (recsel&0xff));
  560. adac_wr_reg(73, (recsel>>8));
  561. } /* wr_regbank */
  562. void adac_power_up_mode_2(void)
  563. {
  564. adac_wr_reg(224, 0x11);
  565. }
  566. static inline void adac_latch(void)
  567. {
  568. adac_wr_reg(1, 1);
  569. adac_wr_reg(1, 0);
  570. }
  571. void adac_startup_seq(void)
  572. {
  573. /* toggle pdz 0->1 */
  574. adac_wr_reg(17, adac_rd_reg(17) & ~0x80);
  575. adac_latch();
  576. adac_wr_reg(17, adac_rd_reg(17) | 0x80);
  577. adac_latch();
  578. /* toggle rstdpz 0->1 */
  579. adac_wr_reg(0, adac_rd_reg(0) & ~2);
  580. adac_latch();
  581. adac_wr_reg(0, adac_rd_reg(0) | 2);
  582. adac_latch();
  583. }
  584. //------------------------------------------------------------------------------
  585. // set_acodec_source(unsigned int src)
  586. //
  587. // Description:
  588. // Select audio CODEC clock source, DAC's data source.
  589. //
  590. // Parameters:
  591. // src -- 0=no clock to CODEC; 1=pcmout to DAC; 2=Aiu I2S out to DAC.
  592. //------------------------------------------------------------------------------
  593. void set_acodec_source (unsigned int src)
  594. {
  595. unsigned long data32;
  596. // Disable acodec clock input and its DAC input
  597. data32 = 0;
  598. data32 |= 0 << 4; // [5:4] acodec_data_sel: 00=disable acodec_sdin; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  599. data32 |= 0 << 0; // [1:0] acodec_clk_sel: 00=Disable acodec_sclk; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  600. WRITE_MPEG_REG(AIU_CODEC_CLK_DATA_CTRL, data32);
  601. // Enable acodec clock from the selected source
  602. data32 = 0;
  603. data32 |= 0 << 4; // [5:4] acodec_data_sel: 00=disable acodec_sdin; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  604. data32 |= src << 0; // [1:0] acodec_clk_sel: 00=Disable acodec_sclk; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  605. WRITE_MPEG_REG(AIU_CODEC_CLK_DATA_CTRL, data32);
  606. // Enable acodec DAC input from the selected source
  607. data32 = 0;
  608. data32 |= src << 4; // [5:4] acodec_data_sel: 00=disable acodec_sdin; 01=Select pcm data; 10=Select AIU I2S data; 11=Not allowed.
  609. data32 |= src << 0; // [1:0] acodec_clk_sel: 00=Disable acodec_sclk; 01=Select pcm clock; 10=Select AIU aoclk; 11=Not allowed.
  610. WRITE_MPEG_REG(AIU_CODEC_CLK_DATA_CTRL, data32);
  611. }
  612. //extern void audio_out_enabled(int flag);
  613. void audio_enable_ouput(int flag)
  614. {
  615. if (flag) {
  616. WRITE_MPEG_REG(AIU_RST_SOFT, 0x05);
  617. READ_MPEG_REG(AIU_I2S_SYNC);
  618. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 3, 1, 2);
  619. if (ENABLE_IEC958) {
  620. WRITE_MPEG_REG(AIU_958_FORCE_LEFT, 0);
  621. WRITE_MPEG_REG(AIU_958_DCU_FF_CTRL, 1);
  622. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 3, 1, 2);
  623. }
  624. } else {
  625. WRITE_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 0, 1, 2);
  626. if (ENABLE_IEC958) {
  627. WRITE_MPEG_REG(AIU_958_DCU_FF_CTRL, 0);
  628. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 1, 2);
  629. }
  630. }
  631. //audio_out_enabled(flag);
  632. }
  633. int if_audio_out_enable()
  634. {
  635. return READ_MPEG_REG_BITS(AIU_MEM_I2S_CONTROL, 1, 2);
  636. }
  637. unsigned int read_i2s_rd_ptr(void)
  638. {
  639. unsigned int val;
  640. val = READ_MPEG_REG(AIU_MEM_I2S_RD_PTR);
  641. return val;
  642. }
  643. void audio_i2s_unmute(void)
  644. {
  645. WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, 0, 8, 8);
  646. WRITE_MPEG_REG_BITS(AIU_958_CTRL, 0, 3, 2);
  647. }
  648. void audio_i2s_mute(void)
  649. {
  650. WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, 0xff, 8, 8);
  651. WRITE_MPEG_REG_BITS(AIU_958_CTRL, 3, 3, 2);
  652. }
  653. void audio_hw_958_reset(unsigned slow_domain, unsigned fast_domain)
  654. {
  655. WRITE_MPEG_REG(AIU_RST_SOFT,
  656. (slow_domain << 3) | (fast_domain << 2));
  657. }
  658. void set_958_channel_status(_aiu_958_channel_status_t * set)
  659. {
  660. if (set) {
  661. WRITE_MPEG_REG(AIU_958_chstat0, set->chstat0_l);
  662. WRITE_MPEG_REG(AIU_958_chstat1, set->chstat1_l);
  663. WRITE_MPEG_REG(AIU_958_CHSTAT_L0, set->chstat0_r);
  664. WRITE_MPEG_REG(AIU_958_CHSTAT_L1, set->chstat1_r);
  665. }
  666. }
  667. static void audio_hw_set_958_pcm24(_aiu_958_raw_setting_t * set)
  668. {
  669. WRITE_MPEG_REG(AIU_958_BPF, 0x80); /* in pcm mode, set bpf to 128 */
  670. set_958_channel_status(set->chan_stat);
  671. }
  672. void audio_set_958_mode(unsigned mode, _aiu_958_raw_setting_t * set)
  673. {
  674. if (mode == AIU_958_MODE_RAW) {
  675. set_958_channel_status(set->chan_stat);
  676. if (ENABLE_IEC958) {
  677. WRITE_MPEG_REG(AIU_958_MISC, 1);
  678. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 8, 1); // raw
  679. }
  680. }else if(mode == AIU_958_MODE_PCM32){
  681. audio_hw_set_958_pcm24(set);
  682. if(ENABLE_IEC958){
  683. WRITE_MPEG_REG(AIU_958_MISC, 0x2020 | (1 << 7));
  684. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1); // pcm
  685. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1); // 16bit
  686. }
  687. }else if (mode == AIU_958_MODE_PCM24) {
  688. audio_hw_set_958_pcm24(set);
  689. if (ENABLE_IEC958) {
  690. WRITE_MPEG_REG(AIU_958_MISC, 0x2020 | (1 << 7));
  691. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1); // pcm
  692. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 7, 1); // 16bit
  693. }
  694. } else if (mode == AIU_958_MODE_PCM16) {
  695. audio_hw_set_958_pcm24(set);
  696. if (ENABLE_IEC958) {
  697. WRITE_MPEG_REG(AIU_958_MISC, 0x2042);
  698. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 0, 8, 1); // pcm
  699. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, 1, 7, 1); // 16bit
  700. }
  701. }
  702. audio_hw_958_reset(0, 1);
  703. WRITE_MPEG_REG(AIU_958_FORCE_LEFT, 1);
  704. }
  705. void audio_hw_958_enable(unsigned flag)
  706. {
  707. if (ENABLE_IEC958) {
  708. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 2, 1);
  709. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 1, 1);
  710. WRITE_MPEG_REG_BITS(AIU_MEM_IEC958_CONTROL, flag, 0, 1);
  711. }
  712. }
  713. unsigned int read_i2s_mute_swap_reg(void)
  714. {
  715. unsigned int val;
  716. val = READ_MPEG_REG(AIU_I2S_MUTE_SWAP);
  717. return val;
  718. }
  719. void audio_i2s_swap_left_right(unsigned int flag)
  720. {
  721. WRITE_MPEG_REG_BITS(AIU_I2S_MUTE_SWAP, flag, 0, 2);
  722. }