1 #ifdef CONFIG_MTK_INTERNAL_HDMI_SUPPORT
3 #include <linux/interrupt.h>
5 #include <linux/slab.h>
7 #include <linux/miscdevice.h>
8 #include <asm/uaccess.h>
9 #include <linux/delay.h>
10 #include <linux/input.h>
11 #include <linux/workqueue.h>
12 #include <linux/kobject.h>
13 #include <linux/earlysuspend.h>
14 #include <linux/platform_device.h>
15 #include <asm/atomic.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/sched.h>
19 #include <linux/kthread.h>
20 #include <linux/bitops.h>
21 #include <linux/kernel.h>
22 #include <linux/byteorder/generic.h>
23 #include <linux/interrupt.h>
24 #include <linux/time.h>
25 #include <linux/rtpm_prio.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/syscalls.h>
28 #include <linux/reboot.h>
29 #include <linux/vmalloc.h>
31 #include <linux/string.h>
32 #include <linux/completion.h>
34 #include "hdmi_ctrl.h"
37 //#include "hdmi_drv.h"
38 #include <cust_eint.h>
39 #include "cust_gpio_usage.h"
40 #include "mach/eint.h"
41 #include "mach/irqs.h"
44 #include <mach/devs.h>
45 #include <mach/mt_typedefs.h>
46 #include <mach/mt_gpio.h>
47 #include <mach/mt_pm_ldo.h>
49 #include <mach/mt_pmic_wrap.h>
53 static unsigned short _CEC_Status
;
55 #define SetCECStatus(arg) (_CEC_Status |= (arg))
56 #define ClrCECStatus(arg) (_CEC_Status &= (~(arg)))
57 #define IsCECStatus(arg) ((_CEC_Status & (arg)) > 0)
59 static unsigned short _CEC_ErrStatus
;
60 #define SetCECErrorFlag(arg) (_CEC_ErrStatus |= (arg))
61 #define ClrCECErrorFlag(arg) (_CEC_ErrStatus &= (~(arg)))
62 #define IsCECErrorFlag(arg) ((_CEC_ErrStatus & (arg)) > 0)
65 static CEC_FRAME_DESCRIPTION ActiveRXFrame
;
66 static CEC_FRAME_DESCRIPTION CTSTestFrame
;
68 unsigned int hdmi_cec_2n(unsigned int u4Data
);
69 unsigned int hdmi_cec_maskvalue(unsigned int u4Width
, unsigned int u4Startbit
);
70 extern void vNotifyAppHdmiCecState(HDMI_NFY_CEC_STATE_T u1hdmicecstate
);
72 unsigned int hdmi_cec_read(unsigned short u2Reg
);
73 void hdmi_cec_write(unsigned short u2Reg
, unsigned int u4Data
);
74 void hdmi_cec_init(void);
76 static CEC_FRAME_DESCRIPTION CEC_rx_msg_queue
[RX_Q_SIZE
];
77 static CEC_FRAME_DESCRIPTION CEC_tx_msg_queue
[TX_Q_SIZE
];
79 CEC_FRAME_DESCRIPTION
* ActiveTXFrame
;
80 CEC_LA_ADDRESS _rCECLaAddr
;
81 static CEC_FRAME_DESCRIPTION cecMwTxMsg
;
82 CEC_ADDRESS _rCECPhysicAddr
;
84 static unsigned char _u1TxFailCause
= 0;
85 static unsigned char _u1ReTxCnt
= 0;
86 static unsigned char CEC_rxQ_read_idx
;
87 static unsigned char CEC_rxQ_write_idx
;
88 static unsigned char CEC_txQ_read_idx
;
89 static unsigned char CEC_txQ_write_idx
;
90 CEC_ACK_INFO_T cec_send_result
;
91 CEC_FRAME_DESCRIPTION
*cec_receive_msg
;
92 static unsigned char cec_msg_report_pending
= 0;
93 extern size_t hdmi_cec_on
;
94 extern void cec_timer_wakeup(void);
96 #define IS_RX_Q_EMPTY() (CEC_rxQ_read_idx == CEC_rxQ_write_idx)
97 #define IS_RX_Q_FULL() (((CEC_rxQ_write_idx+1)%RX_Q_SIZE) == CEC_rxQ_read_idx)
98 #define IS_TX_Q_EMPTY() (CEC_txQ_read_idx == CEC_txQ_write_idx)
99 #define IS_TX_Q_FULL() (((CEC_txQ_write_idx+1)%TX_Q_SIZE) == CEC_txQ_read_idx)
101 #define HDMICEC_BASE (0xF0012000)
103 #define u1RegRead1B(reg16) (hdmi_cec_read(reg16)&0xff)
104 #define u4RegRead4B(reg16) (hdmi_cec_read(reg16))
107 #define RegReadFldAlign(reg16,fld) ((hdmi_cec_read(reg16)>>(Fld_shft(fld)))&(hdmi_cec_2n(Fld_wid(fld))))
108 #define vRegWriteFldAlign(reg16,val,fld) (hdmi_cec_write(reg16, (((hdmi_cec_read(reg16))&(hdmi_cec_maskvalue(Fld_wid(fld),Fld_shft(fld))))|(val<<(Fld_shft(fld))))))
110 #define IS_INT_DATA_RDY() (RegReadFldAlign(RX_EVENT, DATA_RDY))
111 #define IS_INT_HEADER_RDY() (RegReadFldAlign(RX_EVENT, HEADER_RDY))
112 #define IS_INT_MODE_RDY() (RegReadFldAlign(RX_EVENT, MODE_RDY))
113 #define IS_INT_OV() (RegReadFldAlign(RX_EVENT, OV))
114 #define IS_INT_BR_SB_RDY() (RegReadFldAlign(RX_EVENT, BR_SB_RDY))
115 #define IS_INT_SB_RDY() (RegReadFldAlign(RX_EVENT, SB_RDY))
116 #define IS_INT_BR_RDY() (RegReadFldAlign(RX_EVENT, BR_RDY))
117 #define ENABLE_INT_DATA_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_DATA)
118 #define ENABLE_INT_HEADER_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_HEADER)
119 #define ENABLE_INT_MODE_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_MODE)
120 #define ENABLE_INT_OV(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_OV)
121 #define ENABLE_INT_PULSE(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_PULSE)
122 #define ENABLE_INT_BR_SB_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_BR_SB)
123 #define ENABLE_INT_SB_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_SB)
124 #define ENABLE_INT_BR_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_BR)
125 #define CLR_INT_DATA_RDY() vRegWriteFldAlign(RX_EVENT, 0, DATA_RDY)
126 #define CLR_INT_HEADER_RDY() vRegWriteFldAlign(RX_EVENT, 0, HEADER_RDY)
127 #define CLR_INT_MODE_RDY() vRegWriteFldAlign(RX_EVENT, 0, MODE_RDY)
128 #define CLR_INT_OV() vRegWriteFldAlign(RX_EVENT, 0, OV)
129 #define NOTIFY_RX_HW_DATA_TAKEN() vRegWriteFldAlign(RX_EVENT, 0, BR_RDY)
130 #define HW_RX_DATA_ARRIVED() IS_INT_BR_RDY()
131 #define HW_RX_HEADER_ARRIVED() IS_INT_HEADER_RDY()
134 #define IS_INT_UN() (RegReadFldAlign(TX_EVENT, UN))
135 #define IS_INT_LOW() (RegReadFldAlign(TX_EVENT, LOWB))
136 #define IS_TX_FINISH() (RegReadFldAlign(TX_EVENT, BS))
137 #define IS_INT_RB_RDY() (RegReadFldAlign(TX_EVENT, RB_RDY))
138 #define ENABLE_INT_UN(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_UN)
139 #define ENABLE_INT_FAIL(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_FAIL)
140 #define ENABLE_INT_LOW(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_LOW)
141 #define ENABLE_INT_BS(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_BS)
142 #define ENABLE_INT_RB(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_RB)
143 #define CLR_INT_UN() vRegWriteFldAlign(TX_EVENT, 0, UN)
144 #define CLR_INT_LOW() vRegWriteFldAlign(TX_EVENT, 0, LOWB)
145 #define CLR_TX_FINISH() vRegWriteFldAlign(TX_EVENT, 0, BS)
146 #define TRIGGER_TX_HW() vRegWriteFldAlign(TX_EVENT, 1, RB_RDY)
147 #define IS_TX_DATA_TAKEN() (!(IS_INT_RB_RDY()))
148 #define IS_INT_RB_ENABLE() (RegReadFldAlign(TX_EVENT, I_EN_RB))
149 #define IS_INT_FAIL_ENABLE() (RegReadFldAlign(TX_EVENT, I_EN_FAIL))
150 #define DISABLE_ALL_TX_INT() \
152 ENABLE_INT_FAIL(0); \
160 #define IS_RX_FSM_IDLE() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x01)
161 #define IS_RX_FSM_START() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x02)
162 #define IS_RX_FSM_MODE() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x04)
163 #define IS_RX_FSM_MODE1_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x08)
164 #define IS_RX_FSM_MODE1_ARB() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x10)
165 #define IS_RX_FSM_MODE1_FLAG() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x20)
166 #define IS_RX_FSM_MODE2_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x40)
167 #define IS_RX_FSM_MODE2_CMD() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x80)
168 #define IS_RX_FSM_MODE3_ID() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0100)
169 #define IS_RX_FSM_MODE3_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0200)
170 #define IS_RX_FSM_MODE3_DATA() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0400)
171 #define IS_RX_FSM_GENERAL() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0800)
172 #define IS_RX_FSM_ERROR_S() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x1000)
173 #define IS_RX_FSM_ERROR_D() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x2000)
174 #define RX_FSM_STATUS() (RegReadFldAlign(RX_STATUS, RX_FSM))
177 #define IS_TX_FSM_IDLE() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x01)
178 #define IS_TX_FSM_INIT() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x02)
179 #define IS_TX_FSM_EOM() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x04)
180 #define IS_TX_FSM_RETRASMIT() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x08)
181 #define IS_TX_FSM_FAIL() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x10)
182 #define IS_TX_FSM_START() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x20)
183 #define IS_TX_FSM_MODE() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x40)
184 #define IS_TX_FSM_MODE1_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x80)
185 #define IS_TX_FSM_MODE1_DATA() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x100)
186 #define IS_TX_FSM_MODE2_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x200)
187 #define IS_TX_FSM_MODE2_CMD() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x400)
188 #define IS_TX_FSM_MODE3_ID() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x800)
189 #define IS_TX_FSM_MODE3_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x1000)
190 #define IS_TX_FSM_MODE3_DATA() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x2000)
191 #define IS_TX_FSM_GENERAL() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x4000)
192 #define TX_FSM_STATUS() (RegReadFldAlign(TX_STATUS, TX_FSM))
194 #define ENABLE_TX_EN() vRegWriteFldAlign(TR_CONFIG, 1, TX_EN)
195 #define DISABLE_TX_EN() vRegWriteFldAlign(TR_CONFIG, 0, TX_EN)
196 #define ENABLE_RX_EN() vRegWriteFldAlign(TR_CONFIG, 1, RX_EN)
197 #define DISABLE_RX_EN() vRegWriteFldAlign(TR_CONFIG, 0, RX_EN)
199 #define SET_HW_TX_LEN(num) vRegWriteFldAlign(TX_HD_NEXT, num, WTX_M3_DATA_MASK)
200 #define FILL_SRC_FIELD(addr) vRegWriteFldAlign(TX_HD_NEXT, addr, WTX_SRC)
201 #define FILL_DST_FIELD(addr) vRegWriteFldAlign(TX_HD_NEXT, addr, WTX_DST)
202 #define MARK_H_EOM(onoff) vRegWriteFldAlign(TX_HD_NEXT, onoff, WTX_H_EOM)
203 #define MARK_D_EOM(onoff) vRegWriteFldAlign(TX_HD_NEXT, onoff, WTX_D_EOM)
205 #define FILL_TX_DATA(data) vRegWriteFldAlign(TX_DATA_NEXT, data, WTX_DATA)
207 #define GET_HW_RX_LEN() (RegReadFldAlign(RX_HEADER, RXED_M3_DATA_MASK))
208 #define GET_SRC_FIELD() (RegReadFldAlign(RX_HEADER, RXED_SRC))
209 #define GET_DST_FIELD() (RegReadFldAlign(RX_HEADER, RXED_DST))
210 #define GET_SRC_FIELD_RECEIVING() (RegReadFldAlign(RX_HD_NEXT, RXING_SRC))
211 #define GET_DST_FIELD_RECEIVING() (RegReadFldAlign(RX_HD_NEXT, RXING_DST))
212 #define IS_RX_H_EOM() (RegReadFldAlign(RX_HEADER, RXED_H_EOM))
213 #define IS_RX_D_EOM() (RegReadFldAlign(RX_HEADER, RXED_D_EOM))
215 #define GET_HW_RX_DATA() (RegReadFldAlign(RX_DATA, RXED_DATA))
217 #define FLOW_CONTROL_ACK(onoff) \
219 vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_H_ACK);\
220 vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_D_ACK);\
223 #define GET_FOLLOWER_H_ACK() (RegReadFldAlign(TX_HEADER, TXING_H_ACK))
224 #define GET_FOLLOWER_D_ACK() (RegReadFldAlign(TX_HEADER, TXING_D_ACK))
226 #define TX_FAIL_MAX() (RegReadFldAlign(TX_FAIL, RETX_MAX))
227 #define CLR_TX_FAIL_MAX() vRegWriteFldAlign(TX_FAIL, 0, RETX_MAX)
229 #define TX_FAIL_RECORD() u4RegRead4B(TX_FAIL)
231 #define TX_FAIL_SOURCE() (RegReadFldAlign(TX_FAIL, SOURCE))
232 #define CLR_TX_FAIL_SOURCE() vRegWriteFldAlign(TX_FAIL, 0, SOURCE)
233 #define CHECK_RX_EN() (RegReadFldAlign(TR_CONFIG, RX_EN))
235 #define SET_LA1(La1) vRegWriteFldAlign(TR_CONFIG, La1, DEVICE_ADDR)
236 #define SET_LA2(La2) vRegWriteFldAlign(TR_CONFIG, La2, TR_DEVICE_ADDR2)
237 #define SET_LA3(La3) vRegWriteFldAlign(TR_CONFIG, La3, TR_DEVICE_ADDR3)
241 #define RESET_HW_TX() \
247 #define GET_TX_BIT_COUNTER() (RegReadFldAlign(TX_STATUS, TX_BIT_COUNTER))
249 unsigned int IS_HDMI_HTPLG(void)
251 return (RegReadFldAlign(RX_EVENT
, HDMI_HTPLG
));
254 unsigned int IS_HDMI_PORD(void)
256 return (RegReadFldAlign(RX_EVENT
, HDMI_PORD
));
259 void vClear_cec_irq(void)
261 //27mhz, clear HPD/PORT and cec int
262 vRegWriteFldAlign(TR_CONFIG
, 1, CLEAR_CEC_IRQ
);
264 vRegWriteFldAlign(TR_CONFIG
, 0, CLEAR_CEC_IRQ
);
266 //32khz, clear HPD/PORT and CEC RX int
267 vRegWriteFldAlign(RX_GEN_WD
, 1, HDMI_PORD_INT_CLR
);
268 vRegWriteFldAlign(RX_GEN_WD
, 1, RX_INT_CLR
);
269 vRegWriteFldAlign(RX_GEN_WD
, 1, HDMI_HTPLG_INT_CLR
);
273 void vCec_pdn_32k(void)
275 vRegWriteFldAlign(CEC_CKGEN
, 1, CEC_32K_PDN
);
277 vRegWriteFldAlign(RX_GEN_WD
, 1, HDMI_PORD_INT_CLR
);
278 vRegWriteFldAlign(RX_GEN_WD
, 1, RX_INT_CLR
);
279 vRegWriteFldAlign(RX_GEN_WD
, 1, HDMI_HTPLG_INT_CLR
);
281 vRegWriteFldAlign(RX_GEN_WD
, 0, HDMI_PORD_INT_CLR
);
282 vRegWriteFldAlign(RX_GEN_WD
, 0, RX_INT_CLR
);
283 vRegWriteFldAlign(RX_GEN_WD
, 0, HDMI_HTPLG_INT_CLR
);
285 vRegWriteFldAlign(RX_GEN_WD
, 0, HDMI_PORD_INT_32K_EN
);
286 vRegWriteFldAlign(RX_GEN_WD
, 0, RX_INT_32K_EN
);
287 vRegWriteFldAlign(RX_GEN_WD
, 0, HDMI_HTPLG_INT_32K_EN
);
291 void vEnable_hotplug_pord_int(unsigned char u1enable
)
295 vRegWriteFldAlign(RX_EVENT
, 1, HDMI_PORD_INT_EN
);
296 vRegWriteFldAlign(RX_EVENT
, 1, HDMI_HTPLG_INT_EN
);
300 vRegWriteFldAlign(RX_EVENT
, 0, HDMI_PORD_INT_EN
);
301 vRegWriteFldAlign(RX_EVENT
, 0, HDMI_HTPLG_INT_EN
);
304 void vRegWrite4BMsk(unsigned short reg16
, unsigned int val32
, unsigned int msk32
)
308 hdmi_cec_write(reg16
, ((hdmi_cec_read(reg16
))&~msk32
)|val32
);
311 /*----------------------------------------------------------------------------*/
313 void internal_cec_read(unsigned int u4Reg
, unsigned int *p4Data
)
315 *p4Data
= (*(volatile unsigned int*)(u4Reg
));
318 void internal_cec_write(unsigned int u4Reg
, unsigned int u4data
)
320 *(volatile unsigned int*)(u4Reg
) = (u4data
);
323 unsigned int hdmi_cec_read(unsigned short u2Reg
)
326 internal_cec_read(HDMICEC_BASE
+u2Reg
, &u4Data
);
328 //HDMI_CEC_LOG("[R]cec = 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
332 void hdmi_cec_write(unsigned short u2Reg
, unsigned int u4Data
)
334 internal_cec_write(HDMICEC_BASE
+u2Reg
, u4Data
);
336 //HDMI_CEC_LOG("[W]cec= 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
340 unsigned int hdmi_cec_2n(unsigned int u4Data
)
342 unsigned int u4resultvalue
=1;
343 unsigned char u1number
;
345 if(u4Data
==0) return 0; //must be not 0
346 if(u4Data
==0x20) return 0xffffffff;
347 if(u4Data
>0x20) return 0; //must not exceed over 0x20
349 for(u1number
=0; u1number
<u4Data
; u1number
++)
353 //HDMI_CEC_LOG("hdmi_cec_2n data = 0x%08x\n", u4resultvalue-1);
355 return (u4resultvalue
-1);
358 u32
hdmi_cec_maskvalue(unsigned int u4Width
, unsigned int u4Startbit
)
360 unsigned int u4Data
=0xffffffff, i
;
362 for(i
=0; i
<u4Width
; i
++)
364 u4Data
&=(~(hdmi_cec_2n(u4Startbit
+i
)+1));
366 //HDMI_CEC_LOG("hdmi_cec_maskvalue data = 0x%08x\n", u4Data);
370 /*----------------------------------------------------------------------------*/
372 void vRegWrite4B(unsigned short u2Reg
, unsigned int u4Data
)
375 hdmi_cec_write(u2Reg
, u4Data
);
378 void hdmi_cec_init(void)
381 cec_msg_report_pending
= 0;
383 _rCECPhysicAddr
.ui2_pa
= 0xffff;
384 _rCECPhysicAddr
.ui1_la
= 0x0;
388 _u1TxFailCause
= FAIL_NONE
;
390 CEC_rxQ_write_idx
= 0;
391 CEC_rxQ_read_idx
= 0;
392 CEC_txQ_write_idx
= 0;
393 CEC_txQ_read_idx
= 0;
395 _rCECLaAddr
.aui1_la
[0] = 0x0F;
396 _rCECLaAddr
.aui1_la
[1] = 0x0F;
397 _rCECLaAddr
.aui1_la
[2] = 0x0F;
401 vRegWrite4B(CEC_CKGEN, 0x00040082); //3MHz //different from BD /100k
402 vRegWrite4B(TR_TEST, 0x40004010);// Bpad enable¡BTx compared timing 0x19
404 // CYJ.NOTE TX_EN, RX_EN: disable it
405 vRegWrite4B(TR_CONFIG, 0x00000001);
407 vRegWrite4B(RX_T_START_R, 0x007d0070);
408 vRegWrite4B(RX_T_START_F, 0x0099008a);
409 vRegWrite4B(RX_T_DATA, 0x00230040);
410 vRegWrite4B(RX_T_ACK, 0x00000030);
411 vRegWrite4B(RX_T_ERROR, 0x007300aa);
412 vRegWrite4B(TX_T_START, 0x00900076);
413 vRegWrite4B(TX_T_DATA_R, 0x00130030);
414 vRegWrite4B(TX_T_DATA_F, 0x004d004d);
415 vRegWrite4B(TX_ARB, 0x00000596);
419 vRegWrite4B(CEC_CKGEN
, 0x000a0082); //3MHz //different from BD /100k
420 vRegWrite4B(TR_TEST
, 0x40004019);// Bpad enable¡BTx compared timing 0x19
422 // CYJ.NOTE TX_EN, RX_EN: disable it
423 vRegWrite4B(TR_CONFIG
, 0x00000001);
425 vRegWrite4B(RX_T_START_R
, 0x01980154);
426 vRegWrite4B(RX_T_START_F
, 0x01e801a9);
427 vRegWrite4B(RX_T_DATA
, 0x006e00c8);
428 vRegWrite4B(RX_T_ACK
, 0x00000096);
429 vRegWrite4B(RX_T_ERROR
, 0x01680212);
430 vRegWrite4B(TX_T_START
, 0x01c20172);
431 vRegWrite4B(TX_T_DATA_R
, 0x003c0096);
432 vRegWrite4B(TX_T_DATA_F
, 0x00f000f0);
433 vRegWrite4B(TX_ARB
, 0x00000596);
435 // turn off interrupt of general mode
436 vRegWrite4B(TX_GEN_INTR
, 0x00000000);
437 vRegWrite4B(RX_CAP_90
, 0x00000000);
438 vRegWrite4B(TX_GEN_MASK
, 0x00000000);
439 vRegWrite4B(RX_GEN_WD
, 0x00000000);
440 vRegWrite4B(RX_GEN_MASK
, 0x00000000);
441 vRegWrite4B(RX_GEN_INTR
, 0x00000000);
445 vRegWriteFldAlign(TX_HD_NEXT
, 0, WTX_M3_ID
);
446 vRegWriteFldAlign(TX_HD_NEXT
, 0, WTX_M1_DIR
);
447 vRegWriteFldAlign(TX_HD_NEXT
, 0, WTX_M1_PAS
);
448 vRegWriteFldAlign(TX_HD_NEXT
, 0, WTX_M1_NAS
);
449 vRegWriteFldAlign(TX_HD_NEXT
, 0, WTX_M1_DES
);
450 vRegWriteFldAlign(TX_HD_NEXT
, 3, WTX_MODE
);
452 vRegWrite4B(TR_CONFIG
, 0x8fff1101);
454 vRegWrite4BMsk(TX_EVENT
, 0x00, 0xff);
455 vRegWrite4BMsk(RX_EVENT
, 0x00, 0xff);
458 ENABLE_INT_BR_RDY(1);
459 ENABLE_INT_HEADER_RDY(1);
474 void hdmi_cec_power_on(unsigned char pwr
)
480 vRegWriteFldAlign(CEC_CKGEN
,1,PDN
);
484 vRegWriteFldAlign(CEC_CKGEN
,0,PDN
);
487 static unsigned char CEC_rx_enqueue(CEC_FRAME_DESCRIPTION
* frame
)
489 /* check if queue is full */
496 /* copy the new incoming message to rx queue */
497 memcpy(&(CEC_rx_msg_queue
[CEC_rxQ_write_idx
]), frame
, sizeof(CEC_FRAME_DESCRIPTION
));
498 // CYJ.NOTE: no critical section
499 CEC_rxQ_write_idx
= (CEC_rxQ_write_idx
+ 1) % RX_Q_SIZE
;
504 static void _CEC_Receiving(void)
506 static unsigned char* size
;
507 static CEC_FRAME_DESCRIPTION
* frame
= &ActiveRXFrame
;
509 unsigned char i
, rxlen
, is_d_eom
, ret
;
520 // <polling message> only
521 if(GET_HW_RX_LEN() == 0)
523 NOTIFY_RX_HW_DATA_TAKEN();
524 ClrCECStatus(STATE_RX_GET_NEW_HEADER
); //CM 20081210
528 /* new incoming message */
529 if (IsCECStatus(STATE_RX_GET_NEW_HEADER
))
531 ClrCECStatus(STATE_RX_GET_NEW_HEADER
);
532 if (IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE
))
534 HDMI_CEC_LOG("Lost EOM:2\n");
535 SetCECErrorFlag(ERR_RX_LOST_EOM
);
537 SetCECStatus(STATE_WAIT_RX_FRAME_COMPLETE
);
539 size
= &(frame
->size
);
541 frame
->blocks
.header
.initiator
= GET_SRC_FIELD();
542 frame
->blocks
.header
.destination
= GET_DST_FIELD();
546 if (!IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE
))
548 NOTIFY_RX_HW_DATA_TAKEN();
549 SetCECErrorFlag(ERR_RX_LOST_HEADER
);
553 rxlen
= GET_HW_RX_LEN();
554 data
= GET_HW_RX_DATA();
555 is_d_eom
= IS_RX_D_EOM();
556 NOTIFY_RX_HW_DATA_TAKEN();
562 else if (rxlen
== 0x7)
566 else if (rxlen
== 0xf)
570 else if (rxlen
!= 0x1)
572 HDMI_CEC_LOG("invalid rx length occurs\n");
579 frame
->blocks
.opcode
= data
& 0xff;
586 for (i
=0; i
<rxlen
; i
++)
591 HDMI_CEC_LOG("Receive Data Length is wrong ! \n");
596 ASSERT((*size
) >= 2);
597 frame
->blocks
.operand
[(*size
)-2] = data
& 0xff;
605 ClrCECStatus(STATE_WAIT_RX_FRAME_COMPLETE
);
606 SetCECStatus(STATE_RX_COMPLETE_NEW_FRAME
);
608 /* push into rx_queue */
609 ret
= CEC_rx_enqueue(frame
);
612 SetCECErrorFlag(ERR_RXQ_OVERFLOW
);
613 HDMI_CEC_LOG("cec rx buffer overflow\n");
619 static unsigned char _CEC_SendRemainingDataBlocks(void)
621 CEC_FRAME_DESCRIPTION
*frame
;
622 unsigned char errcode
= 0;
624 unsigned char* sendidx
;
625 unsigned char* blocks
;
630 if (!IsCECStatus(STATE_TXING_FRAME
))
635 if (IsCECStatus(STATE_WAIT_TX_DATA_TAKEN
))
637 if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN())
639 ClrCECStatus(STATE_WAIT_TX_DATA_TAKEN
);
643 // tx buffer is not emply
652 /* request current active TX frame */
653 frame
= ActiveTXFrame
;
656 sendidx
= &(frame
->sendidx
);
657 blocks
= &(frame
->blocks
.opcode
);
659 // CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop
660 if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD()>0))
662 HDMI_CEC_LOG("Detect TX FAIL in %s\n", __FUNCTION__
);
668 size
-= ((*sendidx
)+1);
675 /* CYJ:TODO duplicate (as _CEC_SendFrame())! */
709 for (i
=0,j
=size
; i
<4; i
++)
712 data
|= (blocks
[(*sendidx
)]) << 24;
737 SetCECStatus(STATE_WAIT_TX_DATA_TAKEN
);
741 HDMI_CEC_LOG("TRIGGER_TX_HW in %s, size: %x\n", __FUNCTION__
, size
);
750 static void _CEC_Check_Active_Tx_Result(void)
754 if (IsCECStatus(STATE_TXING_FRAME
))
756 if (IsCECStatus(STATE_HW_RETX
))
758 if (TX_FAIL_SOURCE())
760 _u1TxFailCause
= FAIL_SOURCE
;
761 CLR_TX_FAIL_SOURCE();
763 if ((TX_FAIL_RECORD()!=0))
765 DISABLE_ALL_TX_INT();
767 SetCECStatus(STATE_TX_NOACK
);
768 ClrCECStatus(STATE_HW_RETX
);
770 ClrCECStatus(STATE_TXING_FRAME
);
771 if (IS_TX_FSM_FAIL())
773 HDMI_CEC_LOG( "TX NO ACK\n");
777 HDMI_CEC_LOG( "other TX error\n");
779 HDMI_CEC_LOG( "H ACK: %x, D ACK: %x\n", GET_FOLLOWER_H_ACK(), GET_FOLLOWER_D_ACK());
784 else if ((ActiveTXFrame
->sendidx
+1) == (ActiveTXFrame
->size
))
787 if (IS_TX_FSM_IDLE() && IS_TX_FINISH())
789 DISABLE_ALL_TX_INT();
790 SetCECStatus(STATE_TX_FRAME_SUCCESS
);
791 ClrCECStatus(STATE_TXING_FRAME
);
792 HDMI_CEC_LOG( "TX is COMPLETED with: H ACK: %x and D ACK %x\n", (unsigned int)GET_FOLLOWER_H_ACK(), (unsigned int)GET_FOLLOWER_D_ACK());
799 static CEC_FRAME_DESCRIPTION
* _CEC_Get_Cur_TX_Q_Msg(void)
808 return (&(CEC_tx_msg_queue
[CEC_txQ_read_idx
]));
811 static unsigned char _CEC_TX_Dequeue(void)
820 // CYJ.NOTE: no critical section
821 CEC_txQ_read_idx
= (CEC_txQ_read_idx
+ 1) % TX_Q_SIZE
;
825 static void _CEC_tx_msg_notify(UINT8 result
, void* tag
)
829 HDMI_CEC_LOG("cec tx result ok\n");
830 cec_send_result
.pv_tag
= tag
;
831 cec_send_result
.e_ack_cond
= CEC_ACK_COND_OK
;
832 vNotifyAppHdmiCecState(HDMI_CEC_TX_STATUS
);
834 else if (result
== 0x01)
836 HDMI_CEC_LOG("cec tx result fail\n");
837 cec_send_result
.pv_tag
= tag
;
838 cec_send_result
.e_ack_cond
= CEC_ACK_COND_NO_RESPONSE
;
839 vNotifyAppHdmiCecState(HDMI_CEC_TX_STATUS
);
842 void hdmi_cec_api_get_txsts(CEC_ACK_INFO_T
*pt
)
844 memcpy(pt
,&cec_send_result
,sizeof(CEC_ACK_INFO_T
));
846 static void vApiNotifyCECDataArrival(CEC_FRAME_DESCRIPTION
* frame
)
848 cec_receive_msg
= frame
;
849 vNotifyAppHdmiCecState(HDMI_CEC_GET_CMD
);
851 static void PrintFrameDescription(CEC_FRAME_DESCRIPTION
* frame
)
855 HDMI_CEC_LOG(">>>>>>>>>>>>>>>>>>>>>>>>\n");
856 HDMI_CEC_LOG("frame description:\n");
857 HDMI_CEC_LOG("size: 0x%x\n", frame
->size
);
858 HDMI_CEC_LOG("sendidx: 0x%x\n", frame
->sendidx
);
859 HDMI_CEC_LOG("reTXcnt: 0x%x\n", frame
->reTXcnt
);
860 HDMI_CEC_LOG("initiator: 0x%x\n", frame
->blocks
.header
.initiator
);
861 HDMI_CEC_LOG("destination: 0x%x\n", frame
->blocks
.header
.destination
);
864 HDMI_CEC_LOG("opcode: 0x%x\n", frame
->blocks
.opcode
);
866 if ((frame
->size
> 2)&& (frame
->size
<= 16))
868 for (i
=0; i
<(frame
->size
-2); i
++)
870 HDMI_CEC_LOG("0x%02x \n", frame
->blocks
.operand
[i
]);
873 HDMI_CEC_LOG("<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
876 static unsigned char _CEC_SendFrame(CEC_FRAME_DESCRIPTION
* frame
)
878 unsigned char errcode
= 0;
880 unsigned char* sendidx
;
881 unsigned char* blocks
;
886 if (IsCECStatus(STATE_TXING_FRAME
))
890 SetCECStatus(STATE_TXING_FRAME
);
892 // CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop
893 if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD()>0))
895 HDMI_CEC_LOG("Detect TX FAIL in %s\n", __FUNCTION__
);
898 // ASSERT(0); // CAN NOT HAPPEN HERE
902 sendidx
= &(frame
->sendidx
);
903 blocks
= &(frame
->blocks
.opcode
);
907 ClrCECStatus(STATE_TXING_FRAME
);
912 ClrCECStatus(STATE_TXING_FRAME
);
916 // CYJ.NOTE: TX HW is not idle
917 if (!IS_TX_FSM_IDLE())
921 ActiveTXFrame
= frame
;
923 ClrCECStatus(STATE_TX_FRAME_SUCCESS
);
924 ClrCECStatus(STATE_TX_NOACK
);
928 FILL_SRC_FIELD(frame
->blocks
.header
.initiator
);
929 FILL_DST_FIELD(frame
->blocks
.header
.destination
);
975 for (i
=0, j
=size
; i
<4; i
++)
978 data
|= (blocks
[(*sendidx
)]) << 24;
1003 SetCECStatus(STATE_WAIT_TX_DATA_TAKEN
);
1007 HDMI_CEC_LOG("TRIGGER_TX_HW in %s, size: %x\n", __FUNCTION__
, size
);
1010 _u1TxFailCause
= FAIL_NONE
;
1017 static void _CEC_TX_Queue_Loop(void)
1019 CEC_FRAME_DESCRIPTION
* frame
;
1022 /* if the tx message queue is empty */
1023 if (IS_TX_Q_EMPTY())
1028 /* if the tx is active, check the result */
1029 if (IsCECStatus(STATE_TXING_FRAME
))
1031 if(IsCECErrorFlag(ERR_TX_MISALARM
)&& (TX_FAIL_RECORD()!=0)&& IS_TX_FSM_FAIL())
1033 DISABLE_ALL_TX_INT();
1034 ClrCECErrorFlag(ERR_TX_MISALARM
);
1035 SetCECStatus(STATE_TX_NOACK
);
1036 ClrCECStatus(STATE_HW_RETX
);
1037 ClrCECStatus(STATE_TXING_FRAME
);
1041 _CEC_Check_Active_Tx_Result();
1042 if (IsCECStatus(STATE_TX_FRAME_SUCCESS
))
1044 HDMI_CEC_LOG( "This message is successful\n");
1045 frame
= _CEC_Get_Cur_TX_Q_Msg();
1050 _CEC_tx_msg_notify(0x00, frame
->txtag
);
1052 ClrCECStatus(STATE_TX_FRAME_SUCCESS
);
1054 if (IsCECStatus(STATE_TX_NOACK
))
1056 frame
= _CEC_Get_Cur_TX_Q_Msg();
1061 HDMI_CEC_LOG( "This message is failed: %d\n", frame
->reTXcnt
);
1064 ClrCECStatus(STATE_TX_NOACK
);
1065 // CYJ.NOTE: retransmission
1066 if (frame
->reTXcnt
== RETX_MAX_CNT
)
1068 _u1TxFailCause
= FAIL_NONE
;
1069 HDMI_CEC_LOG( "ReTX reach MAX\n");
1070 _CEC_tx_msg_notify(0x01, frame
->txtag
);
1076 /* if the tx is not active, send the next message */
1078 frame
= _CEC_Get_Cur_TX_Q_Msg();
1083 if (_u1TxFailCause
== FAIL_SOURCE
)
1085 if (_u1ReTxCnt
< 15)
1095 HDMI_CEC_LOG( "Send a new message\n");
1096 PrintFrameDescription(frame
);
1097 _CEC_SendFrame(frame
);
1101 static CEC_FRAME_DESCRIPTION
* CEC_rx_dequeue(void)
1103 CEC_FRAME_DESCRIPTION
* ret
;
1106 /* check if queue is empty */
1107 if (IS_RX_Q_EMPTY())
1112 /* return next available entry for middleware */
1113 ret
= &(CEC_rx_msg_queue
[CEC_rxQ_read_idx
]);
1115 // CYJ.NOTE: no critical section
1116 CEC_rxQ_read_idx
= (CEC_rxQ_read_idx
+ 1) % RX_Q_SIZE
;
1121 static unsigned char CEC_frame_validation(CEC_FRAME_DESCRIPTION
* frame
)
1123 unsigned char size
= frame
->size
;
1124 unsigned char i1ret
= TRUE
;
1128 /* CYJ.NOTE: code size issue */
1129 switch (frame
->blocks
.opcode
)
1132 case OPCODE_IMAGE_VIEW_ON
:
1133 case OPCODE_TEXT_VIEW_ON
:
1134 case OPCODE_REQUEST_ACTIVE_SOURCE
:
1135 case OPCODE_STANDBY
:
1136 case OPCODE_RECORD_OFF
:
1137 case OPCODE_RECORD_TV_SCREEN
:
1138 case OPCODE_GET_CEC_VERSION
:
1139 case OPCODE_GIVE_PHYSICAL_ADDRESS
:
1140 case OPCODE_GET_MENU_LANGUAGE
:
1141 case OPCODE_TUNER_STEP_DECREMENT
:
1142 case OPCODE_TUNER_STEP_INCREMENT
:
1143 case OPCODE_GIVE_DEVICE_VENDOR_ID
:
1144 case OPCODE_VENDOR_REMOTE_BUTTON_UP
:
1145 case OPCODE_GIVE_OSD_NAME
:
1146 case OPCODE_USER_CONTROL_RELEASED
:
1147 case OPCODE_GIVE_DEVICE_POWER_STATUS
:
1149 case OPCODE_GIVE_AUDIO_STATUS
:
1150 case OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS
:
1156 case OPCODE_SYSTEM_AUDIO_MODE_REQUEST
:
1157 if ((size
!= 2) && (size
!= 4))
1163 case OPCODE_RECORD_STATUS
:
1164 case OPCODE_TIMER_CLEARED_STATUS
:
1165 case OPCODE_CEC_VERSION
:
1166 case OPCODE_DECK_CONTROL
:
1167 case OPCODE_DECK_STATUS
:
1168 case OPCODE_GIVE_DECK_STATUS
:
1170 case OPCODE_GIVE_TUNER_DEVICE_STATUS
:
1171 case OPCODE_MENU_REQUEST
:
1172 case OPCODE_MENU_STATUS
:
1173 case OPCODE_REPORT_POWER_STATUS
:
1174 case OPCODE_REPORT_AUDIO_STATUS
:
1175 case OPCODE_SET_SYSTEM_AUDIO_MODE
:
1176 case OPCODE_SYSTEM_AUDIO_MODE_STATUS
:
1177 case OPCODE_SET_AUDIO_RATE
:
1183 case OPCODE_USER_CONTROL_PRESSED
:
1184 if ((size
!= 3) && (size
!= 4))
1190 case OPCODE_ACTIVE_SOURCE
:
1191 case OPCODE_INACTIVE_SOURCE
:
1192 case OPCODE_ROUTING_INFORMATION
:
1193 case OPCODE_SET_STREAM_PATH
:
1194 case OPCODE_FEATURE_ABORT
:
1201 case OPCODE_REPORT_PHYSICAL_ADDRESS
:
1202 case OPCODE_SET_MENU_LANGUAGE
:
1203 case OPCODE_DEVICE_VENDOR_ID
:
1210 case OPCODE_ROUTING_CHANGE
:
1211 case OPCODE_SELECT_ANALOGUE_SERVICE
:
1218 case OPCODE_SELECT_DIGITAL_SERVICE
:
1225 case OPCODE_CLEAR_ANALOGUE_TIMER
:
1226 case OPCODE_SET_ANALOGUE_TIMER
:
1233 case OPCODE_CLEAR_DIGITAL_TIMER
:
1234 case OPCODE_SET_DIGITAL_TIMER
:
1240 case OPCODE_RECORD_ON
:
1241 if ((size
< 3) || (size
> 10))
1246 // length == 10 ~ 11
1247 case OPCODE_CLEAR_EXTERNAL_TIMER
:
1248 case OPCODE_SET_EXTERNAL_TIMER
:
1249 if ((size
< 10) || (size
> 11))
1254 case OPCODE_TIMER_STATUS
:
1255 if ((size
!= 3) && (size
!= 5))
1260 case OPCODE_TUNER_DEVICE_STATUS
:
1261 if ((size
!= 7) && (size
!= 10))
1266 case OPCODE_VENDOR_COMMAND
:
1267 case OPCODE_VENDOR_COMMAND_WITH_ID
:
1268 case OPCODE_VENDOR_REMOTE_BUTTON_DOWN
:
1274 case OPCODE_SET_OSD_STRING
:
1275 if ((size
<3) || (size
>16))
1280 case OPCODE_SET_TIMER_PROGRAM_TITLE
:
1281 case OPCODE_SET_OSD_NAME
:
1282 if ((size
<3) || (size
>16))
1290 HDMI_CEC_LOG( "receive invalid frame: %x\n", frame
->blocks
.opcode
);
1291 PrintFrameDescription(frame
);
1296 static unsigned char check_and_init_tx_frame(CEC_FRAME_DESCRIPTION
* frame
)
1298 unsigned char ret
= 0x00;
1301 if ((frame
->size
> CEC_MAX_MESG_SIZE
) || (frame
->size
== 0))
1303 HDMI_CEC_LOG("Tx fram size is not correct \n");
1317 unsigned char _CEC_TX_Enqueue(CEC_FRAME_DESCRIPTION
* frame
)
1320 if (frame
->size
==1)
1322 HDMI_CEC_LOG("Polling LA = 0x%x \n" , (unsigned char)((frame
->blocks
.header
.initiator
<< 4) | frame
->blocks
.header
.destination
));
1326 HDMI_CEC_LOG("Opcode = 0x%x, size = 0x%x \n" , frame
->blocks
.opcode
, frame
->size
);
1330 if (check_and_init_tx_frame(frame
))
1337 HDMI_CEC_LOG("Tx queue is full \n");
1341 memcpy(&(CEC_tx_msg_queue
[CEC_txQ_write_idx
]), frame
, sizeof(CEC_FRAME_DESCRIPTION
));
1342 // CYJ.NOTE: no critical section
1343 CEC_txQ_write_idx
= (CEC_txQ_write_idx
+ 1) % TX_Q_SIZE
;
1348 void hdmi_u4CecSendSLTData(unsigned char *pu1Data
)
1356 CTSTestFrame
.size
= *pu1Data
+ 2;
1357 CTSTestFrame
.sendidx
= 0;
1358 CTSTestFrame
.reTXcnt
= 0;
1359 CTSTestFrame
.txtag
= NULL
;
1360 CTSTestFrame
.blocks
.header
.destination
= 0x00;
1361 CTSTestFrame
.blocks
.header
.initiator
= 0x04;
1362 CTSTestFrame
.blocks
.opcode
= 0x01;
1363 for(i
= 0; i
< *pu1Data
; i
++)
1365 CTSTestFrame
.blocks
.operand
[i
] = *(pu1Data
+ i
+ 1);
1367 _CEC_TX_Enqueue(&CTSTestFrame
);
1371 void hdmi_GetSLTData(CEC_SLT_DATA
* rCecSltData
)
1374 CEC_FRAME_DESCRIPTION
* frame
;
1377 frame
= CEC_rx_dequeue();
1381 rCecSltData
->u1Size
= 5;
1382 for(i
= 0; i
< rCecSltData
->u1Size
; i
++)
1384 rCecSltData
->au1Data
[i
] = i
;
1386 ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME
);
1390 if(frame
->blocks
.opcode
== 0x01)
1392 if (CEC_frame_validation(frame
))
1394 PrintFrameDescription(frame
);
1397 rCecSltData
->u1Size
= frame
->size
- 2;
1398 if (rCecSltData
->u1Size
> 14)
1400 rCecSltData
->u1Size
= 14;
1402 for(i
= 0; i
< rCecSltData
->u1Size
; i
++)
1404 rCecSltData
->au1Data
[i
] = frame
->blocks
.operand
[i
];
1406 HDMI_CEC_LOG("[CEC SLT] Receive data \n");
1407 HDMI_CEC_LOG("[CEC SLT] size = 0x%x \n", rCecSltData
->u1Size
);
1408 HDMI_CEC_LOG("[CEC SLT] data = ");
1410 for(i
= 0; i
< rCecSltData
->u1Size
; i
++)
1412 HDMI_CEC_LOG(" 0x%x ", rCecSltData
->au1Data
[i
]);
1414 HDMI_CEC_LOG(" \n");
1418 void CTS_RXProcess(CEC_FRAME_DESCRIPTION
* frame
)
1422 if (frame
->blocks
.opcode
== OPCODE_ABORT
)
1424 CTSTestFrame
.size
= 4;
1425 CTSTestFrame
.sendidx
= 0;
1426 CTSTestFrame
.reTXcnt
= 0;
1427 CTSTestFrame
.txtag
= NULL
;
1428 CTSTestFrame
.blocks
.header
.destination
= frame
->blocks
.header
.initiator
;
1429 CTSTestFrame
.blocks
.header
.initiator
= 4;
1430 CTSTestFrame
.blocks
.opcode
= OPCODE_FEATURE_ABORT
;
1431 CTSTestFrame
.blocks
.operand
[0] = OPCODE_ABORT
;
1432 CTSTestFrame
.blocks
.operand
[1] = 4;
1434 /////////////////////// Test//////////////////////////////////
1435 CTSTestFrame
.blocks
.operand
[2] = 0x41;
1436 CTSTestFrame
.blocks
.operand
[3] = 0x0;
1437 CTSTestFrame
.blocks
.operand
[4] = 0xff;
1438 CTSTestFrame
.blocks
.operand
[5] = 4;
1439 CTSTestFrame
.blocks
.operand
[6] = 0x41;
1440 CTSTestFrame
.blocks
.operand
[7] = 0x0;
1441 CTSTestFrame
.blocks
.operand
[8] = 0xff;
1442 CTSTestFrame
.blocks
.operand
[9] = 4;
1443 CTSTestFrame
.blocks
.operand
[10] = 10;
1444 CTSTestFrame
.blocks
.operand
[11] = 11;
1445 CTSTestFrame
.blocks
.operand
[12] = 12;
1446 CTSTestFrame
.blocks
.operand
[13] = 13;
1447 ///////////////////////Test////////////////////////////////////
1449 _CEC_TX_Enqueue(&CTSTestFrame
);
1450 HDMI_CEC_LOG ("CTS Send: OPCODE_FEATURE_ABORT\n");
1452 else if (frame
->blocks
.opcode
== OPCODE_GIVE_PHYSICAL_ADDRESS
)
1454 CTSTestFrame
.size
= 5;
1455 CTSTestFrame
.sendidx
= 0;
1456 CTSTestFrame
.reTXcnt
= 0;
1457 CTSTestFrame
.txtag
= NULL
;
1458 CTSTestFrame
.blocks
.header
.destination
= 0xf;
1459 CTSTestFrame
.blocks
.header
.initiator
= 4;
1460 CTSTestFrame
.blocks
.opcode
= OPCODE_REPORT_PHYSICAL_ADDRESS
;
1461 CTSTestFrame
.blocks
.operand
[0] = 0x10;
1462 CTSTestFrame
.blocks
.operand
[1] = 0x00;
1463 CTSTestFrame
.blocks
.operand
[2] = 0x04;
1465 _CEC_TX_Enqueue(&CTSTestFrame
);
1466 HDMI_CEC_LOG( "CTS Send: OPCODE_REPORT_PHYSICAL_ADDRESS\n");
1470 static void CEC_rx_msg_notify(unsigned char u1rxmode
)
1472 CEC_FRAME_DESCRIPTION
* frame
;
1474 if(u1rxmode
==CEC_SLT_MODE
)
1477 //if(u1rxmode==CEC_NORMAL_MODE)
1482 if(cec_msg_report_pending
== 1)
1484 //HDMI_CEC_LOG("wait user get cmd\n");
1488 frame
= CEC_rx_dequeue();
1492 ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME
);
1496 if (CEC_frame_validation(frame
))
1498 HDMI_CEC_LOG ("Receive message\n");
1499 PrintFrameDescription(frame
);
1500 vApiNotifyCECDataArrival(frame
);
1501 cec_msg_report_pending
= 1;
1502 if(u1rxmode
==CEC_CTS_MODE
)
1504 CTS_RXProcess(frame
);
1510 void hdmi_cec_mainloop(unsigned char u1rxmode
)
1513 _CEC_TX_Queue_Loop();
1515 // NOTE: the priority between tx and rx
1516 if (!IsCECStatus(STATE_TXING_FRAME
))
1518 CEC_rx_msg_notify(u1rxmode
);
1523 unsigned char hdmi_cec_isrprocess(unsigned char u1rxmode
)
1525 unsigned char u1ReceivedDst
;
1527 if (HW_RX_HEADER_ARRIVED())
1529 u1ReceivedDst
= GET_DST_FIELD_RECEIVING();
1530 HDMI_CEC_LOG( "u1ReceivedDst = 0x%08x\n", u1ReceivedDst
);
1531 if(u1rxmode
==CEC_CTS_MODE
) _rCECLaAddr
.aui1_la
[0] = 4;
1532 if ((u1ReceivedDst
== _rCECLaAddr
.aui1_la
[0]) || (u1ReceivedDst
== _rCECLaAddr
.aui1_la
[1]) ||
1533 (u1ReceivedDst
== _rCECLaAddr
.aui1_la
[2]) || (u1ReceivedDst
== 0xf))
1535 HDMI_CEC_LOG( "RX:H\n");
1536 if (IsCECStatus(STATE_RX_GET_NEW_HEADER
))
1538 HDMI_CEC_LOG("Lost EOM:1\n");
1539 SetCECErrorFlag(ERR_RX_LOST_EOM
);
1541 SetCECStatus(STATE_RX_GET_NEW_HEADER
);
1545 ClrCECStatus(STATE_RX_GET_NEW_HEADER
);
1546 HDMI_CEC_LOG("RX:H False\n");
1549 if (HW_RX_DATA_ARRIVED())
1551 HDMI_CEC_LOG("RX:D\n");
1556 HDMI_CEC_LOG("Overflow\n");
1558 SetCECStatus(STATE_HW_RX_OVERFLOW
);
1562 if (IsCECStatus(STATE_TXING_FRAME
))
1566 HDMI_CEC_LOG( "Underrun\n");
1568 SetCECErrorFlag(ERR_TX_UNDERRUN
);
1572 HDMI_CEC_LOG( "Buffer Low\n");
1574 if (!IS_INT_RB_RDY())
1576 HDMI_CEC_LOG( "FW is slow to trigger the following blocks\n");
1577 SetCECErrorFlag(ERR_TX_BUFFER_LOW
);
1580 if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN())
1582 HDMI_CEC_LOG("TX Data Taken\n");
1583 _CEC_SendRemainingDataBlocks();
1585 // CYJ.NOTE TX Failure Detection
1586 if (IS_INT_FAIL_ENABLE() && (TX_FAIL_RECORD()!=0))
1588 DISABLE_ALL_TX_INT();
1589 SetCECStatus(STATE_HW_RETX
);
1591 if (TX_FAIL_MAX()|IS_TX_FSM_FAIL())
1593 HDMI_CEC_LOG("TX Fail: %x\n", TX_FAIL_RECORD());
1594 HDMI_CEC_LOG("TX Fail MAX\n");
1598 HDMI_CEC_LOG("TX Fail: %x\n", TX_FAIL_RECORD());
1601 HDMI_CEC_LOG("TX HW FSM: %x\n", TX_FSM_STATUS());
1604 if (IS_RX_Q_EMPTY())
1610 void CECMWSetLA(CEC_LA_ADDRESS
* prLA
)
1614 memcpy(&_rCECLaAddr
, prLA
, sizeof(CEC_LA_ADDRESS
));
1616 ASSERT(_rCECLaAddr
.ui1_num
<= 3);
1618 if (_rCECLaAddr
.ui1_num
== 0)
1623 _rCECLaAddr
.aui1_la
[0] = 0x0F;
1624 _rCECLaAddr
.aui1_la
[1] = 0x0F;
1625 _rCECLaAddr
.aui1_la
[2] = 0x0F;
1627 else if (_rCECLaAddr
.ui1_num
== 1)
1631 SET_LA1(_rCECLaAddr
.aui1_la
[0]);
1632 _rCECLaAddr
.aui1_la
[1] = 0x0F;
1633 _rCECLaAddr
.aui1_la
[2] = 0x0F;
1635 else if (_rCECLaAddr
.ui1_num
== 2)
1638 SET_LA2(_rCECLaAddr
.aui1_la
[1]);
1639 SET_LA1(_rCECLaAddr
.aui1_la
[0]);
1640 _rCECLaAddr
.aui1_la
[2] = 0x0F;
1642 else if (_rCECLaAddr
.ui1_num
== 3)
1644 SET_LA3(_rCECLaAddr
.aui1_la
[2]);
1645 SET_LA2(_rCECLaAddr
.aui1_la
[1]);
1646 SET_LA1(_rCECLaAddr
.aui1_la
[0]);
1649 HDMI_CEC_LOG("MW Set LA & PA \n");
1650 HDMI_CEC_LOG("LA num = 0x%x , LA = 0x%x 0x%x 0x%x\n", _rCECLaAddr
.ui1_num
, _rCECLaAddr
.aui1_la
[0], _rCECLaAddr
.aui1_la
[1], _rCECLaAddr
.aui1_la
[2]);
1651 HDMI_CEC_LOG("PA = %04x \n", _rCECLaAddr
.ui2_pa
);
1654 void hdmi_CECMWSetLA(CEC_DRV_ADDR_CFG_T
* prAddr
)
1660 if (prAddr
->ui1_la_num
> 3)
1665 rLA
.ui1_num
= prAddr
->ui1_la_num
;
1666 rLA
.aui1_la
[0] = prAddr
->e_la
[0];
1667 rLA
.aui1_la
[1] = prAddr
->e_la
[1];
1668 rLA
.aui1_la
[2] = prAddr
->e_la
[2];
1669 rLA
.ui2_pa
= prAddr
->ui2_pa
;
1673 void hdmi_CECMWGet(CEC_FRAME_DESCRIPTION
* frame
)
1676 memcpy(frame
, cec_receive_msg
, sizeof(CEC_FRAME_DESCRIPTION
));
1677 cec_msg_report_pending
= 0;
1680 void hdmi_CECMWSend(CEC_SEND_MSG_T
* msg
)
1687 if ((msg
->t_frame_info
.ui1_init_addr
> 0xf) || (msg
->t_frame_info
.ui1_dest_addr
> 0xf) || (msg
->t_frame_info
.z_operand_size
> LOCAL_CEC_MAX_OPERAND_SIZE
))
1689 HDMI_CEC_LOG("apk send msg error\n");
1693 cecMwTxMsg
.txtag
= msg
->pv_tag
;
1694 cecMwTxMsg
.blocks
.header
.initiator
= msg
->t_frame_info
.ui1_init_addr
;
1695 cecMwTxMsg
.blocks
.header
.destination
= msg
->t_frame_info
.ui1_dest_addr
;
1696 cecMwTxMsg
.sendidx
= 0;
1697 cecMwTxMsg
.reTXcnt
= 0;
1698 if (msg
->t_frame_info
.ui2_opcode
== 0xffff)
1700 cecMwTxMsg
.size
= 1;
1704 cecMwTxMsg
.blocks
.opcode
= msg
->t_frame_info
.ui2_opcode
;
1705 cecMwTxMsg
.size
= msg
->t_frame_info
.z_operand_size
+ 2;
1707 for (i
=0; i
<cecMwTxMsg
.size
-2; i
++)
1709 cecMwTxMsg
.blocks
.operand
[i
] = msg
->t_frame_info
.aui1_operand
[i
];
1712 i4Ret
= _CEC_TX_Enqueue(&cecMwTxMsg
);
1715 msg
->b_enqueue_ok
= FALSE
;
1716 HDMI_CEC_LOG("MW Set cmd fail \n");
1721 msg
->b_enqueue_ok
= TRUE
;
1722 HDMI_CEC_LOG("MW Set cmd sucess \n");
1728 void hdmi_CECMWSetEnableCEC(unsigned char u1EnCec
)
1736 HDMI_CEC_LOG("UI ON \n");
1742 HDMI_CEC_LOG("UI off \n");
1749 void hdmi_NotifyApiCECAddress(CEC_ADDRESS
*cecaddr
)
1753 cecaddr
->ui2_pa
= _rCECPhysicAddr
.ui2_pa
;
1754 cecaddr
->ui1_la
= _rCECPhysicAddr
.ui1_la
;
1757 void hdmi_SetPhysicCECAddress(unsigned short u2pa
, unsigned char u1la
)
1759 HDMI_CEC_LOG("u2pa=%x,u1la=%x\n",u2pa
,u1la
);
1761 _rCECPhysicAddr
.ui2_pa
= u2pa
;
1762 _rCECPhysicAddr
.ui1_la
= u1la
;
1764 extern size_t hdmi_hotplugstate
;
1765 void hdmi_cec_usr_cmd(unsigned int cmd
, unsigned int* result
)
1770 *result
= cec_msg_report_pending
;
1773 *result
= hdmi_hotplugstate
;
1774 printk("[hdmi]hdmi_hotplugstate=%d\n",hdmi_hotplugstate
);
1777 printk("[xubo]debug irq\n");
1778 hdmi_hotplugstate
= 1;
1781 hdmi_CECMWSetEnableCEC(1);
1784 hdmi_CECMWSetEnableCEC(0);