123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- #include <linux/module.h>
- #include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/cache.h>
- #include <asm/cacheflush.h>
- //#include <asm/arch/am_regs.h>
- #include <mach/am_regs.h>
- //#include <asm/bsp.h>
- #include <linux/amports/ptsserv.h>
- //#include <asm/dsp/dsp_register.h>
- #include "dsp_microcode.h"
- #include "audiodsp_module.h"
- #include "dsp_control.h"
- #include "dsp_mailbox.h"
- #include "dsp_codec.h"
- int dsp_codec_start(struct audiodsp_priv *priv)
- {
- return dsp_mailbox_send(priv, 1, M2B_IRQ2_DECODE_START, 0, 0, 0);
- }
- int dsp_codec_stop(struct audiodsp_priv *priv)
- {
- return dsp_mailbox_send(priv, 1, M2B_IRQ3_DECODE_STOP, 0, 0, 0);
- }
- int dsp_codec_get_bufer_data_len(struct audiodsp_priv *priv)
- {
- #define REVERSD_BYTES 32
- #define CACHE_ALIGNED(x) (x&(~0x1f))
- unsigned long rp, wp, len, flags;
- local_irq_save(flags);
- rp = dsp_codec_get_rd_addr(priv);
- wp = dsp_codec_get_wd_addr(priv);
- if (rp > wp) {
- len = priv->stream_buffer_size - (rp - wp);
- } else {
- len = (wp - rp);
- }
- len = (len > REVERSD_BYTES) ? (len - REVERSD_BYTES) : 0;
- len = CACHE_ALIGNED(len);
- local_irq_restore(flags);
- return len;
- }
- int dsp_codec_get_bufer_data_len1(struct audiodsp_priv *priv, unsigned long wd_ptr)
- {
- #define REVERSD_BYTES 32
- #define CACHE_ALIGNED(x) (x&(~0x1f))
- unsigned long rp, wp, len, flags;
- //if(wd_ptr != DSP_RD(DSP_DECODE_OUT_WD_ADDR))
- // printk("w1 == %x , w2 == %x, r == %x\n", DSP_RD(DSP_DECODE_OUT_WD_ADDR), wd_ptr, DSP_RD(DSP_DECODE_OUT_RD_ADDR));
- local_irq_save(flags);
- rp = dsp_codec_get_rd_addr(priv);
- wp = ARC_2_ARM_ADDR_SWAP(wd_ptr);
- if (rp > wp) {
- len = priv->stream_buffer_size - (rp - wp);
- } else {
- len = (wp - rp);
- }
- len = (len > REVERSD_BYTES) ? (len - REVERSD_BYTES) : 0;
- len = CACHE_ALIGNED(len);
- local_irq_restore(flags);
- return len;
- }
- unsigned long dsp_codec_inc_rd_addr(struct audiodsp_priv *priv, int size)
- {
- unsigned long rd, flags;
- local_irq_save(flags);
- rd = dsp_codec_get_rd_addr(priv);
- rd = rd + size;
- if (rd >= priv->stream_buffer_end) {
- rd = rd - priv->stream_buffer_size;
- }
- DSP_WD(DSP_DECODE_OUT_RD_ADDR, ARM_2_ARC_ADDR_SWAP((void*)rd));
- local_irq_restore(flags);
- return rd;
- }
- u32 dsp_codec_get_current_pts(struct audiodsp_priv *priv)
- {
- #ifdef CONFIG_AM_PTSSERVER
- u32 pts;
- u32 delay_pts;
- int len;
- u64 frame_nums;
- int res;
- u32 offset, buffered_len, wp;
- mutex_lock(&priv->stream_buffer_mutex);
- if (priv->frame_format.channel_num == 0 || priv->frame_format.sample_rate == 0 || priv->frame_format.data_width == 0) {
- printk("unvalid audio format!\n");
- mutex_unlock(&priv->stream_buffer_mutex);
- return -1;
- }
- #if 0
- if (priv->stream_fmt == MCODEC_FMT_COOK) {
- pts = priv->cur_frame_info.offset;
- mutex_unlock(&priv->stream_buffer_mutex);
- } else
- #endif
- {
- buffered_len = DSP_RD(DSP_BUFFERED_LEN);
- wp = DSP_RD(DSP_DECODE_OUT_WD_PTR);
- offset = DSP_RD(DSP_AFIFO_RD_OFFSET1);
- if (priv->stream_fmt == MCODEC_FMT_COOK || priv->stream_fmt == MCODEC_FMT_RAAC) {
- pts = DSP_RD(DSP_AFIFO_RD_OFFSET1);
- res = 0;
- } else {
- res = pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts, 300);
- //printk("pts_lookup_offset = %d, buffer_len = %d, res = %d\n", offset, buffered_len, res);
- if (!priv->first_lookup_over) {
- priv->first_lookup_over = 1;
- if (first_lookup_pts_failed(PTS_TYPE_AUDIO)) {
- priv->out_len_after_last_valid_pts = 0;
- priv->last_valid_pts = pts;
- mutex_unlock(&priv->stream_buffer_mutex);
- return pts;
- }
- }
- }
- if (res == 0) {
- //printk("check out pts == %x\n", pts);
- priv->out_len_after_last_valid_pts = 0;
- len = buffered_len + dsp_codec_get_bufer_data_len1(priv, wp);
- frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
- delay_pts = div64_u64(frame_nums*90, priv->frame_format.sample_rate/1000);
- //printk("cal delay pts == %x\n", delay_pts);
- if (pts > delay_pts) {
- pts -= delay_pts;
- } else {
- pts = 0;
- }
- priv->last_valid_pts = pts;
- //printk("len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
- // len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
- }
- else if (priv->last_valid_pts >= 0) {
- pts = priv->last_valid_pts;
- len = priv->out_len_after_last_valid_pts;
- frame_nums = (len * 8 / (priv->frame_format.data_width * priv->frame_format.channel_num));
- pts += div64_u64(frame_nums*90, priv->frame_format.sample_rate/1000);
- //printk("last_pts = %d, len = %d, data_width = %d, channel_num = %d, frame_nums = %lld, sample_rate = %d, pts = %d\n",
- // priv->last_valid_pts, len, priv->frame_format.data_width,priv->frame_format.channel_num, frame_nums, priv->frame_format.sample_rate, pts);
- }
- else {
- printk("checkout audio pts failed!\n");
- pts = -1;
- }
- mutex_unlock(&priv->stream_buffer_mutex);
- }
- return pts;
- #endif
- return -1;
- }
|