dsp_codec.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <linux/module.h>
  2. #include <linux/sched.h>
  3. #include <linux/kernel.h>
  4. #include <linux/cache.h>
  5. #include <asm/cacheflush.h>
  6. //#include <asm/arch/am_regs.h>
  7. #include <mach/am_regs.h>
  8. //#include <asm/bsp.h>
  9. #include <linux/amports/ptsserv.h>
  10. //#include <asm/dsp/dsp_register.h>
  11. #include "dsp_microcode.h"
  12. #include "audiodsp_module.h"
  13. #include "dsp_control.h"
  14. #include "dsp_mailbox.h"
  15. #include "dsp_codec.h"
  16. int dsp_codec_start(struct audiodsp_priv *priv)
  17. {
  18. return dsp_mailbox_send(priv, 1, M2B_IRQ2_DECODE_START, 0, 0, 0);
  19. }
  20. int dsp_codec_stop(struct audiodsp_priv *priv)
  21. {
  22. return dsp_mailbox_send(priv, 1, M2B_IRQ3_DECODE_STOP, 0, 0, 0);
  23. }
  24. int dsp_codec_get_bufer_data_len(struct audiodsp_priv *priv)
  25. {
  26. #define REVERSD_BYTES 32
  27. #define CACHE_ALIGNED(x) (x&(~0x1f))
  28. unsigned long rp, wp, len, flags;
  29. local_irq_save(flags);
  30. rp = dsp_codec_get_rd_addr(priv);
  31. wp = dsp_codec_get_wd_addr(priv);
  32. if (rp > wp) {
  33. len = priv->stream_buffer_size - (rp - wp);
  34. } else {
  35. len = (wp - rp);
  36. }
  37. len = (len > REVERSD_BYTES) ? (len - REVERSD_BYTES) : 0;
  38. len = CACHE_ALIGNED(len);
  39. local_irq_restore(flags);
  40. return len;
  41. }
  42. int dsp_codec_get_bufer_data_len1(struct audiodsp_priv *priv, unsigned long wd_ptr)
  43. {
  44. #define REVERSD_BYTES 32
  45. #define CACHE_ALIGNED(x) (x&(~0x1f))
  46. unsigned long rp, wp, len, flags;
  47. //if(wd_ptr != DSP_RD(DSP_DECODE_OUT_WD_ADDR))
  48. // printk("w1 == %x , w2 == %x, r == %x\n", DSP_RD(DSP_DECODE_OUT_WD_ADDR), wd_ptr, DSP_RD(DSP_DECODE_OUT_RD_ADDR));
  49. local_irq_save(flags);
  50. rp = dsp_codec_get_rd_addr(priv);
  51. wp = ARC_2_ARM_ADDR_SWAP(wd_ptr);
  52. if (rp > wp) {
  53. len = priv->stream_buffer_size - (rp - wp);
  54. } else {
  55. len = (wp - rp);
  56. }
  57. len = (len > REVERSD_BYTES) ? (len - REVERSD_BYTES) : 0;
  58. len = CACHE_ALIGNED(len);
  59. local_irq_restore(flags);
  60. return len;
  61. }
  62. unsigned long dsp_codec_inc_rd_addr(struct audiodsp_priv *priv, int size)
  63. {
  64. unsigned long rd, flags;
  65. local_irq_save(flags);
  66. rd = dsp_codec_get_rd_addr(priv);
  67. rd = rd + size;
  68. if (rd >= priv->stream_buffer_end) {
  69. rd = rd - priv->stream_buffer_size;
  70. }
  71. DSP_WD(DSP_DECODE_OUT_RD_ADDR, ARM_2_ARC_ADDR_SWAP((void*)rd));
  72. local_irq_restore(flags);
  73. return rd;
  74. }
  75. u32 dsp_codec_get_current_pts(struct audiodsp_priv *priv)
  76. {
  77. #ifdef CONFIG_AM_PTSSERVER
  78. u32 pts;
  79. u32 delay_pts;
  80. int len;
  81. u64 frame_nums;
  82. int res;
  83. u32 offset, buffered_len, wp;
  84. mutex_lock(&priv->stream_buffer_mutex);
  85. if (priv->frame_format.channel_num == 0 || priv->frame_format.sample_rate == 0 || priv->frame_format.data_width == 0) {
  86. printk("unvalid audio format!\n");
  87. mutex_unlock(&priv->stream_buffer_mutex);
  88. return -1;
  89. }
  90. #if 0
  91. if (priv->stream_fmt == MCODEC_FMT_COOK) {
  92. pts = priv->cur_frame_info.offset;
  93. mutex_unlock(&priv->stream_buffer_mutex);
  94. } else
  95. #endif
  96. {
  97. buffered_len = DSP_RD(DSP_BUFFERED_LEN);
  98. wp = DSP_RD(DSP_DECODE_OUT_WD_PTR);
  99. offset = DSP_RD(DSP_AFIFO_RD_OFFSET1);
  100. if (priv->stream_fmt == MCODEC_FMT_COOK || priv->stream_fmt == MCODEC_FMT_RAAC) {
  101. pts = DSP_RD(DSP_AFIFO_RD_OFFSET1);
  102. res = 0;
  103. } else {
  104. res = pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300);
  105. //printk("pts_lookup_offset = %d, buffer_len = %d, res = %d\n", offset, buffered_len, res);
  106. if (!priv->first_lookup_over) {
  107. priv->first_lookup_over = 1;
  108. if (first_lookup_pts_failed(PTS_TYPE_AUDIO)) {
  109. priv->out_len_after_last_valid_pts = 0;
  110. priv->last_valid_pts = pts;
  111. mutex_unlock(&priv->stream_buffer_mutex);
  112. return pts;
  113. }
  114. }
  115. }
  116. if (res == 0) {
  117. //printk("check out pts == %x\n", pts);
  118. priv->out_len_after_last_valid_pts = 0;
  119. len = buffered_len + dsp_codec_get_bufer_data_len1(priv, wp);
  120. frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
  121. delay_pts = div64_u64(frame_nums*90, priv->frame_format.sample_rate/1000);
  122. //printk("cal delay pts == %x\n", delay_pts);
  123. if (pts > delay_pts) {
  124. pts -= delay_pts;
  125. } else {
  126. pts = 0;
  127. }
  128. priv->last_valid_pts = pts;
  129. //printk("len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
  130. // len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
  131. }
  132. else if (priv->last_valid_pts >= 0) {
  133. pts = priv->last_valid_pts;
  134. len = priv->out_len_after_last_valid_pts;
  135. frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
  136. pts += div64_u64(frame_nums*90, priv->frame_format.sample_rate/1000);
  137. //printk("last_pts = %d, len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
  138. // priv->last_valid_pts, len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
  139. }
  140. else {
  141. printk("checkout audio pts failed!\n");
  142. pts = -1;
  143. }
  144. mutex_unlock(&priv->stream_buffer_mutex);
  145. }
  146. return pts;
  147. #endif
  148. return -1;
  149. }