123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386 |
- #include "drv_types.h"
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/device.h>
- #include <linux/signal.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/interrupt.h>
- #include <linux/mm.h>
- #include <linux/vmalloc.h> // drv_vmalloc() drv_vfree()
- #include <linux/version.h>
- #include <drv_devices.h>
- #include <drv_cec_internal.h>
- #include <drv_cec_external.h>
- #include "cec.h"
- #include "sysreg.h"
- #include "hdmi_cfg.h"
- #include "hdmi.h"
- #include "hdmi_hw.h"
- #include "hdmi_mapping.h"
- #include "hdmi_hpd.h"
- #include "hdmi_dbg.h"
- #include "debounce.h"
- #include "hdmi_processing.h"
- #include "hdmi_time.h"
- #include "drv_gpio.h"
- #define CDEV_CEC_MAJOR CEC_DEV_MAJOR
- #define CECSTATE_ADDR 0xbe0f0510
- static INT32 cecd_pid = -1;
- static struct work_struct wq_cec_signal;
- static pCEC_MSG_t pMsg = NULL;
- #ifdef HDMI_DDC5V_WORKAROUND
- static DEBOUNCE PortA_5V_debounce;
- static DEBOUNCE PortB_5V_debounce;
- static DEBOUNCE PortC_5V_debounce;
- static DRV_5V_LEVEL_e ePortA_SW_5V = DRV_5V_LEVEL_LOW, ePortB_SW_5V = DRV_5V_LEVEL_LOW, ePortC_SW_5V = DRV_5V_LEVEL_LOW;
- static DEBOUNCE PortA_HPD_debounce;
- static DEBOUNCE PortB_HPD_debounce;
- static DEBOUNCE PortC_HPD_debounce;
- #else
- static DEBOUNCE Src_5V_debounce;
- #endif
- //for ARC 5V GPIO
- GPIOPin_t geGpio5V_Pin = GPIO_NOT_USE;
- HDMI_PORT_T geARCPort = HDMI_PORT_NULL;
- static DEBOUNCE ArcGpio_5V_debounce;
- static UINT8 BootUpByOneTouchPlay = 0;
- static UINT8 BootUpLog = 0x0;
- //static struct work_struct wq_SetHPD_A_TOGGLE;
- //static struct work_struct wq_SetHPD_B_TOGGLE;
- //static struct work_struct wq_SetHPD_C_TOGGLE;
- void SetHPD_A_TOGGLE(void)
- {
- hdmi_apply_hpd(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW);
- /* Wait HDMI_HPD_L2H_DELAY ms for hot plug pulse width */
- HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
- hdmi_apply_hpd(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH);
- }
- void SetHPD_B_TOGGLE(void)
- {
- hdmi_apply_hpd(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW);
- /* Wait HDMI_HPD_L2H_DELAY ms for hot plug pulse width */
- HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
- hdmi_apply_hpd(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH);
- }
- void SetHPD_C_TOGGLE(void)
- {
- hdmi_apply_hpd(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_LOW);
- /* Wait HDMI_HPD_L2H_DELAY ms for hot plug pulse width */
- HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
- hdmi_apply_hpd(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_HIGH);
- }
- #ifdef INIT_BY_KMF
- static void TxFIFO_handler(pCEC_MSG_t pm);
- static INT32 QueryLink(UINT32 pAddr)
- {
- return (pAddr & 0xf000) >> 12;
- }
- static UINT32 query_physical_address(UINT8 logAddr)
- {
- UINT32 paddr = 0;
- INT32 timeout = 20, count;
- UINT8 cec_interrupt_flag = false;
- pFRAME_t m = &(pMsg->txMsg);
- m->block_num = 2;
- m->src = 0x0;
- m->dst = logAddr;
- m->opcode = 0x83;
- TxFIFO_handler(pMsg);
- HDMI_DelayMs(55);
- for (; timeout > 0; timeout--)
- {
- if (m->status == CEC_STATUS_TXNOACK)
- {
- cecdbg("CEC_STATUS_TXNOACK\n");
- return 0;
- }
- if (m->status == CEC_STATUS_TXEOMDONE)
- {
- cecdbg("CEC_STATUS_TXEOMDONE\n");
- break;
- }
- HDMI_DelayMs(25);
- }
- timeout = 30;
- for(;;)
- {
- HDMI_DelayMs(100);
- //cecdbg("HDMI_RegisterRead(CEC_rxData_EOM) = %d, (pMsg->bMsg = %d) , (timeout = %d) , (pMsg->bMessageDone = %d)",HDMI_RegisterRead(CEC_rxData_EOM), (pMsg->bMsg) , (timeout) , (pMsg->bMessageDone));
- if(pMsg->bMessageDone == true)
- {
- break;
- }
- if((timeout--) <= 0)
- {
- break;
- }
- }
- cecdbg("timeout = %d\n",timeout);
- for(timeout = 0;timeout<20 && (cec_interrupt_flag == false);timeout++)
- {
- pFRAME_t f;
- INT32 i = pMsg->Rp;
- count = pMsg->Wp;
- for (; i != count ; i = (i + 1) % FRAMEMAX)
- {
- f = &pMsg->rxMsg[i];
- if (f->opcode == 0x84 && f->src == logAddr && f->block_num == 5)
- {
- cec_interrupt_flag = true;
- paddr = ((f->param[0] << 8) | f->param[1]);
- break;
- }
- }
- HDMI_DelayMs(50);
- }
- return paddr;
- }
- /* return hdmi link no to umf: 1-hdmi1, 2-hdmi2 */
- INT32 CEC_Query(UINT8 logAddr)
- {
- INT32 ret;
- BootUpLog = logAddr;
- ret = QueryLink(query_physical_address(logAddr));
- cecdbg("%s: logAddr 0x%x in hdmi %d\n", __FUNCTION__, logAddr, ret);
- if(ret != 0) BootUpByOneTouchPlay = 1;
- return ret;
- }
- UINT8 CEC_BootUpByOneTouchPlay( )
- {
- UINT8 ret=0;
- if(BootUpByOneTouchPlay == 1)
- {
- ret = 1;
- BootUpByOneTouchPlay = 0;
- }
- return ret;
- }
- #endif
- #ifdef HDMI_DDC5V_WORKAROUND
- static void Check_PortA_5V_change(void *data)
- {
- UINT32 fIs_5V_Changed = FALSE;
- //DRV_5V_LEVEL_e ePortA_5V_Level = *((DRV_5V_LEVEL_e*)data);
- DRV_5V_LEVEL_e ePortA_5V_Level = (DRV_5V_LEVEL_e)data;
-
- //UINT8 fInRange = HDMI_RegisterRead(HDMIRX_IN_RANGE);
- if(ePortA_5V_Level == DRV_5V_LEVEL_HIGH)
- {
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- #ifdef CONFIG_HDMI_MHL_PORT
- if(CONFIG_HDMI_MHL_PORT==HDMI_PORT_A)
- {
- int i;
- for( i=0 ; i<5 ; i++ )
- {
- if(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)
- {
- cecdbg("A in MHL mode ignore set hpd %d \n",i);
- return;
- }
- }
-
- }
- #endif
- #endif
- if(ePortA_SW_5V == DRV_5V_LEVEL_LOW)
- {
- cecdbg("A in\n");
- fIs_5V_Changed = TRUE;
- ePortA_SW_5V = DRV_5V_LEVEL_HIGH;
- //if(hdmi_get_cur_port() == HDMI_PORT_A)
- // hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH);
- #ifdef CONFIG_CHANGE_HOT_PLUG_ACTION
- #if (defined CONFIG_SUPPORT_CEC_TV) || (defined HDMI_SET_HPD_AT_ALL_SOURCE)
- if(1)
- #else
- if(hdmi_get_cur_port() == HDMI_PORT_A)
- #endif
- #endif
- {
- #if (defined CONFIG_HDMI_PORT_A_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_A))
- debounce_notice(&PortA_HPD_debounce, (void *)(fIs_5V_Changed), 300);
- #else
- hdmi_apply_hpd(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH);
- #endif
- }
- }
- //turn on SW 5V prevent HDMI auto reset when DDC 5V low
- if(hdmi_get_cur_port() == HDMI_PORT_A)
- sysset_HDMI_SW5V(HDMI_PORT_A, TRUE);
- }
- else if(ePortA_5V_Level == DRV_5V_LEVEL_LOW && ePortA_SW_5V == DRV_5V_LEVEL_HIGH)
- {
- if((hdmi_get_cur_port() == HDMI_PORT_A) && (hdmi_flag_check(HAS_ACTIVE_DATA)))
- {
- return;
- }
- else
- {
- cecdbg("A out\n");
- fIs_5V_Changed = TRUE;
- ePortA_SW_5V = DRV_5V_LEVEL_LOW;
- #if (defined CONFIG_HDMI_PORT_A_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_A))
- debounce_exit(&PortA_HPD_debounce);
- #endif
- hdmi_apply_hpd(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW);
- }
- }
- if( fIs_5V_Changed == TRUE)
- {
- #ifdef CONFIG_SUPPORT_HDMI_PLUGIN_CHANGE_SOURCE
- if (ePortA_SW_5V == DRV_5V_LEVEL_HIGH)
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_A);
- else
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_NUM);
- #endif
- #if (defined CONFIG_HDMI_PORT_A_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_A))
- if(ePortA_SW_5V == DRV_5V_LEVEL_LOW)
- #endif
- {
- hdmi_hpd_update();
- }
- }
- }
- static void Check_PortB_5V_change(void *data)
- {
- UINT32 fIs_5V_Changed = FALSE;
- //DRV_5V_LEVEL_e ePortB_5V_Level = *((DRV_5V_LEVEL_e*)data);
- DRV_5V_LEVEL_e ePortB_5V_Level = (DRV_5V_LEVEL_e)data;
-
- //UINT8 fInRange = HDMI_RegisterRead(HDMIRX_IN_RANGE);
- if(ePortB_5V_Level == DRV_5V_LEVEL_HIGH)
- {
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- #ifdef CONFIG_HDMI_MHL_PORT
- if(CONFIG_HDMI_MHL_PORT==HDMI_PORT_B)
- {
- int i;
- for( i=0 ; i<5 ; i++ )
- {
- if(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)
- {
- cecdbg("B in MHL mode ignore set hpd %d \n",i);
- return;
- }
- }
-
- }
- #endif
- #endif
- if(ePortB_SW_5V == DRV_5V_LEVEL_LOW)
- {
- cecdbg("B in\n");
- fIs_5V_Changed = TRUE;
- ePortB_SW_5V = DRV_5V_LEVEL_HIGH;
- //if(hdmi_get_cur_port() == HDMI_PORT_B)
- // hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH);
- #ifdef CONFIG_CHANGE_HOT_PLUG_ACTION
- #if (defined CONFIG_SUPPORT_CEC_TV) || (defined HDMI_SET_HPD_AT_ALL_SOURCE)
- if(1)
- #else
- if(hdmi_get_cur_port() == HDMI_PORT_B)
- #endif
- #endif
- {
- #if (defined CONFIG_HDMI_PORT_B_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_B))
- debounce_notice(&PortB_HPD_debounce, (void *)(fIs_5V_Changed), 300);
- #else
- hdmi_apply_hpd(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH);
- #endif
- }
- }
- //turn on SW 5V prevent HDMI auto reset when DDC 5V low
- if(hdmi_get_cur_port() == HDMI_PORT_B)
- sysset_HDMI_SW5V(HDMI_PORT_B, TRUE);
- }
- else if(ePortB_5V_Level == DRV_5V_LEVEL_LOW && ePortB_SW_5V == DRV_5V_LEVEL_HIGH)
- {
- if((hdmi_get_cur_port() == HDMI_PORT_B) && (hdmi_flag_check(HAS_ACTIVE_DATA)))
- {
- return;
- }
- else
- {
- cecdbg("B out\n");
- fIs_5V_Changed = TRUE;
- ePortB_SW_5V = DRV_5V_LEVEL_LOW;
- #if (defined CONFIG_HDMI_PORT_B_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_B))
- debounce_exit(&PortB_HPD_debounce);
- #endif
- hdmi_apply_hpd(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW);
- }
- }
- if( fIs_5V_Changed == TRUE)
- {
- #ifdef CONFIG_SUPPORT_HDMI_PLUGIN_CHANGE_SOURCE
- if (ePortB_SW_5V == DRV_5V_LEVEL_HIGH)
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_B);
- else
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_NUM);
- #endif
- #if (defined CONFIG_HDMI_PORT_B_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_B))
- if(ePortB_SW_5V == DRV_5V_LEVEL_LOW)
- #endif
- {
- hdmi_hpd_update();
- }
- }
- }
- static void Check_PortC_5V_change(void *data)
- {
- UINT32 fIs_5V_Changed = FALSE;
- //DRV_5V_LEVEL_e ePortC_5V_Level = *((DRV_5V_LEVEL_e*)data);
- DRV_5V_LEVEL_e ePortC_5V_Level = (DRV_5V_LEVEL_e)data;
- //UINT8 fInRange = HDMI_RegisterRead(HDMIRX_IN_RANGE);
- if(ePortC_5V_Level == DRV_5V_LEVEL_HIGH)
- {
- if(ePortC_SW_5V == DRV_5V_LEVEL_LOW)
- {
- cecdbg("C in\n");
- fIs_5V_Changed = TRUE;
- ePortC_SW_5V = DRV_5V_LEVEL_HIGH;
- //if(hdmi_get_cur_port() == HDMI_PORT_C)
- // hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_HIGH);
- #ifdef CONFIG_CHANGE_HOT_PLUG_ACTION
- #if (defined CONFIG_SUPPORT_CEC_TV) || (defined HDMI_SET_HPD_AT_ALL_SOURCE)
- if(1)
- #else
- if(hdmi_get_cur_port() == HDMI_PORT_C)
- #endif
- #endif
- {
- #if (defined CONFIG_HDMI_PORT_C_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_C))
- debounce_notice(&PortC_HPD_debounce, (void *)(fIs_5V_Changed), 300);
- #else
- hdmi_apply_hpd(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_HIGH);
- #endif
- }
- }
- //turn on SW 5V prevent HDMI auto reset when DDC 5V low
- if(hdmi_get_cur_port() == HDMI_PORT_C)
- sysset_HDMI_SW5V(HDMI_PORT_C, TRUE);
- }
- else if(ePortC_5V_Level == DRV_5V_LEVEL_LOW && ePortC_SW_5V == DRV_5V_LEVEL_HIGH)
- {
- if((hdmi_get_cur_port() == HDMI_PORT_C) && (hdmi_flag_check(HAS_ACTIVE_DATA)))
- {
- return;
- }
- else
- {
- cecdbg("C out\n");
- fIs_5V_Changed = TRUE;
- ePortC_SW_5V = DRV_5V_LEVEL_LOW;
- #if (defined CONFIG_HDMI_PORT_C_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_C))
- debounce_exit(&PortC_HPD_debounce);
- #endif
- hdmi_apply_hpd(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_LOW);
- }
- }
- if( fIs_5V_Changed == TRUE)
- {
- #ifdef CONFIG_SUPPORT_HDMI_PLUGIN_CHANGE_SOURCE
- if (ePortC_SW_5V == DRV_5V_LEVEL_HIGH)
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_C);
- else
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_NUM);
- #endif
- #if (defined CONFIG_HDMI_PORT_C_HAVE_EXT_1K) && (!defined(CONFIG_HDMI_GPIO_DETECT_PORT_C))
- if(ePortC_SW_5V == DRV_5V_LEVEL_LOW)
- #endif
- {
- hdmi_hpd_update();
- }
- }
- }
- DRV_5V_LEVEL_e CEC_Get_SW5V(HDMI_PORT_T ePort)
- {
- DRV_5V_LEVEL_e eLevel;
- switch(ePort)
- {
- case HDMI_PORT_A:
- eLevel = ePortA_SW_5V;
- break;
- case HDMI_PORT_B:
- eLevel = ePortB_SW_5V;
- break;
- case HDMI_PORT_C:
- eLevel = ePortC_SW_5V;
- break;
- default:
- eLevel = DRV_5V_LEVEL_LOW;
- break;
- }
- return eLevel;
- }
- static void Set_PortA_HPD_Timer_Fn(void *data)
- {
- DRV_5V_LEVEL_e ePort_5V_Level = CEC_Get_SW5V(HDMI_PORT_A);
- UINT32 fIs_5V_Changed = (UINT32)data;
- hdmi_apply_hpd(DRV_HDMI_PORT_A, (ePort_5V_Level == DRV_5V_LEVEL_HIGH) ? DRV_HPD_LEVEL_HIGH:DRV_HPD_LEVEL_LOW);
- if(fIs_5V_Changed == TRUE)
- {
- hdmi_hpd_update();
- }
- }
- static void Set_PortB_HPD_Timer_Fn(void *data)
- {
- DRV_5V_LEVEL_e ePort_5V_Level = CEC_Get_SW5V(HDMI_PORT_B);
- UINT32 fIs_5V_Changed = (UINT32)data;
- hdmi_apply_hpd(DRV_HDMI_PORT_B, (ePort_5V_Level == DRV_5V_LEVEL_HIGH) ? DRV_HPD_LEVEL_HIGH:DRV_HPD_LEVEL_LOW);
- if(fIs_5V_Changed == TRUE)
- {
- hdmi_hpd_update();
- }
- }
- static void Set_PortC_HPD_Timer_Fn(void *data)
- {
- DRV_5V_LEVEL_e ePort_5V_Level = CEC_Get_SW5V(HDMI_PORT_C);
- UINT32 fIs_5V_Changed = (UINT32)data;
- hdmi_apply_hpd(DRV_HDMI_PORT_C, (ePort_5V_Level == DRV_5V_LEVEL_HIGH) ? DRV_HPD_LEVEL_HIGH:DRV_HPD_LEVEL_LOW);
- if(fIs_5V_Changed == TRUE)
- {
- hdmi_hpd_update();
- }
- }
- #else
- static void CheckSrc5V_change(void *dummy)
- {
- hdmi_hpd_update();
- }
- #endif
- static void CEC_parser_wq(void *dummy)
- {
- struct task_struct *p;
- p = find_task_by_vpid(cecd_pid);
- if (p)
- {
- send_sig_info(CEC_SIG, (void*)1, p);
- }
- }
- static void CEC_parser(void)
- {
- schedule_work(&wq_cec_signal);
- }
- static void RxFIFO_handler(pCEC_MSG_t pm)
- {
- if (!pm->rxFifo_cnt)
- {
- return;
- }
- HDMI_RegisterWrite(CEC_Rx_FIFO_POP, 0);
- pm->rxFifo_cnt--;
- if (HDMI_RegisterRead(CEC_rxData_sbit))
- {
- pm->rxBlock_ptr = 0;
- pm->rxMsg[pm->Wp].block_num = 0;
- pm->bMsg = true;
- }
- if (pm->bMsg)
- {
- pm->rxMsg[pm->Wp].block[pm->rxBlock_ptr] = HDMI_RegisterRead(CEC_rxData);
- //hdmidbg("\trxMsg[%d].block[%d]=0x%02x\tA%dE%d\n",pm->Wp,pm->rxBlock_ptr,HDMI_RegisterRead(CEC_rxData), HDMI_RegisterRead(CEC_rxData_ACK), HDMI_RegisterRead(CEC_rxData_EOM));
- if (pm->rxBlock_ptr < 17)
- {
- pm->rxBlock_ptr++;
- }
- }
- if (HDMI_RegisterRead(CEC_rxData_EOM) && pm->bMsg)
- {
- #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE
- INT32 c,n;
- INT8 str[40];
- #endif
- pm->rxMsg[pm->Wp].block_num = pm->rxBlock_ptr;
- pm->rxBlock_ptr = 0;
- pm->rxFifo_cnt = 0;
- pm->bMsg = false;
-
- #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE
- //print recieved CEC message
- for(c=0,n=0;c<pm->rxMsg[pm->Wp].block_num;c++)
- {
- if (n >= 0)
- {
- n += sprintf(&str[n], "%02x%s", pm->rxMsg[pm->Wp].block[c], c != (pm->rxMsg[pm->Wp].block_num - 1) ? "" : "\n");
- }
- }
- cecdbg("Msg recv %s",str);
- #endif
- pm->Wp = (pm->Wp + 1) % FRAMEMAX;
- if (pm->Wp == pm->Rp)
- {
- pm->bOverwrite = true;
- }
- pm->bMessageDone = true;
- CEC_parser();
- }
- HDMI_RegisterWrite(CEC_Rx_FIFO_POP, 1);
- }
- static void TxFIFO_handler(pCEC_MSG_t pm)
- {
- pFRAME_t ptxMsg = &(pm->txMsg);
- INT32 i = 0;
- #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE
- INT32 c,n;
- INT8 str[40];
- #endif
- if (ptxMsg->status == CEC_STATUS_TXSENDING)
- {
- return;
- }
- if (ptxMsg->block_num <= 0)
- {
- return;
- }
- ptxMsg->status = CEC_STATUS_TXSENDING;
- HDMI_RegisterWrite(CEC_HEADER_follower, ptxMsg->block[0] & 0xf);
- HDMI_RegisterWrite(CEC_HEADER_initiator, ptxMsg->block[0] >> 4);
- for (i = 1; i < ptxMsg->block_num; i++)
- {
- HDMI_RegisterWrite(CEC_DataBlock00 + (i - 1), ptxMsg->block[i]);
- }
- #ifdef CONFIG_SUPPORT_DEBUG_MESSAGE
- //print send CEC message
- for(c=0,n=0;c<ptxMsg->block_num;c++)
- {
- if (n >= 0)
- {
- n += sprintf(&str[n], "%02x%s", ptxMsg->block[c], c != (ptxMsg->block_num - 1) ? "" : "\n");
- }
- }
- cecdbg("Msg sent: %s",str);
- #endif
-
- if (ptxMsg->block_num > 1)
- {
- HDMI_RegisterWrite(CEC_Header_EOM, 0);
- HDMI_RegisterWrite(CEC_Block_XX_EOM, ptxMsg->block_num - 2);
- HDMI_RegisterWrite(CEC_R_retry_th, 3);
- }
- else
- {
- HDMI_RegisterWrite(CEC_Header_EOM, 1);
- HDMI_RegisterWrite(CEC_Block_XX_EOM, 0);
- HDMI_RegisterWrite(CEC_R_retry_th, 1);
- }
- HDMI_RegisterWrite(CEC_TransmissionStart, 0);
- HDMI_RegisterWrite(CEC_TransmissionStart, 1);
- }
- #ifdef CONFIG_DEBUG_DRV_CEC_WRITE_EN
- static UINT8 char2Hex(INT8 ch)
- {
- if (ch >= '0' && ch <= '9')
- {
- return ch - '0';
- }
- else if (ch >= 'a' && ch <= 'f')
- {
- return ch - 'a' + 10;
- }
- else if (ch >= 'A' && ch <= 'F')
- {
- return ch - 'A' + 10;
- }
- return 0x0;
- }
- static void msg_parser(const INT8 *str)
- {
- UINT8 ch = '\0';
- UINT32 i = 0;
- while (*str != ' ' && *str != '\0' && *(str + 1) != '\0')
- {
- ch = char2Hex(*str) * 16 + char2Hex(*(str + 1));
- str = str + 2;
- pMsg->txMsg.block[i] = ch;
- i++;
- if (i >= 17)
- {
- break;
- }
- }
- pMsg->txMsg.block_num = i;
- }
- #endif
- static void BootUpPatch(void)
- {
- cecdbg("%s:\n", __FUNCTION__);
- /* Patch: Change source to related hdmi source */
- if (BootUpLog)
- {
- UINT32 addr;
- FRAME_t m;
- pMsg->bMessageDone = false;
- addr = query_physical_address(BootUpLog);
- m.block[0] = 0xf | ((BootUpLog & 0xf) << 4);
- m.block[1] = 0x82; // Active Source
- m.block[2] = ((addr >> 8) & 0xff);
- m.block[3] = ((addr) & 0xff);
- m.block_num = 4;
- if (pMsg->bOverwrite)
- {
- cecdbg("Msg overwrite\n");
- pMsg->Rp++;
- }
- memcpy(&pMsg->rxMsg[pMsg->Wp], &m, sizeof(FRAME_t));
- pMsg->txMsg.status = CEC_STATUS_TXEOMDONE;
- pMsg->txMsg.block_num = 0;
- pMsg->Wp = (pMsg->Wp + 1) % FRAMEMAX;
- if (pMsg->Wp == pMsg->Rp)
- {
- cecdbg("Msg Full\n");
- pMsg->bOverwrite = true;
- }
- pMsg->bMessageDone = true;
- cecdbg("Patch: Send <Active Source> log 0x%01x addr 0x%04x\n", BootUpLog, addr);
- BootUpLog = 0;
- }
- }
- #ifdef CONFIG_DEBUG_DRV_CEC_WRITE_EN
- INT32 CEC_write(struct file *file, const INT8 __user * buf, size_t size, loff_t * ppos)
- {
- switch (buf[0])
- {
- case 'm':
- case 'M':
- msg_parser(buf + 1);
- TxFIFO_handler(pMsg);
- break;
- case 't':
- case 'T':
- msg_parser(buf + 1);
- memcpy(&pMsg->rxMsg[pMsg->Wp], &pMsg->txMsg, sizeof(FRAME_t));
- pMsg->txMsg.status = CEC_STATUS_TXEOMDONE;
- pMsg->txMsg.block_num = 0;
- pMsg->Wp = (pMsg->Wp + 1) % FRAMEMAX;
- if (pMsg->Wp == pMsg->Rp)
- {
- pMsg->bOverwrite = true;
- }
- pMsg->bMessageDone = true;
- CEC_parser();
- break;
- default:
- break;
- }
- return size;
- }
- #endif
- void DRV_CEC_Transmit_ARC(UINT8 ucEnable, UINT8 hw_port, INT8 sw_port)
- {
- sysset_cec_arc(ucEnable ? true : false);
- }
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8)
- long CEC_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- #else
- ssize_t CEC_ioctl(struct inode *inode, struct file *filp, UINT32 cmd, ULONG arg)
- #endif
- {
- BOOL bDebugLog = bCECDBG;
- UINT32 uiPhyAddr;
- UINT8 hw_port, ucEnable = 0;
- INT8 sw_port;
- switch (cmd)
- {
- case CEC_CECEnable:
- cecdbg("IOC CECEnable:%ld\n",arg);
- if (arg==0)
- {
- ucEnable = 0;
- cecdbg("Set ARC OFF\n");
- DRV_CEC_Transmit_ARC(ucEnable , hw_port, sw_port);
- }
- break;
- case CEC_REGISTER:
- cecdbg("IOC REGISTER:PID%d\n", cecd_pid);
- /* Patch: boot up by cec, resend active source to cecd */
- BootUpPatch();
- /* Report hpd status again when cecd is started. */
- hdmi_report_cur_hpd();
- /* Assign cecd pid for driver. Put this at the last one. */
- cecd_pid = arg;
- break;
- case CEC_DEBUGLOG:
- copy_to_user((void*)arg, (void*)&bDebugLog, sizeof(BOOL));
- cecdbg("IOC DEBUGLOG:%d\n", bCECDBG);
- break;
- case CEC_SENDMSG:
- cecdbg("IOC SENDMSG\n");
- TxFIFO_handler(pMsg);
- break;
- case CEC_DEBUG://For AP debug only.
- memcpy(&pMsg->rxMsg[pMsg->Wp], &pMsg->txMsg, sizeof(FRAME_t));
- pMsg->txMsg.status = CEC_STATUS_TXEOMDONE;
- pMsg->txMsg.block_num = 0;
- pMsg->Wp = (pMsg->Wp + 1) % FRAMEMAX;
- if (pMsg->Wp == pMsg->Rp)
- {
- pMsg->bOverwrite = true;
- }
- pMsg->bMessageDone = true;
- CEC_parser();
- break;
- case CEC_ReportARCInitiation:
- uiPhyAddr = arg;
- cecdbg("IOC ReportARCInitiationn:0x%x\n", uiPhyAddr);
- hw_port = (UINT8) hdmi_hw_port(((uiPhyAddr >> 12) & 0x0f) - 1);
- sw_port = hdmi_sw_port(((uiPhyAddr >> 12) & 0x0f) - 1); //switch port
- ucEnable = 1;
- DRV_CEC_Transmit_ARC(ucEnable, hw_port, sw_port);
- break;
- case CEC_ReportARCTermination:
- uiPhyAddr = arg;
- cecdbg("IOC ReportARCTermination:0x%x\n", uiPhyAddr);
- hw_port = (UINT8) hdmi_hw_port(((uiPhyAddr >> 12) & 0x0f) - 1);
- sw_port = hdmi_sw_port(((uiPhyAddr >> 12) & 0x0f) - 1); //switch port
- ucEnable = 0;
- DRV_CEC_Transmit_ARC(ucEnable, hw_port, sw_port);
- break;
- case CEC_ARC_PORT_HPD_TOGGLE:
- printk("IOC CEC_ARC_PORT_HPD_TOGGLE:%ld\n",arg);
- if (arg==1)
- {
- printk("CEC_ARC_PORT_HPD_TOGGLE\n");
- hdmi_apply_hpd((1 << geARCPort), DRV_HPD_LEVEL_LOW);
- HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
- hdmi_apply_hpd((1 << geARCPort), DRV_HPD_LEVEL_HIGH);
- }
- break;
-
- }
- return 0;
- }
- INT32 CEC_mmap(struct file *filp, struct vm_area_struct *vma)
- {
- if (vma->vm_end - vma->vm_start > 4096)
- {
- return -ENOMEM;
- }
- if (remap_pfn_range(vma, vma->vm_start, vmalloc_to_pfn(pMsg), vma->vm_end - vma->vm_start, vma->vm_page_prot))
- {
- return -EAGAIN;
- }
- return 0;
- }
- irqreturn_t CEC_ISR(INT32 irq, void* dev_id)
- {
- //static DRV_5V_LEVEL_e ePortA_5V_Level = DRV_5V_LEVEL_LOW, ePortB_5V_Level = DRV_5V_LEVEL_LOW, ePortC_5V_Level = DRV_5V_LEVEL_LOW;
- //volatile CEC_REG0000_t *tCEC_INT = (CEC_REG0000_t *)0xbe1e0000;
- CEC_REG0000_t tCEC_INT;
- CEC_REG0000_t dCEC_INT_tmp;
- tCEC_INT.dCECReg0000_0003 = HDMI_RegisterRead(CEC_0000_DW_0000);
- dCEC_INT_tmp.dCECReg0000_0003 = tCEC_INT.dCECReg0000_0003 & 0xF00017FF; //mask interrupt bit
- if((geARCPort != HDMI_PORT_A) || (geGpio5V_Pin == GPIO_NOT_USE))
- {
- if (tCEC_INT.ists_ddc5v_0_fall)
- {
- cecdbg("INT A 5V out\n");
- dCEC_INT_tmp.ists_ddc5v_0_fall = 1; //for clear
- //ePortA_5V_Level = DRV_5V_LEVEL_LOW;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortA_5V_debounce, (void *)DRV_5V_LEVEL_LOW, (hdmi_get_cur_port() == HDMI_PORT_A) ? 0:500);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- if (tCEC_INT.ists_ddc5v_0_rise)
- {
- cecdbg("INT A 5V in\n");
- dCEC_INT_tmp.ists_ddc5v_0_rise = 1; //for clear
- //ePortA_5V_Level = DRV_5V_LEVEL_HIGH;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortA_5V_debounce, (void *)DRV_5V_LEVEL_HIGH, 0);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- }
- if((geARCPort != HDMI_PORT_B) || (geGpio5V_Pin == GPIO_NOT_USE))
- {
- if (tCEC_INT.ists_ddc5v_1_fall)
- {
- cecdbg("INT B 5V out\n");
- dCEC_INT_tmp.ists_ddc5v_1_fall = 1; //for clear
- //ePortB_5V_Level = DRV_5V_LEVEL_LOW;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortB_5V_debounce, (void *)DRV_5V_LEVEL_LOW, (hdmi_get_cur_port() == HDMI_PORT_B) ? 0:500);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- if (tCEC_INT.ists_ddc5v_1_rise)
- {
- cecdbg("INT B 5V in\n");
- dCEC_INT_tmp.ists_ddc5v_1_rise = 1; //for clear
- //ePortB_5V_Level = DRV_5V_LEVEL_HIGH;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortB_5V_debounce, (void *)DRV_5V_LEVEL_HIGH, 0);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- }
- if((geARCPort != HDMI_PORT_C) || (geGpio5V_Pin == GPIO_NOT_USE))
- {
- if (tCEC_INT.R_INTR_Status_rx_ddc5v_2_fall)
- {
- cecdbg("INT C 5V out\n");
- dCEC_INT_tmp.R_INTR_Status_rx_ddc5v_2_fall = 1; //for clear
- //ePortC_5V_Level = DRV_5V_LEVEL_LOW;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortC_5V_debounce, (void *)DRV_5V_LEVEL_LOW, (hdmi_get_cur_port() == HDMI_PORT_C) ? 0:500);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- if (tCEC_INT.R_INTR_Status_rx_ddc5v_2_rise)
- {
- cecdbg("INT C 5V in\n");
- dCEC_INT_tmp.R_INTR_Status_rx_ddc5v_2_rise = 1; //for clear
- //ePortC_5V_Level = DRV_5V_LEVEL_HIGH;
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_notice(&PortC_5V_debounce, (void *)DRV_5V_LEVEL_HIGH, 0);
- #else
- debounce_notice(&Src_5V_debounce, NULL, 30);
- #endif
- }
- }
-
- if (tCEC_INT.ists_tx_noarbit)
- {
- cecdbg("tx_noarbit\n");
- dCEC_INT_tmp.ists_tx_noarbit = 1; //for clear
- pMsg->txMsg.status = CEC_STATUS_TXNOARBIT;
- pMsg->txMsg.block_num = 0;
- }
- else if (tCEC_INT.ists_tx_noack)
- {
- cecdbg("x_noack\n");
- dCEC_INT_tmp.ists_tx_noack = 1; //for clear
- pMsg->txMsg.status = CEC_STATUS_TXNOACK;
- pMsg->txMsg.block_num = 0;
- }
- else if (tCEC_INT.ists_tx_eom_done)
- {
- pFRAME_t ptxMsg = &(pMsg->txMsg);
- cecdbg("tx_eom_done\n");
- dCEC_INT_tmp.ists_tx_eom_done = 1; //for clear
- ptxMsg->status = CEC_STATUS_TXEOMDONE;
- ptxMsg->block_num = 0;
- }
- else if (tCEC_INT.ists_rfifo_ready)
- {
- cecdbg("rfifo_ready\n");
- dCEC_INT_tmp.ists_rfifo_ready = 1; //for clear
- pMsg->rxFifo_cnt = HDMI_RegisterRead(CEC_R_rfifo_th) + 1;
- RxFIFO_handler(pMsg);
- }
- else if (tCEC_INT.ists_rx_pop_done)
- {
- cecdbg("rx_pop_done\n");
- dCEC_INT_tmp.ists_rx_pop_done = 1; //for clear
- RxFIFO_handler(pMsg);
- }
- else if (tCEC_INT.ists_rx_discon)
- {
- cecdbg("rx_discon\n");
- dCEC_INT_tmp.ists_rx_discon = 1; //for clear
- }
- else if (tCEC_INT.ists_rx_eom)
- {
- cecdbg("rx_eom\n");
- dCEC_INT_tmp.ists_rx_eom = 1; //for clear
- pMsg->rxFifo_cnt = HDMI_RegisterRead(CEC_R_rfifo_th);
- RxFIFO_handler(pMsg);
- }
- HDMI_RegisterWrite(CEC_0000_DW_0000, dCEC_INT_tmp.dCECReg0000_0003); //clear interrupt status
-
- return IRQ_HANDLED;
- }
- static void CheckArcGpio5V_change(void *dummy)
- {
- DRV_5V_LEVEL_e eGpio5VLevel = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT) ? DRV_5V_LEVEL_HIGH:DRV_5V_LEVEL_LOW);
- cecdbg("%s Gpio5VLevel=%d\n", __FUNCTION__, eGpio5VLevel);
- #ifdef CONFIG_SUPPORT_HDMI_PLUGIN_CHANGE_SOURCE
- if(eGpio5VLevel == DRV_5V_LEVEL_HIGH)
- hdmi_5v_change_need_ChangeSrc(geARCPort);
- else
- hdmi_5v_change_need_ChangeSrc(HDMI_PORT_NUM);
- #endif
- if(eGpio5VLevel == DRV_5V_LEVEL_HIGH)
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_INVETER
- EnableGPIOInterrupt(geGpio5V_Pin, 0x1); // 00 low_level trigger, 01 high_level trigger, 10 falling edge, 11 rising edge
- #else
- EnableGPIOInterrupt(geGpio5V_Pin, 0x0); // 00 low_level trigger, 01 high_level trigger, 10 falling edge, 11 rising edge
- #endif
- }
- else
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_INVETER
- EnableGPIOInterrupt(geGpio5V_Pin, 0x0); // 00 low_level trigger, 01 high_level trigger, 10 falling edge, 11 rising edge
- #else
- EnableGPIOInterrupt(geGpio5V_Pin, 0x1); // 00 low_level trigger, 01 high_level trigger, 10 falling edge, 11 rising edge
- #endif
- }
- #ifdef HDMI_DDC5V_WORKAROUND
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
- debounce_notice(&PortA_5V_debounce, (void *)eGpio5VLevel, 0);
- #endif
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
- debounce_notice(&PortB_5V_debounce, (void *)eGpio5VLevel, 0);
- #endif
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
- debounce_notice(&PortC_5V_debounce, (void *)eGpio5VLevel, 0);
- #endif
- #else
- debounce_notice(&Src_5V_debounce, NULL, 0);
- #endif
-
- }
- HDMI_CABLE_T DRV_GPIO5V_GET_CABLE_CONNECT_STATE(void)
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_INVETER
- if(GPIOTryRead(geGpio5V_Pin) == 0)
- #else
- if(GPIOTryRead(geGpio5V_Pin) == 1)
- #endif
- return HDMI_CALBE_CONNECT;
- else
- return HDMI_CALBE_DISCONT;
- }
- void DRV_GPIO5V_ISR_Callback(void)
- {
- DisableGPIOInterrupt(geGpio5V_Pin); //disable interrupt when interrupt happend
- cecdbg("%s\n", __FUNCTION__);
- debounce_notice(&ArcGpio_5V_debounce, (void *)NULL, 250); //debounce GPIO 5V value for 250ms and enable interrupt
- }
- char check_mhl_det(void)
- {
- int i;
- for( i=0 ; i<5 ; i++ )
- {
- if(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)
- {
- cecdbg("in MHL mode ignore set hpd %d \n",i);
- return 1;
- }
- }
- return 0;
- }
- void DRV_Set_GPIO5V_ARCPort(GPIOPin_t eGpio5V_Pin, HDMI_PORT_T eARCPort)
- {
- UINT8 bIntrEn = 0;
- geGpio5V_Pin = eGpio5V_Pin;
- geARCPort = eARCPort;
- cecdbg("%s GPIO:%d ARCPort:%d\n", __FUNCTION__, geGpio5V_Pin, geARCPort);
- if(geGpio5V_Pin != GPIO_NOT_USE)
- {
- #ifdef CONFIG_SUPPORT_MONITOR
- //setup DDC 5V interrupt
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
- bIntrEn = 0;
- #else
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_A) == HDMI_SRC_NULL)?0:1;
- #endif
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_fall, bIntrEn);
- sysset_DDC_PortA_Det5V_En(bIntrEn);
-
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
- bIntrEn = 0;
- #else
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_B) == HDMI_SRC_NULL)?0:1;
- #endif
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_fall, bIntrEn);
- sysset_DDC_PortB_Det5V_En(bIntrEn);
-
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
- bIntrEn = 0;
- #else
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_C) == HDMI_SRC_NULL)?0:1;
- #endif
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_fall, bIntrEn);
- sysset_DDC_PortC_Det5V_En(bIntrEn);
- #else
- //setup DDC 5V interrupt
- bIntrEn = (geARCPort == HDMI_PORT_A)?0:
- (hdmi_get_channel_at_hw_port(HDMI_PORT_A) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_fall, bIntrEn);
- sysset_DDC_PortA_Det5V_En(bIntrEn);
-
- bIntrEn = (geARCPort == HDMI_PORT_B)?0:
- (hdmi_get_channel_at_hw_port(HDMI_PORT_B) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_fall, bIntrEn);
- sysset_DDC_PortB_Det5V_En(bIntrEn);
-
- bIntrEn = (geARCPort == HDMI_PORT_C)?0:
- (hdmi_get_channel_at_hw_port(HDMI_PORT_C) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_fall, bIntrEn);
- sysset_DDC_PortC_Det5V_En(bIntrEn);
- #endif
- }
- else
- {
- printk("!!!!!! geGpio5V_Pin == GPIO_NOT_USE !!!!!!\n");
- //All 3 hdmi ports use DDC 5V interrupt
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_A) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_fall, bIntrEn);
- sysset_DDC_PortA_Det5V_En(bIntrEn);
-
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_B) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_fall, bIntrEn);
- sysset_DDC_PortB_Det5V_En(bIntrEn);
-
- bIntrEn = (hdmi_get_channel_at_hw_port(HDMI_PORT_C) == HDMI_SRC_NULL)?0:1;
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_rise, bIntrEn);
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_fall, bIntrEn);
- sysset_DDC_PortC_Det5V_En(bIntrEn);
- }
-
- #ifndef CONFIG_SUPPORT_MONITOR
- if(geGpio5V_Pin != GPIO_NOT_USE && geARCPort != HDMI_PORT_NULL)
- {
- RegGPIOCallBackFun(geGpio5V_Pin, DRV_GPIO5V_ISR_Callback);
- //dabounce GPIO 5V value for 250ms and enable interrupt
- debounce_notice(&ArcGpio_5V_debounce, (void *)NULL, 250);
- }
- #endif
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- #if CONFIG_HDMI_MHL_PORT == 0
- if(check_mhl_det()== 0)
- #endif
- #endif
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
- #else
- sysset_HDMI_SW5V(HDMI_PORT_A,false);
- #endif
- }
- #ifdef CONFIG_HDMI_SUPPORT_MHL
- #if CONFIG_HDMI_MHL_PORT == 1
- if(check_mhl_det()== 0)
- #endif
- #endif
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
- #else
- sysset_HDMI_SW5V(HDMI_PORT_B,false);
- #endif
- }
- {
- #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
- #else
- sysset_HDMI_SW5V(HDMI_PORT_C,false);
- #endif
- }
- }
- HDMI_PORT_T DRV_Get_GPIO5V_ARCPort(void)
- {
- return geARCPort;
- }
- #define IRQ_CEC 34
- static void CEC_dispatch(struct pt_regs *regs)
- {
- do_IRQ(IRQ_CEC);
- }
- static struct file_operations CEC_fops =
- {
- #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,8))
- .unlocked_ioctl = CEC_ioctl,
- #else
- .ioctl = CEC_ioctl,
- #endif
- #ifdef CONFIG_DEBUG_DRV_CEC_WRITE_EN
- .write = CEC_write,
- #endif
- .mmap = CEC_mmap,
- .owner = THIS_MODULE,
- };
- #define RXFIFO_TH 2
- #define CECDRV_DEVNAME "/dev/cec" /* Driver Device Name */
- static INT32 cec_devno;
- static struct cdev cec_cdev;
- INT32 DRV_CEC_Init(void)
- {
- INT32 status;
- UINT8 *pCECstate = (UINT8*)CECSTATE_ADDR;
- cecdbg("%s\n", __FUNCTION__);
- pMsg = (pCEC_MSG_t)drv_vmalloc(sizeof(CEC_MSG_t), MODULEID_CEC);
- memset(pMsg, 0x0, sizeof(CEC_MSG_t));
- sysset_hdmi_hpd_detection();
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_rise, 0);
- HDMI_RegisterWrite(CEC_ien_ddc5v_0_fall, 0);
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_rise, 0);
- HDMI_RegisterWrite(CEC_ien_ddc5v_1_fall, 0);
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_rise, 0);
- HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_fall, 0);
- if(HDMI_RegisterRead(CEC_ists_ddc5v_0_rise) == 1){cecdbg("CEC_ists_ddc5v_0_rise clr");HDMI_RegisterWrite(CEC_ists_ddc5v_0_rise,0);}
- if(HDMI_RegisterRead(CEC_ists_ddc5v_0_fall) == 1){cecdbg("CEC_ists_ddc5v_0_fall clr");HDMI_RegisterWrite(CEC_ists_ddc5v_0_fall,0);}
- if(HDMI_RegisterRead(CEC_ists_ddc5v_1_rise) == 1){cecdbg("CEC_ists_ddc5v_1_rise clr");HDMI_RegisterWrite(CEC_ists_ddc5v_1_rise,0);}
- if(HDMI_RegisterRead(CEC_ists_ddc5v_1_fall) == 1){cecdbg("CEC_ists_ddc5v_1_fall clr");HDMI_RegisterWrite(CEC_ists_ddc5v_1_fall,0);}
- if(HDMI_RegisterRead(CEC_R_INTR_Status_rx_ddc5v_2_rise) == 1){cecdbg("CEC_R_INTR_Status_rx_ddc5v_2_rise clr");HDMI_RegisterWrite(CEC_R_INTR_Status_rx_ddc5v_2_rise,0);}
- if(HDMI_RegisterRead(CEC_R_INTR_Status_rx_ddc5v_2_fall) == 1){cecdbg("CEC_R_INTR_Status_rx_ddc5v_2_fall clr");HDMI_RegisterWrite(CEC_R_INTR_Status_rx_ddc5v_2_fall,0);}
- if (!pMsg)
- {
- cecdbg("%s: Can not allocate memory\n", __FUNCTION__);
- return -ENOMEM;
- }
- if (*pCECstate)
- {
- cecdbg("onetouch play");
- hdmi_apply_hpd(
- #if ((CONFIG_HDMI_PORT_MAP & 0x00f) != 0)
- DRV_HDMI_PORT_A |
- #endif
- #if ((CONFIG_HDMI_PORT_MAP & 0x0f0) != 0)
- DRV_HDMI_PORT_B |
- #endif
- #if ((CONFIG_HDMI_PORT_MAP & 0xf00) != 0)
- DRV_HDMI_PORT_C |
- #endif
- 0 , DRV_HPD_LEVEL_LOW);
- HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
- hdmi_apply_hpd_by5V(
- #if ((CONFIG_HDMI_PORT_MAP & 0x00f) != 0)
- DRV_HDMI_PORT_A |
- #endif
- #if ((CONFIG_HDMI_PORT_MAP & 0x0f0) != 0)
- DRV_HDMI_PORT_B |
- #endif
- #if ((CONFIG_HDMI_PORT_MAP & 0xf00) != 0)
- DRV_HDMI_PORT_C |
- #endif
- 0);
- }
- INIT_WORK(&wq_cec_signal, (work_func_t) CEC_parser_wq);
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_init(&PortA_5V_debounce, Check_PortA_5V_change);
- debounce_init(&PortB_5V_debounce, Check_PortB_5V_change);
- debounce_init(&PortC_5V_debounce, Check_PortC_5V_change);
- debounce_init(&PortA_HPD_debounce, Set_PortA_HPD_Timer_Fn);
- debounce_init(&PortB_HPD_debounce, Set_PortB_HPD_Timer_Fn);
- debounce_init(&PortC_HPD_debounce, Set_PortC_HPD_Timer_Fn);
- #else
- debounce_init(&Src_5V_debounce, CheckSrc5V_change);
- #endif
- debounce_init(&ArcGpio_5V_debounce, CheckArcGpio5V_change);
- // INIT_WORK(&wq_SetHPD_A_TOGGLE, (work_func_t) SetHPD_A_TOGGLE);
- // INIT_WORK(&wq_SetHPD_B_TOGGLE, (work_func_t) SetHPD_B_TOGGLE);
- // INIT_WORK(&wq_SetHPD_C_TOGGLE, (work_func_t) SetHPD_C_TOGGLE);
- set_vi_handler(IRQ_CEC, (vi_handler_t) CEC_dispatch);
- status = request_irq(IRQ_CEC, &CEC_ISR, IRQF_DISABLED, "cec", NULL);
- if (status)
- {
- return -EIO;
- }
- cec_devno = MKDEV(CDEV_CEC_MAJOR, 0);
- status = register_chrdev_region(cec_devno, 0, CECDRV_DEVNAME);
- if (status)
- {
- return -EIO;
- }
- cdev_init(&cec_cdev, &CEC_fops);
- cec_cdev.owner = THIS_MODULE;
- cec_cdev.ops = &CEC_fops;
- if (cdev_add(&cec_cdev, cec_devno, 1))
- {
- return -EIO;
- }
- //cecdbg("(CEC_ien_ddc5v_0_rise) = %d\n",HDMI_RegisterRead(CEC_ien_ddc5v_0_rise));
- //cecdbg("(CEC_ien_ddc5v_0_fall) = %d\n",HDMI_RegisterRead(CEC_ien_ddc5v_0_fall));
- //cecdbg("(CEC_ien_ddc5v_1_rise) = %d\n",HDMI_RegisterRead(CEC_ien_ddc5v_1_rise));
- //cecdbg("(CEC_ien_ddc5v_1_fall) = %d\n",HDMI_RegisterRead(CEC_ien_ddc5v_1_fall));
- //cecdbg("(CEC_R_INTR_en_rx_ddc5v_2_rise) = %d\n",HDMI_RegisterRead(CEC_R_INTR_en_rx_ddc5v_2_rise));
- //cecdbg("(CEC_R_INTR_en_rx_ddc5v_2_fall) = %d\n",HDMI_RegisterRead(CEC_R_INTR_en_rx_ddc5v_2_fall));
- //cecdbg("(CEC_R_cec_en) = %d\n",HDMI_RegisterRead(CEC_R_cec_en));
- sysset_HDMI_CEC_DIODE_ON();
- HDMI_RegisterWrite(CEC_R_cec_en, 0); //Disable CEC
- HDMI_RegisterWrite(CEC_R_cec_en, 1); //Enable CEC
- HDMI_RegisterWrite(CEC_R_rfifo_th, RXFIFO_TH);
- HDMI_RegisterWrite(CEC_ien_tx_noarbit, 1);
- HDMI_RegisterWrite(CEC_ien_tx_noack, 1);
- HDMI_RegisterWrite(CEC_ien_tx_eom_done, 1);
- HDMI_RegisterWrite(CEC_ien_rfifo_ready, 1);
- HDMI_RegisterWrite(CEC_ien_rx_pop_done, 1);
- HDMI_RegisterWrite(CEC_ien_rx_discon, 1);
- HDMI_RegisterWrite(CEC_ien_rx_eom, 1);
- HDMI_RegisterWrite(CEC_timer_retryframe_period, 0xca);
- HDMI_RegisterWrite(CEC_timer_newframe_preiod, 0x12);
- HDMI_RegisterWrite(CEC_timer_conframe_period, 0x1d);
- //enable 5V interrupt move to DRV_Set_GPIO5V_ARCPort
- //HDMI_RegisterWrite(CEC_ien_ddc5v_0_rise, 1);
- //HDMI_RegisterWrite(CEC_ien_ddc5v_0_fall, 1);
- //HDMI_RegisterWrite(CEC_ien_ddc5v_1_rise, 1);
- //HDMI_RegisterWrite(CEC_ien_ddc5v_1_fall, 1);
- //HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_rise, 1);
- //HDMI_RegisterWrite(CEC_R_INTR_en_rx_ddc5v_2_fall, 1);
-
- HDMI_RegisterWrite(CEC_R_hpd_man, 1); /* enable */
- pMsg->txMsg.status = CEC_STATUS_TXEOMDONE;
- pMsg->txMsg.block_num = 0;
- pMsg->Wp = 0;
- pMsg->Rp = 0;
- pMsg->bMessageDone = false;
- return 0;
- }
- void DRV_CEC_Exit(void)
- {
- //Disable all interrupts.
- HDMI_RegisterWrite(CEC_0008_DW_0008, HDMI_RegisterRead(CEC_0008_DW_0008) & 0xfffff000);
- HDMI_RegisterWrite(CEC_0020_DW_0020, HDMI_RegisterRead(CEC_0020_DW_0020) & 0xf0ffffff);
- HDMI_RegisterWrite(CEC_R_cec_en, 0);//Disable CEC
- free_irq(IRQ_CEC, NULL);
- cdev_del(&cec_cdev);
- unregister_chrdev_region(cec_devno, 0);
- #ifdef HDMI_DDC5V_WORKAROUND
- debounce_exit(&PortA_5V_debounce);
- debounce_exit(&PortB_5V_debounce);
- debounce_exit(&PortC_5V_debounce);
- debounce_exit(&PortA_HPD_debounce);
- debounce_exit(&PortB_HPD_debounce);
- debounce_exit(&PortC_HPD_debounce);
- #else
- debounce_exit(&Src_5V_debounce);
- #endif
- if (pMsg)
- {
- vfree(pMsg);
- }
- }
|