123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578 |
- #include "drv_types.h"
- #include <linux/kernel.h> // abs(), max()
- #include <asm/mips-boards/drvmem.h>
- #include <asm/io.h>
- #include "hdmi.h"
- #include "hdmi_dbg.h"
- #include "hdmi_hw.h"
- #include "hdmi_audio.h"
- #include "hdmi_cmdq.h"
- #include "hdmi_notice.h"
- #include "gpioi2c.h"
- #include "sysreg.h"
- #include "drv_audio_internal.h"
- #include "../audio/drv_audio_common.h"
- #include "spdif_parser.h"
- #ifdef INIT_BY_KMF
- #include <drv2kmf.h>
- #endif
- //In previous software architecture, we only have multiple PCM channel case in media and HDMI.
- //In order to reduce memory usage in new architecture, We want to block Multi-pcm case in HDMI driver.
- //#define CONFIG_HDMI_Support_MULTI_PCM
- void HDMI_Audio_ChannelLocked(void);
- typedef enum
- {
- HDMI_PATH_LINEAR = 0,
- HDMI_PATH_PARSE,
- HDMI_PATH_BYPASS,
- } HDMI_PATH_T;
- //use smaller sample nuber to improve AV sync issue
- #define LINEAR_SAMPLE_NUMBER 768
- #define Linear_Buffer_Number 32
- //#define LINEAR_SAMPLE_NUMBER 1536
- //#define Linear_Buffer_Number 16
- #define PARSE_BUFFER_SIZE 4096
- #define BYPASS_SAMPLE_NUMBER 1536
- #define NonLinear_ByPass_Buffer_Number 16
- #define NonLinear_Parse_Buffer_Number 16
- typedef struct _WRITEBUF_DESC
- {
- union
- {
- UINT32 dw1;
- struct
- {
- UINT32 Buffer_Valid: 1;
- UINT32 Discontinuous: 1;
- UINT32 Pause_Exist: 1;
- UINT32 Buffer_Full: 1;
- UINT32 reserved1: 12;
- UINT32 b_size: 16;
- };
- };
- union
- {
- UINT32 dw2;
- struct
- {
- UINT32 b_dlth: 16;
- UINT32 reserved2: 8;
- UINT32 b_th: 8;
- };
- };
- union
- {
- UINT32 dw3;
- UINT32 PTS;
- };
- union
- {
- UINT32 dw4;
- struct
- {
- UINT32 PTS_high: 1;
- UINT32 reserved3: 15;
- UINT32 Vbmap: 16;
- };
- };
- union
- {
- UINT32 dw5;
- struct
- {
- UINT32 reserved4: 4;
- UINT32 b1_sadd: 27;
- UINT32 reserved5: 1;
- };
- };
- union
- {
- UINT32 dw6;
- struct
- {
- UINT32 reserved6: 4;
- UINT32 b2_sadd: 27;
- UINT32 reserved7: 1;
- };
- };
- union
- {
- UINT32 dw7;
- struct
- {
- UINT32 reserved8: 4;
- UINT32 b3_sadd: 27;
- UINT32 reserved9: 1;
- };
- };
- union
- {
- UINT32 dw8;
- struct
- {
- UINT32 reservedA: 4;
- UINT32 b4_sadd: 27;
- UINT32 reservedB: 1;
- };
- };
- } WRITEBUF_DESC, *WRITEBUF_DESC_PTR;
- typedef struct _HDMI_PARSER
- {
- struct
- {
- UINT32 audio_type: 1; //LINEAR/NONLINEAR
- UINT32 sfreq: 4;
- UINT32 osfreq: 4;
- UINT32 wordLen: 4;
- UINT32 reserved1: 3;
- UINT32 chcount: 3;
- UINT32 spkplace: 8;
- UINT32 downmixinhb: 1;
- UINT32 lvshVal: 4;
- };
- struct
- {
- UINT32 offset_flag: 1;
- UINT32 bDualChannel: 1;
- UINT32 TX_path: 3;
- UINT32 path: 2;
- // see defined values HDMI_PATH_xxxx
- UINT32 sp_non_linear_type: 5;
- UINT32 codingMode: 3;
- // codingMode
- // 0:1+1 dual mode, 1:C, 2:L R, 3: L C R,
- // 4:L R S, 5:L C R S, 6:L R SL SR, 7:L C R SL SR
- // AC3 - The same with codingMode
- // MPEG - 0:L R, 1:Joint Stereo, 2:Dual channel, 3:Single channel
- UINT32 bSupportNotice: 1;
- UINT32 relock_count: 8;
- UINT32 reserver2: 8;
- //~cdlin
- };
- INT32 reset516_count;
- INT32 audio_stream_type; //AC3 or MPEG
- UINT32 audio_offset;
- UINT32 NLdelayCnt;
- UINT32 sample_number;
- UINT32 writeBufNum;
- UINT32 bufSize;
- UINT8 *writeBuf;
- UINT8 *writeBufDsp;
- UINT32 wbuf_index;
- UINT8 cmdq[32];
- UINT32 Freq;
- UINT32 pPts;
- } HDMI_PARSER, *HDMI_PARSER_PTR;
- static HDMI_PARSER g_hp;
- static UINT8 Reset_Count = 0;
- volatile BOOL bReset = false;
- static volatile BOOL audio_active = false;
- volatile BOOL chLock_flag = false;
- volatile INT32 menu_path = AUDIO_MENU_INTERNAL;
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- extern BOOL MHL_CABLE_IN;
- extern BOOL MHL_CTS;
- #endif
- static UINT32 getDW(UINT8* ptr)
- {
- return ((*ptr << 24) | (*(ptr + 1) << 16) | (*(ptr + 2) << 8) | *(ptr + 3));
- }
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- static UINT8 getSpeakerPlacement(UINT32 spkplace)
- {
- UINT8 chinvalid[32] =
- {
- 0xfc, 0xf8, 0xf4, 0xf0, 0xec, 0xe8, 0xe4, 0xe0,
- 0xcc, 0xc8, 0xc4, 0xc0, 0x8c, 0x88, 0x84, 0x80,
- 0x0c, 0x08, 0x04, 0x00, 0x3c, 0x38, 0x34, 0x30,
- 0x2c, 0x28, 0x24, 0x20, 0x0c, 0x08, 0x04, 0x00
- };
- return chinvalid[spkplace];
- }
- #endif
- static UINT8 getChannelCount(UINT32 spkplace, UINT32 chcount)
- {
- // chcnt. 0 - 2ch, 1- 5.1ch, 2 - 7.1 ch
- UINT8 chcnt_spk[32] =
- {
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
- };
- static UINT8 chcnt_chn[8] =
- {
- 2, 0, 1, 1, 1, 1, 2, 2
- };
- return (chcnt_spk[spkplace] < chcnt_chn[chcount]) ? chcnt_spk[spkplace] : chcnt_chn[chcount];
- }
- static UINT32 getFreq(UINT32 idx)
- {
- UINT32 ofreq_list[16] =
- {
- 1, 192000, 12000, 176400, 1 , 96000, 8000, 88200,
- 16000, 24000, 11025, 22050, 32000, 48000, 1, 44100
- };
- return ofreq_list[idx];
- }
- static BOOL verifyFreq(HDMI_PARSER_PTR hp, UINT32 pts_dif2)
- {
- UINT32 pts_dif1 = (hp->sample_number * 45000) / hp->Freq;
- if((hp->sp_non_linear_type)== 21) //EAC3 (Dolby Digital Plus) bypass verfy freq.
- return true;
-
- if (abs(pts_dif1 - pts_dif2) > 10)
- {
- UINT32 rfreq = 0, sfreq = 0, min_dist = 192000, dist = 0;
- UINT8 osfreq = 13; //48k
- INT32 i = 0;
- rfreq = (45000 * hp->sample_number) / pts_dif2;
- for (i = 0; i < 16; i++)
- {
- sfreq = getFreq(i);
- dist = (sfreq < rfreq) ? (rfreq - sfreq) : (sfreq - rfreq);
- if (dist < min_dist)
- {
- min_dist = dist;
- osfreq = i;
- }
- }
- if (osfreq == hp->osfreq)
- {
- return true;
- }
- hp->osfreq = osfreq;
- hp->Freq = getFreq(hp->osfreq);
- if (hp->Freq == 1)
- {
- return true;
- }
- return false;
- }
- return true;
- }
- static UINT8 AUDIO_freq(INT32 freq)
- {
- static INT32 dsp_freq_list[9] =
- {24000, 48000, 96000, 192000, 22050, 44100, 88200, 176400, 32000};
- UINT8 i = 0;
- if (freq == 0)
- {
- return 15;
- }
- for (i = 0; i < sizeof(dsp_freq_list) / sizeof(INT32); i++)
- {
- if (freq == dsp_freq_list[i])
- {
- return i;
- }
- }
- return 15;
- }
- #define HDMI_AUDIO_PTS_OFFSET 60 // PCM BUFFER NUMBER = 16, 192KHZ FRAME TIME = 4ms,, modify PTS OFFSET = 60ms ( 60/4 = 15 < 16)
- #define HDMI_AUDIO_PTS_OFFSET_NL 100
- static void AUDIO_setDelayTime(HDMI_PARSER_PTR hp)
- {
- if (hp->path == HDMI_PATH_LINEAR || hp->path == HDMI_PATH_BYPASS)
- {
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- if((MHL_CTS == TRUE)&&(MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet() == CONFIG_HDMI_MHL_PORT))
- {
- hp->audio_offset = 250 * 90; // 100 ms
- }
- else
- {
- hp->audio_offset = HDMI_AUDIO_PTS_OFFSET * 90; // 60 ms
- }
- #else
- hp->audio_offset = HDMI_AUDIO_PTS_OFFSET * 90; // 60 ms
-
- #endif
- hp->NLdelayCnt = 0;
- }
- else // hp->path == HDMI_PATH_PARSE
- {
- if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR ||
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM)
- {
- hp->audio_offset = HDMI_AUDIO_PTS_OFFSET_NL * 90; // 100 ms
- hp->NLdelayCnt = ((30 * hp->Freq) / 1000) >> 5;
- }
- else
- {
- hp->audio_offset = HDMI_AUDIO_PTS_OFFSET_NL * 90;// 100 ms
- hp->NLdelayCnt = 0;
- }
- }
- }
- static void AUDIO_ResetLock(void)
- {
- HDMI_PARSER_PTR hp = &g_hp;
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 0);
- HDMI_Interrupt_Disable(INTR_Buffer_Change_Pulse);
- while (HDMI_RegisterRead(HDMIRX_Buffer_chg_cnt))
- {
- HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Buffer_Change_Pulse); //clear
- }
- memset(hp, 0, sizeof(HDMI_PARSER));
- HDMI_AudioResetDecoder();
- chLock_flag = false;
- HDMI_Audio_ChannelLocked();
- HDMI_Interrupt_Enable(INTR_Buffer_Change_Pulse);
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 1);
- }
- void DRV_HDMI_AudioEnable(void)
- {
- TVFE_Audio_Mute_t MC;
- hdmidbg("%s\n", __FUNCTION__);
- #define PRECHARGE_MODE 1
- #define BURST_MODE 0 // Default 0:128, 1:256, 2:512
- chLock_flag = false;
- if (audio_active)
- {
- hdmidbg("\tdone\n");
- return;
- }
- if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) == 0)
- {
- hdmidbg("\tCan't enable audio in dvi\n");
- return;
- }
- if (HDMI_RegisterRead(HDMIRX_AS_exist))
- {
- hdmidbg("\tNoraml Audio!\n");
- HDMI_RegisterWrite(HDMIRX_R_HBRAS_sel, 0);
- }
- else
- {
- if (HDMI_RegisterRead(HDMIRX_HBRAS_exist))
- {
- hdmidbg("\tHBRAS Audio!\n");
- HDMI_RegisterWrite(HDMIRX_R_HBRAS_sel, 1);
- }
- else
- {
- hdmidbg("\tNoraml Audio!\n");
- HDMI_RegisterWrite(HDMIRX_R_HBRAS_sel, 0);
- }
- }
- sysset_hdmi_stcclk();
- HDMI_RegisterWrite(HDMIRX_R_parsing_en, 0);
- HDMI_RegisterWrite(HDMIRX_R_unlock_th, 0x2);
- HDMI_RegisterWrite(HDMIRX_R_layout_detect, 1);
- HDMI_RegisterWrite(HDMIRX_R_layout_th, 0);
- HDMI_RegisterWrite(HDMIRX_R_mem_ap_en, PRECHARGE_MODE);
- HDMI_RegisterWrite(HDMIRX_R_as_mem_mode, BURST_MODE);
- HDMI_Interrupt_Enable(INTR_Channel_Status_Lock_Pulse);
- HDMI_RegisterWrite(HDMIRX_R_audio_enable, 1);
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 0);
- HDMI_Interrupt_Disable(INTR_Buffer_Change_Pulse);
- audio_active = true;
- //ADD MUTE PROTECT TO AVOID UNSMOOTH AUDIO OUTPUT
- MC.Enable = 0;
- MC.Mute_Delay= 0;
- MC.Mute_TXSpeed= 0;
- MC.Mute_Path = TVFE_AUDIO_MUTE_DRV_ALL_PATH;
-
- DRV_AUDIO_DC_SetMute(&MC);
- //~MUTE PROTECT
- }
- void DRV_HDMI_AudioDisable(void)
- {
- TVFE_Audio_Mute_t MC;
- hdmidbg("%s\n", __FUNCTION__);
- chLock_flag = false;
- if (!audio_active)
- {
- hdmidbg("\tdone\n");
- return;
- }
- //ADD MUTE PROTECT TO AVOID UNSMOOTH AUDIO OUTPUT
- MC.Enable = 1;
- MC.Mute_Delay= 0;
- MC.Mute_TXSpeed= 0;
- MC.Mute_Path = TVFE_AUDIO_MUTE_DRV_ALL_PATH;
-
- DRV_AUDIO_DC_SetMute(&MC);
- //~MUTE PROTECT
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 0);
- HDMI_Interrupt_Disable(INTR_Buffer_Change_Pulse | INTR_Channel_Status_Lock_Pulse | INTR_audio_sample_coming | INTR_HBR_audio_sample_coming | INTR_ACP_packets);
- HDMI_RegisterWrite(HDMIRX_R_audio_enable, 0);
- audio_active = false;
- memset(&g_hp, 0, sizeof(HDMI_PARSER));
- }
- void DRV_HDMI_AudioSetOutputPath(UINT8 menu_select)
- {
- BOOL bAudioEnable;
- bAudioEnable = HDMI_RegisterRead(HDMIRX_R_audio_enable) ? TRUE : FALSE;
- if (bAudioEnable)
- {
- DRV_HDMI_AudioDisable();
- }
- menu_path = menu_select;
- if (bAudioEnable)
- {
- DRV_HDMI_AudioEnable();
- }
- }
- void DRV_HDMI_AudioRestart(void)
- {
- hdmidbg("%s\n", __FUNCTION__);
- if (HDMI_RegisterRead(HDMIRX_R_audio_enable))
- {
- DRV_HDMI_AudioDisable();
- DRV_HDMI_AudioEnable();
- }
- else
- {
- if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) == 1)
- {
- hdmidbg("%s:input signal changed form dvi to hdmi!\n", __FUNCTION__);
- DRV_HDMI_AudioDisable();
- DRV_HDMI_AudioEnable();
- }
- else
- {
- hdmidbg("%s:Skipped! Audio is not enable!\n", __FUNCTION__);
- }
- }
- }
- void HDMI_Audio_ChannelLocked(void)
- {
- HDMI_PARSER_PTR hp = &g_hp;
- pAUDIO_CMDQ cmdq = (pAUDIO_CMDQ)(hp->cmdq);
- UINT8 audio_type = (HDMI_RegisterRead(HDMIRX_R_ACS_CSts) & 0x2) >> 1;
- UINT8 chcount = HDMI_RegisterRead(HDMIRX_R_Ado_CC) & 0x7;
- UINT8 spkplace = HDMI_RegisterRead(HDMIRX_R_Ado_CA) & 0x1f;
- UINT8 downmixinhb = HDMI_RegisterRead(HDMIRX_R_Ado_DMInh);
- UINT8 lvshVal = HDMI_RegisterRead(HDMIRX_R_Ado_LSV);
- UINT8 osfreq = ~(HDMI_RegisterRead(HDMIRX_R_ACS_Sfeq)) & 0xf;
- UINT8 sp_non_linear_type = HDMI_RegisterRead(HDMIRX_R_sp_non_linear_type);
- UINT32 i = 0;
- if (menu_path == AUDIO_MENU_MUTE)
- {
- hp->TX_path = menu_path;
- return;
- }
-
- if (chLock_flag)
- {
- if (hp->osfreq != osfreq || hp->audio_type != audio_type || hp->chcount != chcount || hp->spkplace != spkplace)
- {
- hdmidbg("channel status is changed\n");
- HDMI_Audio_ChannelUnlocked();
- }
- else
- {
- if(hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT)
- {
- //PHILIPS DVD player updated audio buffer before ch lock function when switch play DD&DDP file at ARC case
- //but buffer update fucntion verfies PTS to change sfreq(48k<->192k), ch lock function will show channel status no changed
- //add check sp_non_linear_type to do error handle.
- if(hp->sp_non_linear_type != sp_non_linear_type)
- {
- hdmidbg("channel status is changed, ori_type=%d, hw_type=%d\n", hp->sp_non_linear_type, sp_non_linear_type);
- HDMI_Audio_ChannelUnlocked();
- }
- }
- else
- {
- hdmidbg("channel status no changed, return\n");
- return;
- }
- }
- }
- HDMI_RegisterWrite(HDMIRX_R_disc_tout, 0x48000); // 24576000x12ms
- HDMI_RegisterWrite(HDMIRX_R_as_w_timeout, 0x0);
- // Reset Audio Decoder
- bReset = true;
- // hp initialization
- hp->offset_flag = false;
- hp->reset516_count = 0;
- hp->relock_count = 0;
- hp->bDualChannel = false;
- hp->codingMode = 7; //AC3 5.1ch
- hp->bSupportNotice = false;
- hp->TX_path = menu_path; //Menu decide the TX path.
- hp->wbuf_index = 0; // Write buffer Index pointer
- hp->audio_type = audio_type;
- hp->wordLen = HDMI_RegisterRead(HDMIRX_R_ACS_Wlen);
- // hp->osfreq = HDMI_RegisterRead(HDMIRX_R_ACS_OSFeq);
- // hp->sfreq = HDMI_RegisterRead(HDMIRX_R_ACS_Sfeq);
- hp->osfreq = osfreq;
- hp->chcount = chcount;
- hp->spkplace = spkplace;
- hp->downmixinhb = downmixinhb;
- hp->lvshVal = lvshVal;
- // hp->sp_non_linear_type = HDMI_RegisterRead(HDMIRX_R_sp_non_linear_type);
- hp->sp_non_linear_type = 1; //Default AC3 Format
- hp->pPts = 0;
- hp->Freq = getFreq(hp->osfreq);
- hdmidbg("%s: %s audio %dK\n", __FUNCTION__,
- audio_type ? "nonlinear" : "linear",
- hp->Freq / 1000);
- /* Initialize audio command queue */
- cmdq->CID = AUDIO_CID;
- cmdq->RxType = AUDIO_RX_TYPE_HDMI;
- cmdq->sfreq = AUDIO_freq(hp->Freq);
- cmdq->ZeroStuffLen = 0;
- if (hp->audio_type) // nonlinear
- {
- hp->lvshVal = 0; //we should not take these two variables in account in NonLinear path.
- hp->downmixinhb = 0; // Set to 0.
- if (hp->TX_path == AUDIO_MENU_INTERNAL || hp->TX_path == AUDIO_MENU_EXTERNAL)
- {
- hp->path = HDMI_PATH_PARSE;
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_I2S;
- }
- else if (hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT)
- {
- hp->path = HDMI_PATH_BYPASS;
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_SPDIF;
- }
- else if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR)
- {
- hp->path = HDMI_PATH_PARSE;
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_NONLINEAR;
- }
- else if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM)
- {
- hp->path = HDMI_PATH_PARSE;
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_LINEAR;
- }
- }
- else //linear
- {
- hp->path = HDMI_PATH_LINEAR;
- if (hp->TX_path == AUDIO_MENU_INTERNAL || hp->TX_path == AUDIO_MENU_EXTERNAL)
- {
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_I2S;
- }
- else if (hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT)
- {
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_SPDIF;
- }
- else if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR ||
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM)
- {
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_LINEAR;
- }
- }
- if (hp->path == HDMI_PATH_LINEAR) //linear
- {
- hdmidbg("<LINEAR>\n");
- HDMI_RegisterWrite(HDMIRX_R_parsing_en, 0);
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- HDMI_RegisterWrite(HDMIRX_R_rx_ch_set, 0x2);
- #else
- /* Patch: Only stereo pcm input is allowed. */
- HDMI_RegisterWrite(HDMIRX_R_rx_ch_set, 0x0);
- #endif
- /* Setup write buffer number */
- HDMI_RegisterWrite(HDMIRX_R_wbuf_num, Linear_Buffer_Number - 1);
- hp->bufSize = LINEAR_SAMPLE_NUMBER << 3; //Buffer size (1 group) for linear audio data.
- hp->writeBufNum = Linear_Buffer_Number;
- /* Note: Four write buffer group should be in different blank. Blank size is 64 bytes */
- hp->writeBufDsp = (UINT8*)AUDIO_RX_HDMI_DESP_BUFF_ADDR;
- hp->writeBuf = (UINT8*)AUDIO_PCM_BUFF_ADDR;
- /* Setup write buffer descriptor for hdmi audio rx */
- HDMI_RegisterWrite(HDMIRX_R_dma_start_addr, ((UINT32)hp->writeBufDsp & 0x1fffffff) >> 4);
- for (i = 0; i < hp->writeBufNum; i++)
- {
- WRITEBUF_DESC_PTR wbufdsc_ptr = (WRITEBUF_DESC_PTR)(hp->writeBufDsp + i * sizeof(WRITEBUF_DESC));
- wbufdsc_ptr->Buffer_Valid = 0;
- wbufdsc_ptr->b_size = hp->bufSize >> 4;
- wbufdsc_ptr->dw5 = 0;
- wbufdsc_ptr->dw6 = 0;
- wbufdsc_ptr->dw7 = 0;
- wbufdsc_ptr->dw8 = 0;
- wbufdsc_ptr->b1_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize))) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b1_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b1_sadd);
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- wbufdsc_ptr->b2_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize) + 1 * (hp->writeBufNum * hp->bufSize) + 64 * 1)) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b2_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b2_sadd);
- wbufdsc_ptr->b3_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize) + 2 * (hp->writeBufNum * hp->bufSize) + 64 * 2)) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b3_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b3_sadd);
- wbufdsc_ptr->b4_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize) + 3 * (hp->writeBufNum * hp->bufSize) + 64 * 3)) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b4_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b4_sadd);
- #endif
- }
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- memset((UINT8*)((((WRITEBUF_DESC_PTR) hp->writeBufDsp)->b2_sadd << 4) | 0xa0000000), 0, hp->bufSize * hp->writeBufNum);
- memset((UINT8*)((((WRITEBUF_DESC_PTR) hp->writeBufDsp)->b3_sadd << 4) | 0xa0000000), 0, hp->bufSize * hp->writeBufNum);
- #endif
- cmdq->flag = AUDIO_FLAG_PCM_OUT;
- cmdq->inDataType = AUDIO_DATA_TYPE_PCM;
- cmdq->outDataType = AUDIO_DATA_TYPE_PCM;
- cmdq->FrameNo = hp->writeBufNum;// write buffer size
- hp->audio_stream_type = cmdq->inDataType;
- hp->sample_number = LINEAR_SAMPLE_NUMBER;
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- cmdq->spkplace = getSpeakerPlacement(spkplace);
- cmdq->chcnt = getChannelCount(spkplace, chcount);
- #else
- /* Patch: Only stereo audio is allowed now */
- cmdq->spkplace = 0xfc;
- cmdq->chcnt = 0;
- #endif
- cmdq->sp_non_linear_type = 0;
- cmdq->sample_bit = hp->wordLen;
- }
- else if (hp->path == HDMI_PATH_PARSE) // parse mode
- {
- hdmidbg("<PARSE>\n");
- HDMI_RegisterWrite(HDMIRX_R_parsing_en, 1);
- HDMI_RegisterWrite(HDMIRX_R_rx_ch_set, 0); // one group in one write buffer
- HDMI_RegisterWrite(HDMIRX_R_wbuf_num, NonLinear_Parse_Buffer_Number - 1);
- /* Swap high low bytes in parse mode */
- HDMI_RegisterWrite(HDMIRX_R_byte_swap, 0x01);
- hp->bufSize = PARSE_BUFFER_SIZE;
- hp->writeBufNum = NonLinear_Parse_Buffer_Number;
- hp->writeBufDsp = (UINT8*)AUDIO_RX_HDMI_DESP_BUFF_ADDR;
- hp->writeBuf = (UINT8*)AUDIO_CMD_BUFF_ADDR;
- /* Setup write buffer descriptor for hdmi audio rx */
- HDMI_RegisterWrite(HDMIRX_R_dma_start_addr, ((UINT32)hp->writeBufDsp & 0x1fffffff) >> 4);
- for (i = 0; i < hp->writeBufNum; i++)
- {
- WRITEBUF_DESC_PTR wbufdsc_ptr = (WRITEBUF_DESC_PTR)(hp->writeBufDsp + i * sizeof(WRITEBUF_DESC));
- wbufdsc_ptr->Buffer_Valid = 0;
- wbufdsc_ptr->b_size = hp->bufSize >> 4;
- wbufdsc_ptr->b_th = 1; //NonLinear, 1 frame in one write buffer
- wbufdsc_ptr->dw5 = 0;
- wbufdsc_ptr->b1_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize))) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b1_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b1_sadd);
- }
- cmdq->flag = AUDIO_FLAG_DECODING;
- hp->audio_stream_type = cmdq->inDataType = AUDIO_DATA_TYPE_AC3;
- hp->sample_number = 1536;
- cmdq->outDataType = AUDIO_DATA_TYPE_PCM;
- cmdq->FrameNo = 1; //One frame in buffer will be decoded.
- cmdq->spkplace = 0;
- cmdq->chcnt = 0;
- cmdq->sp_non_linear_type = 0;
- cmdq->sample_bit = 0;
- }
- else if (hp->path == HDMI_PATH_BYPASS)
- {
- hdmidbg("<BYPASS>\n");
- HDMI_RegisterWrite(HDMIRX_R_parsing_en, 0);
- HDMI_RegisterWrite(HDMIRX_R_rx_ch_set, 0); // one group in one write buffer
- HDMI_RegisterWrite(HDMIRX_R_wbuf_num, NonLinear_ByPass_Buffer_Number - 1); //ByPass mode, 32 write buffer now
- hp->bufSize = BYPASS_SAMPLE_NUMBER * 8;
- hp->writeBufNum = NonLinear_ByPass_Buffer_Number;
- hp->writeBufDsp = (UINT8*)AUDIO_RX_HDMI_DESP_BUFF_ADDR;
- hp->writeBuf = (UINT8*)AUDIO_PCM_BUFF_ADDR;
- /* Setup write buffer descriptor for hdmi audio rx */
- HDMI_RegisterWrite(HDMIRX_R_dma_start_addr, ((UINT32)hp->writeBufDsp & 0x1fffffff) >> 4);
- for (i = 0; i < hp->writeBufNum; i++)
- {
- WRITEBUF_DESC_PTR wbufdsc_ptr = (WRITEBUF_DESC_PTR)(hp->writeBufDsp + i * sizeof(WRITEBUF_DESC));
- wbufdsc_ptr->Buffer_Valid = 0;
- wbufdsc_ptr->b_size = hp->bufSize >> 4;
- wbufdsc_ptr->b_th = 1; //NonLinear, 1 frame in one write buffer
- wbufdsc_ptr->dw5 = 0;
- wbufdsc_ptr->b1_sadd = (((UINT32)(hp->writeBuf + i * (hp->bufSize))) & 0x1fffffff) >> 4;
- wbufdsc_ptr->b1_sadd = GET_ADDR_FOR_HW(wbufdsc_ptr->b1_sadd);
- }
- cmdq->flag = AUDIO_FLAG_BYPASS;
- hp->audio_stream_type = 0;
- cmdq->inDataType = cmdq->outDataType = AUDIO_DATA_TYPE_AC3;
-
- //hp->audio_stream_type = cmdq->inDataType = cmdq->outDataType = AUDIO_DATA_TYPE_AC3;
- hp->sample_number = BYPASS_SAMPLE_NUMBER;
- cmdq->FrameNo = 1;
- cmdq->spkplace = 0;
- cmdq->chcnt = 0;
- //cmdq->sp_non_linear_type=hp->sp_non_linear_type;
- cmdq->sample_bit = 0;
- }
- /* HDMI Source SPDIF OUT fix at SPDIF_WORD_LENGTH_16_BITS */
- //cmdq->sample_bit = 0x2;// SPDIF_WORD_LENGTH_16_BITS = 0x2,
- hdmidbg(" writeBufDsp 0x%p\n", hp->writeBufDsp);
- hdmidbg(" writeBuf 0x%p\n", hp->writeBuf);
- AUDIO_setDelayTime(hp);
- chLock_flag = true;
- HDMI_Interrupt_Enable(INTR_Buffer_Change_Pulse);
- //HDMI_Interrupt_Enable(INTR_ACP_packets);
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 1);
- }
- void HDMI_Audio_ChannelUnlocked(void)
- {
- HDMI_PARSER_PTR hp = &g_hp;
- HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 0);
- HDMI_Interrupt_Disable(INTR_Buffer_Change_Pulse);
- while (HDMI_RegisterRead(HDMIRX_Buffer_chg_cnt))
- {
- HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Buffer_Change_Pulse); //clear
- }
- // set_current_state(TASK_UNINTERRUPTIBLE);
- // schedule_timeout(1);
- memset(hp, 0, sizeof(HDMI_PARSER));
- HDMI_AudioResetDecoder();
- chLock_flag = false;
- }
- static UINT32 ddp_get_freq(unsigned char *ptr)
- {
- UINT32 sfreq = 0;
- if (ptr[0] == 0x0b && ptr[1] == 0x77)
- {
- UINT32 fscod_tbl[4] = {48000, 44100, 32000, 0};
- UINT32 fscod2_tbl[4] = {24000, 22050, 16000, 0};
- /* check fscod */
- if ((ptr[4] >> 6) != 0x3)
- {
- sfreq = fscod_tbl[ptr[4] >> 6];
- }
- else
- {
- /* fscod2_numblkscod */
- sfreq = fscod2_tbl[(ptr[4] >> 4) & 0x3];
- }
- }
- return sfreq;
- }
- static UINT32 ddp_get_framesize(UINT8 *ptr)
- {
- UINT32 fsz = 0;
- if (ptr[0] == 0x0b && ptr[1] == 0x77)
- {
- UINT32 frmsize_tlb[3][38] =
- {
- {64, 64, 80, 80, 96, 96, 112, 112, 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, 384, 448, 448, 512, 512, 640, 640, 768, 768, 896, 896, 1024, 1024, 1152, 1152, 1280, 1280},
- {69, 70, 87, 88, 104, 105, 121, 122, 139, 140, 174, 175, 208, 209, 243, 244, 278, 279, 348, 349, 417, 418, 487, 488, 557, 558, 696, 697, 835, 836, 975, 976, 1114, 1115, 1253, 1254, 1393, 1394},
- {96, 96, 120, 120, 144, 144, 168, 168, 192, 192, 240, 240, 288, 288, 336, 336, 384, 384, 480, 480, 576, 576, 672, 672, 768, 768, 960, 960, 1152, 1152, 1344, 1344, 1536, 1536, 1728, 1728, 1920, 1920}
- };
- UINT8 bsid = ptr[5] >> 3;
- if (bsid <= 8)
- {
- /* frmsizecod < 38 && fscod < 3 */
- if ( /*(ptr[4] & 0x1f) < 38 && */ (ptr[4] >> 6) < 3) // (ptr[4] & 0x1f) < 38 is always TRUE
- {
- /* dd size = 2 * frmsize_tlb[fscod][frmsizecod] */
- fsz = 2 * frmsize_tlb[ptr[4] >> 6][ptr[4] & 0x1f];
- }
- }
- else if (bsid >= 11 && bsid <= 16)
- {
- /* ddp size = 2 * (ec3_frmsize + 1) */
- fsz = 2 * ((((ptr[2] & 0x7) << 8) | ptr[3]) + 1);
- }
- }
- return fsz;
- }
- static BOOL ddp_substrm_frame(UINT8 *ptr)
- {
- if (ptr[0] == 0x0b && ptr[1] == 0x77)
- {
- return (ptr[2] & 0xf8);
- }
- return FALSE;
- }
- #define ALIGN4(sz) ((sz+3) & (~0x3))
- void ddp_receive_frames(void *dev,
- UINT8 *ddp, UINT32 ddpsz, UINT32 pts)
- {
- HDMI_PARSER_PTR hp = (HDMI_PARSER_PTR)dev;
- AUDIO_CMDQ gcmdq, *cmdq = &gcmdq;
- BOOL validFrame = FALSE;
- UINT32 frmsz = 0, freq = 0;
- UINT32 parsed_sz = 0;
- UINT8 *ptr = NULL;
- UINT8 ACP_type = 0xff;
- if (ddp == NULL || ddpsz < 24)
- {
- hdmidbg("%s: Invalid IEC61937 buffer\n", __FUNCTION__);
- return;
- }
- memcpy(cmdq, &hp->cmdq, sizeof(AUDIO_CMDQ));
- //hdmidbg("%s: ddp 0x%p ddpsz %d pts 0x%08x\n", __FUNCTION__, ddp, ddpsz, pts);
- /* Parse and validate whole IEC61937 payload */
- parsed_sz = 8;
- ptr = ddp + parsed_sz;
- for (; parsed_sz < ddpsz; ptr += ALIGN4(frmsz))
- {
- frmsz = ddp_get_framesize(ptr);
- freq = ddp_get_freq(ptr);
- validFrame = (frmsz && freq) ? TRUE : FALSE;
- if (validFrame == FALSE)
- {
- break;
- }
- /* Patch: Audio Decoder only accept 4 byte aligned pointer,
- adjust the buffer to meet the requirement. */
- parsed_sz += frmsz;
- if ((ALIGN4(frmsz) != frmsz) && ptr + frmsz < ddp + ddpsz)
- {
- memmove(ptr + ALIGN4(frmsz), ptr + frmsz, ddpsz - parsed_sz);
- }
- }
- cmdq->flag = AUDIO_FLAG_DECODING;
- cmdq->pause = 0;
- cmdq->discontinue = 0;
- cmdq->chcnt = 0;
- cmdq->sfreq = AUDIO_freq(freq);
- cmdq->inDataType = AUDIO_DATA_TYPE_EAC3;
- cmdq->outDataType = AUDIO_DATA_TYPE_PCM;
- cmdq->DataPtr = (UINT32)ddp;
- cmdq->DataSize = hp->sample_number;
- cmdq->PTS_High = pts >> 31;
- cmdq->PTS = pts << 1;
- cmdq->spdif_channel_status_category_code = HDMI_RegisterRead(HDMIRX_R_ACS_CatC);
- cmdq->copy_protection = (HDMI_RegisterRead(HDMIRX_R_ACS_CSts) & 0x04) >> 2;
- //HC Modify
- ACP_type = HDMI_RegisterRead(HDMIRX_R_ACP_Type);
- if((ACP_type == ACP_GENERIC_AUDIO) || (ACP_type == ACP_IEC60958_IDENTIFIED))
- {
- cmdq->copy_protection = 0; // ACP TYPE = 0 1, CP bit = 0, L bit =1
- cmdq->spdif_channel_status_category_code = cmdq->spdif_channel_status_category_code | 0x80;
- }
- //~HC
- switch (hp->TX_path)
- {
- case AUDIO_MENU_INTERNAL:
- case AUDIO_MENU_EXTERNAL:
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_I2S;
- break;
- case AUDIO_MENU_PARALLEL_SPDIF_LINEAR:
- case AUDIO_MENU_SPDIF_OUTPUT_PCM:
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_LINEAR;
- break;
- case AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR:
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_NONLINEAR;
- break;
- default:
- break;
- }
- if (HDMI_RegisterRead(HDMIRX_R_AV_Mute))
- {
- validFrame = FALSE;
- }
- if (validFrame)
- {
- if (bReset)
- {
- bReset = HDMI_AudioResetDecoder() ? FALSE : TRUE;
- }
- if (!bReset)
- {
- if (!hp->offset_flag)
- {
- hp->Freq = freq;
- AUDIO_setDelayTime(hp);
- hp->offset_flag = HDMI_AudioSetOffset(hp->audio_offset, hp->NLdelayCnt);
- }
- if (hp->offset_flag)
- {
- parsed_sz = 8;
- ptr = ddp + parsed_sz;
- for (; parsed_sz < ddpsz;
- parsed_sz += frmsz, ptr += ALIGN4(frmsz), cmdq->DataPtr += ALIGN4(frmsz))
- {
- frmsz = ddp_get_framesize(ptr);
- if (frmsz == 0)
- {
- break;
- }
- /* skip substream frame */
- if (ddp_substrm_frame(ptr))
- {
- continue;
- }
- /* Fire frame */
- HDMI_AudioSendCmdq(cmdq);
- }
- }
- }
- }
- else
- {
- bReset = TRUE;
- hp->offset_flag = FALSE;
- }
- }
- typedef enum
- {
- E_SPDIF_TYPE_UNKNOWN = 0,
- E_SPDIF_TYPE_DD,
- E_SPDIF_TYPE_DDP,
- E_SPDIF_TYPE_OTHERS,
- } E_SPDIF_TYPE;
- static E_SPDIF_TYPE check_spdif_type(UINT8 *inbuf, UINT32 inbufsz)
- {
- UINT32 i;
- UINT32 *in = (UINT32*)inbuf;
- for (i = 0; i < inbufsz / 4 - 1; i += 2)
- {
- if ((in[i] >> 16) == 0xf872 && (in[i + 1] >> 16) == 0x4e1f)
- {
- UINT8 t = (in[i + 2] >> 16) & 0x1f;
- if (t == 1)
- {
- return E_SPDIF_TYPE_DD;
- }
- else if (t == 21)
- {
- return E_SPDIF_TYPE_DDP;
- }
- else
- {
- return E_SPDIF_TYPE_OTHERS;
- }
- }
- }
- return E_SPDIF_TYPE_UNKNOWN;
- }
- void HDMI_Audio_BufferUpdated(void)
- {
- HDMI_PARSER_PTR hp = &g_hp;
- pAUDIO_CMDQ cmdq;
- WRITEBUF_DESC_PTR wbufdsc;
- UINT32 cur_wbuf;
- BOOL validData = false;
- UINT8 audio_type = (HDMI_RegisterRead(HDMIRX_R_ACS_CSts) & 0x2) >> 1;
- UINT32 pts_diff;
- static UINT8 ACP_type_pre = 0xFF;
- UINT8 ACP_type = 0;
- AUDIO_IEC61937_HEADER sp_header;
- UINT8* dataptr;
- HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Buffer_Change_Pulse); //clear
- if (!audio_active)
- {
- hdmidbg("%s:hdmi aud is not enable\n", __FUNCTION__);
- return;
- }
- cmdq = (pAUDIO_CMDQ)(&hp->cmdq);
- wbufdsc = (WRITEBUF_DESC_PTR)(hp->writeBufDsp + hp->wbuf_index * sizeof(WRITEBUF_DESC));
- cur_wbuf = wbufdsc->b1_sadd << 4;
- dataptr = (UINT8*)(cur_wbuf | 0xa0000000);
- sp_header.dw1 = getDW(dataptr);
- sp_header.dw2 = getDW(dataptr+4);
- if (hp->audio_type != audio_type)
- {
- if (sp_header.data_type == 21 ||hp->sp_non_linear_type == 21)
- {
- hdmidbg("%s:EAC3 skip aud type mismatch case (hp->data:%d, header->datatype=%d\n", __FUNCTION__, hp->sp_non_linear_type, sp_header.data_type);
- }
- else
- {
- hdmidbg("%s:aud type mismatch(ori:%d, hw_reg=%d\n", __FUNCTION__, hp->audio_type, audio_type);
- AUDIO_ResetLock();
- return;
- }
- }
- if (hp->path == HDMI_PATH_LINEAR)
- {
- if (wbufdsc->Buffer_Full && !wbufdsc->Discontinuous)
- {
- validData = true;
- cmdq->DataSize = hp->bufSize; // size of one write buffer group
- cmdq->DataPtr = cur_wbuf | 0xa0000000;
- cmdq->pause = wbufdsc->Pause_Exist;
- cmdq->discontinue = wbufdsc->Discontinuous;
- }
- }
- else if (hp->path == HDMI_PATH_PARSE)
- {
- //hdmidbg("%s:hp->data:%d, header->datatype=%d, b_dlth=%d, bufsze=%d\n", __FUNCTION__, hp->sp_non_linear_type, sp_header.data_type, wbufdsc->b_dlth ,hp->bufSize);
- if ((wbufdsc->b_dlth >= wbufdsc->b_th && !wbufdsc->Discontinuous) ||((wbufdsc->b_dlth == 0) &&(sp_header.data_type == 21 ||hp->sp_non_linear_type == 21)))
- //if(wbufdsc->b_dlth >= wbufdsc->b_th && !wbufdsc->Discontinuous)
- {
- validData = true;
- if (HDMI_RegisterRead(HDMIRX_R_parsing_en))
- {
- if (hp->sp_non_linear_type != sp_header.data_type)
- {
- bReset = true;
- hp->offset_flag = false;
- hp->bSupportNotice = false;
- }
- hp->sp_non_linear_type = sp_header.data_type;
-
- if(hp->sp_non_linear_type == 21)
- {
- HDMI_RegisterWrite(HDMIRX_R_parsing_en, 0);
- HDMI_RegisterWrite(HDMIRX_R_byte_swap, 0);
- hdmi_spdif_parser_init(
- hp->writeBuf + NonLinear_Parse_Buffer_Number * PARSE_BUFFER_SIZE,
- ddp_receive_frames, hp);
- validData = false;
- }
- }
- else
- {
- UINT32 pts;
- validData = false;
- hp->sp_non_linear_type = 21;
- pts = (wbufdsc->PTS_high << 31) | (wbufdsc->PTS >> 1);
- hdmi_spdif_parser_handler(dataptr, hp->bufSize, pts);
- }
- switch (hp->sp_non_linear_type)
- {
- case 4:
- hp->sample_number = 384;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 5:
- hp->sample_number = 1152;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 6:
- hp->sample_number = 1152;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 8:
- hp->sample_number = 768;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 9:
- hp->sample_number = 2304;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 10:
- hp->sample_number = 1152;
- cmdq->inDataType = AUDIO_DATA_TYPE_MPEG;
- break;
- case 1:
- hp->sample_number = 1536;
- cmdq->inDataType = AUDIO_DATA_TYPE_AC3;
- break;
- case 21: //EAC3
- hp->sample_number = 1536;
- cmdq->inDataType = AUDIO_DATA_TYPE_EAC3;
- break;
- case 11: //DTS type I
- hp->sample_number = 512;
- cmdq->inDataType = AUDIO_DATA_TYPE_DTS; //Currenttly unspported audio type
- break;
- case 12: //DTS type II
- hp->sample_number = 1024;
- cmdq->inDataType = AUDIO_DATA_TYPE_DTS;
- break;
- case 13: //DTS type III
- hp->sample_number = 2048;
- cmdq->inDataType = AUDIO_DATA_TYPE_DTS;
- break;
- case 7: //MPEG-2 AAC
- hp->sample_number = 1024;
- cmdq->inDataType = AUDIO_DATA_TYPE_UNKNOW;
- break;
- case 14: //ATRAC
- hp->sample_number = 512;
- cmdq->inDataType = AUDIO_DATA_TYPE_UNKNOW;
- break;
- case 15: //ATRAC 2/3
- hp->sample_number = 1024;
- cmdq->inDataType = AUDIO_DATA_TYPE_UNKNOW;
- break;
- default:
- cmdq->inDataType = AUDIO_DATA_TYPE_UNKNOW;
- hp->sample_number = 1536;
- break;
- }
- cmdq->DataSize = hp->sample_number;
- cmdq->DataPtr = cur_wbuf | 0xa0000000;
- cmdq->pause = wbufdsc->Pause_Exist;
- cmdq->discontinue = wbufdsc->Discontinuous;
- cmdq->sp_non_linear_type = hp->sp_non_linear_type;
- if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR ||
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM)
- {
- INT32 framesize = ((*(((UINT8*)cmdq->DataPtr) + 6)) << 8 |
- *(((UINT8*)cmdq->DataPtr) + 7));
- cmdq->flag = AUDIO_FLAG_DECODING;
- cmdq->outDataType = AUDIO_DATA_TYPE_PCM;
- /* Only clear zero stuffing when input type is not EAC3. */
- if(hp->sp_non_linear_type != 21)
- {
- framesize /= 8;
- cmdq->NLsize = ((8 + framesize + 15) & ~15) >> 4;
- memset(((UINT8*)cmdq->DataPtr) + 8 + framesize,
- 0x0, cmdq->NLsize * 16 - framesize - 8);
- }
- if (cmdq->inDataType == AUDIO_DATA_TYPE_AC3 ||
- cmdq->inDataType == AUDIO_DATA_TYPE_EAC3)
- {
- if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM)
- {
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_LINEAR;
- }
- else
- {
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_NONLINEAR;
- }
- }
- else if (cmdq->inDataType == AUDIO_DATA_TYPE_MPEG)
- {
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_LINEAR;
- }
- else if (cmdq->inDataType == AUDIO_DATA_TYPE_DTS)
- {
- cmdq->TxType = AUDIO_TX_TYPE_I2S_AND_SPDIF_NONLINEAR;
- cmdq->NLsize = ((8 + framesize + 15) & ~15);//use NLsize send DTS framesize
- }
- else //if(cmdq->inDataType == AUDIO_DATA_TYPE_UNKNOW)
- {
- if (hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR)
- {
- cmdq->flag = AUDIO_FLAG_REPACKAGE;
- cmdq->outDataType = AUDIO_DATA_TYPE_UNKNOW;
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_SPDIF;
- cmdq->DataSize = (8 + framesize + 15)&~15; // size is 16 bytes aligned.
- cmdq->ZeroStuffLen = (4 * hp->sample_number - cmdq->DataSize) / 16 - 1;
- }
- }
- }
- else// if(cmdq->TxType==AUDIO_TX_TYPE_ONLY_I2S)
- {
- cmdq->NLsize = 0;
- }
- }
- }
- else if (hp->path == HDMI_PATH_BYPASS)
- {
- if (wbufdsc->Buffer_Full && !wbufdsc->Discontinuous)
- {
- validData = true;
- cmdq->DataSize = hp->bufSize;
- cmdq->DataPtr = cur_wbuf | 0xa0000000;
- cmdq->pause = wbufdsc->Pause_Exist;
- cmdq->discontinue = wbufdsc->Discontinuous;
- }
- }
- if (validData && (wbufdsc->PTS == 0 && wbufdsc->PTS_high == 0))
- {
- hdmidbg("%s: PTS is not normal. Skip the buffer\n", __FUNCTION__);
- validData = false;
- }
- pts_diff = ((wbufdsc->PTS_high << 31) | (wbufdsc->PTS >> 1)) - hp->pPts;
- if (validData && !pts_diff)
- {
- hdmidbg("%s: PTS is decreasing. Skip the buffer\n", __FUNCTION__);
- validData = false;
- }
- if (validData && hp->pPts)
- {
- if (verifyFreq(hp, pts_diff) == false)
- {
- hdmidbg("%s: Change audio freq to %d\n", __FUNCTION__, hp->Freq);
- #define Max_Reset_Count 100
- if ((hp->path == HDMI_PATH_PARSE) && (Reset_Count < Max_Reset_Count) &&
- (cmdq->inDataType == AUDIO_DATA_TYPE_UNKNOW))
- {
- DRV_HDMI_AudioDisable();
- }
- cmdq->sfreq = AUDIO_freq(hp->Freq);
- AUDIO_setDelayTime(hp);
- if (hp->offset_flag)
- {
- bReset = true;
- hp->offset_flag = false;
- }
- if(HDMI_RegisterRead(HDMIRX_R_audio_enable) == 0)
- {
- DRV_HDMI_AudioEnable();
- Reset_Count++;
- hdmidbg("AUDIO_bufChange:Reset_Count=%d\n", Reset_Count);
- }
- #define HDMI_RELOCK_TIMEBOUND 0xa
- if (hp->relock_count++ > HDMI_RELOCK_TIMEBOUND)
- {
- AUDIO_ResetLock();
- return;
- }
- }
- else
- {
- if (hp->Freq == 1)
- {
- hdmidbg("Freq is abnormal!!\n");
- validData = false;
- }
- if ((hp->path == HDMI_PATH_PARSE) && (cmdq->inDataType == AUDIO_DATA_TYPE_UNKNOW))
- {
- Reset_Count = 0;
- }
- }
- }
- else
- {
- validData = false;
- }
- cmdq->spdif_channel_status_category_code = HDMI_RegisterRead(HDMIRX_R_ACS_CatC);
- cmdq->copy_protection = (HDMI_RegisterRead(HDMIRX_R_ACS_CSts) & 0x04) >> 2;
- cmdq->PTS = wbufdsc->PTS;
- cmdq->PTS_High = wbufdsc->PTS_high;
- hp->pPts = (wbufdsc->PTS_high << 31) | (wbufdsc->PTS >> 1);
- /* Check IEC61937 header in parse mode */
- if (validData && hp->path == HDMI_PATH_PARSE)
- {
- if (cmdq->inDataType == AUDIO_DATA_TYPE_AC3)
- {
- AUDIO_AC3HEADERDATA ac3_header;
- ac3_header.dw1 = getDW(((UINT8*)cmdq->DataPtr) + 8);
- ac3_header.dw2 = getDW(((UINT8*)cmdq->DataPtr) + 12);
- if (ac3_header.syncword != 0x0b77)
- {
- validData = false;
- }
- else
- {
- if (hp->codingMode != ac3_header.acmod)
- {
- bReset = true;
- hp->offset_flag = false;
- hp->codingMode = ac3_header.acmod;
- }
- else
- {
- hp->codingMode = ac3_header.acmod;
- hp->bDualChannel = (hp->codingMode == 0);
- }
- }
- }
- else if (cmdq->inDataType == AUDIO_DATA_TYPE_MPEG)
- {
- AUDIO_MPEGHEADERDATA mpeg_header;
- mpeg_header.dw = getDW(((UINT8*)cmdq->DataPtr) + 8);
- if ((mpeg_header.dw & 0xfff40000) != 0xfff40000)
- {
- validData = false;
- }
- else
- {
- UINT8 codMode = ((mpeg_header.mode == 2) ? 0 : ((mpeg_header.mode == 3) ? 1 : 2));
- if (hp->codingMode != codMode)
- {
- bReset = true;
- hp->offset_flag = false;
- hp->codingMode = codMode;
- }
- else
- {
- hp->codingMode = codMode;
- hp->bDualChannel = (hp->codingMode == 0);
- }
- }
- }
- else if (cmdq->inDataType == AUDIO_DATA_TYPE_DTS)
- {
- validData = true;//jsut not make valiData false;
- }
- else
- {
- if (cmdq->flag == AUDIO_FLAG_DECODING)
- {
- validData = false;
- }
- }
- }
- else if (validData && hp->path == HDMI_PATH_LINEAR)
- {
- UINT8 chcount = HDMI_RegisterRead(HDMIRX_R_Ado_CC) & 0x7;
- UINT8 spkplace = HDMI_RegisterRead(HDMIRX_R_Ado_CA) & 0x1f;
- #if 0//CONFIG_HDMI_Support_MULTI_PCM
- UINT8 cur_chcnt = getChannelCount(spkplace, chcount);
- UINT8 old_chcnt = getChannelCount(hp->spkplace, hp->chcount);
- if (old_chcnt != cur_chcnt)
- {
- hp->chcount = chcount;
- hp->spkplace = spkplace;
- bReset = true;
- hp->offset_flag = false;
- cmdq->spkplace = getSpeakerPlacement(spkplace);
- cmdq->chcnt = cur_chcnt;
- }
- #else
- /* Patch: Only stereo pcm input is allowed. */
- if (getChannelCount(spkplace, chcount))
- {
- //validData = false;
- }
- #endif
- }
- else if (validData && hp->path == HDMI_PATH_BYPASS)
- {
- if (hp->audio_stream_type == 0)
- {
- hp->audio_stream_type = check_spdif_type((UINT8*)(cur_wbuf | 0xa0000000), hp->bufSize);
- //hdmidbg("check_spdif_type %d\n",hp->audio_stream_type);
- switch (hp->audio_stream_type)
- {
- case E_SPDIF_TYPE_UNKNOWN:
- validData = FALSE;
- break;
- case E_SPDIF_TYPE_DDP:
- cmdq->inDataType = cmdq->outDataType = AUDIO_DATA_TYPE_EAC3;
- break;
- case E_SPDIF_TYPE_DD:
- case E_SPDIF_TYPE_OTHERS:
- default:
- break;
- }
- }
- }
- ACP_type = HDMI_RegisterRead(HDMIRX_R_ACP_Type);
- /* HDMI Source SPDIF OUT fix at SPDIF_WORD_LENGTH_16_BITS */
- //cmdq->sample_bit = 0x2;// SPDIF_WORD_LENGTH_16_BITS = 0x2,
- //HC Modify
- if((ACP_type == ACP_GENERIC_AUDIO) || (ACP_type == ACP_IEC60958_IDENTIFIED))
- {
- cmdq->copy_protection = 0; // ACP TYPE = 0 1, CP bit = 0, L bit =1
- cmdq->spdif_channel_status_category_code = cmdq->spdif_channel_status_category_code | 0x80;
- }
- //~HC
-
- if (ACP_type_pre != ACP_type)
- {
- HDMI_NoticeAudioACP(HDMI_RegisterRead(HDMIRX_R_ACP_Type));
- ACP_type_pre = ACP_type;
- }
- /* Check ACP Type */
- if ((HDMI_RegisterRead(HDMIRX_R_ACP_Type) != ACP_GENERIC_AUDIO &&
- HDMI_RegisterRead(HDMIRX_R_ACP_Type) != ACP_IEC60958_IDENTIFIED) &&
- (hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT ||
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR ||
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_LINEAR ||hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT_PCM))
- {
- if (hp->TX_path == AUDIO_MENU_SPDIF_OUTPUT)
- {
- validData = false;
- }
- else
- {
- /* Change audio path: parallel linear/non-linear --> Internal speaker */
- hp->TX_path = AUDIO_MENU_INTERNAL;
- cmdq->TxType = AUDIO_TX_TYPE_ONLY_I2S;
- }
- }
- /* Notice Flow control if we support the audio type */
- if (!hp->bSupportNotice)
- {
- // BOOL bSupported = (cmdq->inDataType != AUDIO_DATA_TYPE_UNKNOW);
- /* DTS is supported when SDPIF Out is enable */
- /* if (!bSupported &&
- cmdq->inDataType == AUDIO_DATA_TYPE_DTS &&
- hp->TX_path == AUDIO_MENU_PARALLEL_SPDIF_NONLINEAR)
- {
- bSupported = 1;
- }
- */
- // HDMI_NoticeAudioTypeSupport(bSupported);
- hp->bSupportNotice = true;
- }
- /* Audio Mute when current control packet contains av mute flag */
- if (HDMI_RegisterRead(HDMIRX_R_AV_Mute))
- {
- validData = false;
- }
- if (validData)
- {
- if (bReset)
- {
- bReset = HDMI_AudioResetDecoder() ? false : true;
- }
- if (!bReset)
- {
- if (!hp->offset_flag)
- {
- hp->offset_flag = HDMI_AudioSetOffset(hp->audio_offset, hp->NLdelayCnt);
- }
- if (hp->offset_flag)
- {
- HDMI_AudioSendCmdq(cmdq);
- }
- }
- }
- else
- {
- /* Software parsing EAC3 frames, don't reset. */
- if (hp->offset_flag && hp->sp_non_linear_type != 21)
- {
- bReset = true;
- hp->offset_flag = false;
- }
- }
- hp->wbuf_index = (hp->wbuf_index + 1) % hp->writeBufNum;
- wbufdsc->b_size = hp->bufSize >> 4;
-
- //wbufdsc->Buffer_Valid=0;
- //wbufdsc->Discontinuous=0;
- //wbufdsc->Pause_Exist=0;
- //wbufdsc->Buffer_Full=0;
- //wbufdsc->b_dlth=0;
- //wbufdsc->PTS=0;
- //wbufdsc->PTS_high=0;
- }
|