import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / hdmi / internal_hdmi / mt8127 / hdmicec.c
1 #ifdef CONFIG_MTK_INTERNAL_HDMI_SUPPORT
2
3 #include <linux/interrupt.h>
4 #include <linux/i2c.h>
5 #include <linux/slab.h>
6 #include <linux/irq.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>
30 #include <linux/fs.h>
31 #include <linux/string.h>
32 #include <linux/completion.h>
33
34 #include "hdmi_ctrl.h"
35 #include "hdmicec.h"
36
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"
42
43
44 #include <mach/devs.h>
45 #include <mach/mt_typedefs.h>
46 #include <mach/mt_gpio.h>
47 #include <mach/mt_pm_ldo.h>
48
49 #include <mach/mt_pmic_wrap.h>
50
51
52
53 static unsigned short _CEC_Status;
54
55 #define SetCECStatus(arg) (_CEC_Status |= (arg))
56 #define ClrCECStatus(arg) (_CEC_Status &= (~(arg)))
57 #define IsCECStatus(arg) ((_CEC_Status & (arg)) > 0)
58
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)
63
64
65 static CEC_FRAME_DESCRIPTION ActiveRXFrame;
66 static CEC_FRAME_DESCRIPTION CTSTestFrame;
67
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);
71
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);
75
76 static CEC_FRAME_DESCRIPTION CEC_rx_msg_queue[RX_Q_SIZE];
77 static CEC_FRAME_DESCRIPTION CEC_tx_msg_queue[TX_Q_SIZE];
78
79 CEC_FRAME_DESCRIPTION * ActiveTXFrame;
80 CEC_LA_ADDRESS _rCECLaAddr;
81 static CEC_FRAME_DESCRIPTION cecMwTxMsg;
82 CEC_ADDRESS _rCECPhysicAddr;
83
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);
95
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)
100
101 #define HDMICEC_BASE (0xF0012000)
102
103 #define u1RegRead1B(reg16) (hdmi_cec_read(reg16)&0xff)
104 #define u4RegRead4B(reg16) (hdmi_cec_read(reg16))
105
106
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))))))
109
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()
132
133 /* TX_EVENT */
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() \
151 do { \
152 ENABLE_INT_FAIL(0); \
153 ENABLE_INT_RB(0); \
154 ENABLE_INT_LOW(0); \
155 ENABLE_INT_UN(0); \
156 ENABLE_INT_BS(0); \
157 } while (0)
158
159 /* RX FSM status */
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))
175
176 /* TX FSM status */
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))
193
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)
198
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)
204
205 #define FILL_TX_DATA(data) vRegWriteFldAlign(TX_DATA_NEXT, data, WTX_DATA)
206
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))
214
215 #define GET_HW_RX_DATA() (RegReadFldAlign(RX_DATA, RXED_DATA))
216
217 #define FLOW_CONTROL_ACK(onoff) \
218 do {\
219 vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_H_ACK);\
220 vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_D_ACK);\
221 } while (0)
222
223 #define GET_FOLLOWER_H_ACK() (RegReadFldAlign(TX_HEADER, TXING_H_ACK))
224 #define GET_FOLLOWER_D_ACK() (RegReadFldAlign(TX_HEADER, TXING_D_ACK))
225
226 #define TX_FAIL_MAX() (RegReadFldAlign(TX_FAIL, RETX_MAX))
227 #define CLR_TX_FAIL_MAX() vRegWriteFldAlign(TX_FAIL, 0, RETX_MAX)
228
229 #define TX_FAIL_RECORD() u4RegRead4B(TX_FAIL)
230
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))
234
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)
238
239
240
241 #define RESET_HW_TX() \
242 do { \
243 DISABLE_TX_EN();\
244 ENABLE_TX_EN();\
245 } while (0)
246
247 #define GET_TX_BIT_COUNTER() (RegReadFldAlign(TX_STATUS, TX_BIT_COUNTER))
248
249 unsigned int IS_HDMI_HTPLG(void)
250 {
251 return (RegReadFldAlign(RX_EVENT, HDMI_HTPLG));
252 }
253
254 unsigned int IS_HDMI_PORD(void)
255 {
256 return (RegReadFldAlign(RX_EVENT, HDMI_PORD));
257 }
258
259 void vClear_cec_irq(void)
260 {
261 //27mhz, clear HPD/PORT and cec int
262 vRegWriteFldAlign(TR_CONFIG, 1, CLEAR_CEC_IRQ);
263 udelay(2);
264 vRegWriteFldAlign(TR_CONFIG, 0, CLEAR_CEC_IRQ);
265
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);
270
271 }
272
273 void vCec_pdn_32k(void)
274 {
275 vRegWriteFldAlign(CEC_CKGEN, 1, CEC_32K_PDN);
276
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);
280
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);
284
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);
288
289 }
290
291 void vEnable_hotplug_pord_int(unsigned char u1enable)
292 {
293 if(u1enable==0)
294 {
295 vRegWriteFldAlign(RX_EVENT, 1, HDMI_PORD_INT_EN);
296 vRegWriteFldAlign(RX_EVENT, 1, HDMI_HTPLG_INT_EN);
297 }
298 else
299 {
300 vRegWriteFldAlign(RX_EVENT, 0, HDMI_PORD_INT_EN);
301 vRegWriteFldAlign(RX_EVENT, 0, HDMI_HTPLG_INT_EN);
302 }
303 }
304 void vRegWrite4BMsk(unsigned short reg16, unsigned int val32, unsigned int msk32)
305 {
306 HDMI_CEC_FUNC();
307 val32 &=msk32;
308 hdmi_cec_write(reg16, ((hdmi_cec_read(reg16))&~msk32)|val32);
309 }
310
311 /*----------------------------------------------------------------------------*/
312
313 void internal_cec_read(unsigned int u4Reg, unsigned int *p4Data)
314 {
315 *p4Data = (*(volatile unsigned int*)(u4Reg));
316 }
317
318 void internal_cec_write(unsigned int u4Reg, unsigned int u4data)
319 {
320 *(volatile unsigned int*)(u4Reg) = (u4data);
321 }
322
323 unsigned int hdmi_cec_read(unsigned short u2Reg)
324 {
325 unsigned int u4Data;
326 internal_cec_read(HDMICEC_BASE+u2Reg, &u4Data);
327
328 //HDMI_CEC_LOG("[R]cec = 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
329 return u4Data;
330 }
331
332 void hdmi_cec_write(unsigned short u2Reg, unsigned int u4Data)
333 {
334 internal_cec_write(HDMICEC_BASE+u2Reg, u4Data);
335
336 //HDMI_CEC_LOG("[W]cec= 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
337 }
338
339
340 unsigned int hdmi_cec_2n(unsigned int u4Data)
341 {
342 unsigned int u4resultvalue=1;
343 unsigned char u1number;
344
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
348
349 for(u1number=0; u1number<u4Data; u1number++)
350 {
351 u4resultvalue *= 2;
352 }
353 //HDMI_CEC_LOG("hdmi_cec_2n data = 0x%08x\n", u4resultvalue-1);
354
355 return (u4resultvalue-1);
356 }
357
358 u32 hdmi_cec_maskvalue(unsigned int u4Width, unsigned int u4Startbit)
359 {
360 unsigned int u4Data=0xffffffff, i;
361
362 for(i=0; i<u4Width; i++)
363 {
364 u4Data &=(~(hdmi_cec_2n(u4Startbit+i)+1));
365 }
366 //HDMI_CEC_LOG("hdmi_cec_maskvalue data = 0x%08x\n", u4Data);
367
368 return u4Data;
369 }
370 /*----------------------------------------------------------------------------*/
371
372 void vRegWrite4B(unsigned short u2Reg, unsigned int u4Data)
373 {
374 HDMI_CEC_FUNC();
375 hdmi_cec_write(u2Reg, u4Data);
376 }
377
378 void hdmi_cec_init(void)
379 {
380 HDMI_CEC_FUNC();
381 cec_msg_report_pending = 0;
382
383 _rCECPhysicAddr.ui2_pa = 0xffff;
384 _rCECPhysicAddr.ui1_la = 0x0;
385
386 _CEC_Status = 0;
387 _CEC_ErrStatus = 0;
388 _u1TxFailCause = FAIL_NONE;
389 _u1ReTxCnt = 0;
390 CEC_rxQ_write_idx = 0;
391 CEC_rxQ_read_idx = 0;
392 CEC_txQ_write_idx = 0;
393 CEC_txQ_read_idx = 0;
394
395 _rCECLaAddr.aui1_la[0] = 0x0F;
396 _rCECLaAddr.aui1_la[1] = 0x0F;
397 _rCECLaAddr.aui1_la[2] = 0x0F;
398
399 /*
400 //32k
401 vRegWrite4B(CEC_CKGEN, 0x00040082); //3MHz //different from BD /100k
402 vRegWrite4B(TR_TEST, 0x40004010);// Bpad enable¡BTx compared timing 0x19
403
404 // CYJ.NOTE TX_EN, RX_EN: disable it
405 vRegWrite4B(TR_CONFIG, 0x00000001);
406
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);
416
417 */
418
419 vRegWrite4B(CEC_CKGEN, 0x000a0082); //3MHz //different from BD /100k
420 vRegWrite4B(TR_TEST, 0x40004019);// Bpad enable¡BTx compared timing 0x19
421
422 // CYJ.NOTE TX_EN, RX_EN: disable it
423 vRegWrite4B(TR_CONFIG, 0x00000001);
424
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);
434
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);
442
443 FLOW_CONTROL_ACK(1);
444
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);
451
452 vRegWrite4B(TR_CONFIG, 0x8fff1101);
453
454 vRegWrite4BMsk(TX_EVENT, 0x00, 0xff);
455 vRegWrite4BMsk(RX_EVENT, 0x00, 0xff);
456 // RX_EVENT
457 ENABLE_INT_OV(1);
458 ENABLE_INT_BR_RDY(1);
459 ENABLE_INT_HEADER_RDY(1);
460 // TX_EVENT
461 ENABLE_INT_UN(0);
462 ENABLE_INT_LOW(0);
463 ENABLE_INT_FAIL(0);
464 ENABLE_INT_BS(0);
465 ENABLE_INT_RB(0);
466 //la
467 SET_LA1(0x0F);
468 SET_LA2(0x0F);
469 SET_LA3(0x0F);
470
471 return;
472 }
473
474 void hdmi_cec_power_on(unsigned char pwr)
475 {
476 HDMI_CEC_FUNC();
477
478 if(pwr == 0)
479 {
480 vRegWriteFldAlign(CEC_CKGEN,1,PDN);
481 }
482 else
483 {
484 vRegWriteFldAlign(CEC_CKGEN,0,PDN);
485 }
486 }
487 static unsigned char CEC_rx_enqueue(CEC_FRAME_DESCRIPTION* frame)
488 {
489 /* check if queue is full */
490 HDMI_CEC_FUNC();
491 if (IS_RX_Q_FULL())
492 {
493 return FALSE;
494 }
495
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;
500
501 return TRUE;
502 }
503
504 static void _CEC_Receiving(void)
505 {
506 static unsigned char* size;
507 static CEC_FRAME_DESCRIPTION* frame = &ActiveRXFrame;
508 unsigned int data;
509 unsigned char i, rxlen, is_d_eom, ret;
510
511 HDMI_CEC_FUNC();
512
513 // no data available
514 if(!IS_INT_BR_RDY())
515 {
516 ASSERT(0);
517 return;
518 }
519
520 // <polling message> only
521 if(GET_HW_RX_LEN() == 0)
522 {
523 NOTIFY_RX_HW_DATA_TAKEN();
524 ClrCECStatus(STATE_RX_GET_NEW_HEADER); //CM 20081210
525 return;
526 }
527
528 /* new incoming message */
529 if (IsCECStatus(STATE_RX_GET_NEW_HEADER))
530 {
531 ClrCECStatus(STATE_RX_GET_NEW_HEADER);
532 if (IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE))
533 {
534 HDMI_CEC_LOG("Lost EOM:2\n");
535 SetCECErrorFlag(ERR_RX_LOST_EOM);
536 }
537 SetCECStatus(STATE_WAIT_RX_FRAME_COMPLETE);
538
539 size = &(frame->size);
540 (*size) = 0;
541 frame->blocks.header.initiator = GET_SRC_FIELD();
542 frame->blocks.header.destination = GET_DST_FIELD();
543 (*size)++;
544 }
545
546 if (!IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE))
547 {
548 NOTIFY_RX_HW_DATA_TAKEN();
549 SetCECErrorFlag(ERR_RX_LOST_HEADER);
550 return;
551 }
552
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();
557
558 if (rxlen == 0x3)
559 {
560 rxlen = 2;
561 }
562 else if (rxlen == 0x7)
563 {
564 rxlen = 3;
565 }
566 else if (rxlen == 0xf)
567 {
568 rxlen = 4;
569 }
570 else if (rxlen != 0x1)
571 {
572 HDMI_CEC_LOG("invalid rx length occurs\n");
573 //assert(0);
574 }
575
576 // for opcode
577 if ((*size) == 1)
578 {
579 frame->blocks.opcode = data & 0xff;
580 data >>= 8;
581 (*size)++;
582 rxlen--;
583 }
584
585 // for operand
586 for (i=0; i<rxlen; i++)
587 {
588
589 if ((*size) > 15)
590 {
591 HDMI_CEC_LOG("Receive Data Length is wrong ! \n");
592 break;
593 }
594 else
595 {
596 ASSERT((*size) >= 2);
597 frame->blocks.operand[(*size)-2] = data & 0xff;
598 data >>= 8;
599 (*size)++;
600 }
601 }
602
603 if (is_d_eom)
604 {
605 ClrCECStatus(STATE_WAIT_RX_FRAME_COMPLETE);
606 SetCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
607
608 /* push into rx_queue */
609 ret = CEC_rx_enqueue(frame);
610 if (ret == FALSE)
611 {
612 SetCECErrorFlag(ERR_RXQ_OVERFLOW);
613 HDMI_CEC_LOG("cec rx buffer overflow\n");
614 //ASSERT(0);
615 }
616 }
617 }
618
619 static unsigned char _CEC_SendRemainingDataBlocks(void)
620 {
621 CEC_FRAME_DESCRIPTION *frame;
622 unsigned char errcode = 0;
623 unsigned char size;
624 unsigned char* sendidx;
625 unsigned char* blocks;
626 unsigned int data;
627 unsigned char i,j;
628 HDMI_CEC_FUNC();
629
630 if (!IsCECStatus(STATE_TXING_FRAME))
631 {
632 return 0;
633 }
634
635 if (IsCECStatus(STATE_WAIT_TX_DATA_TAKEN))
636 {
637 if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN())
638 {
639 ClrCECStatus(STATE_WAIT_TX_DATA_TAKEN);
640 }
641 else
642 {
643 // tx buffer is not emply
644 return 0;
645 }
646 }
647 else
648 {
649 return 0;
650 }
651
652 /* request current active TX frame */
653 frame = ActiveTXFrame;
654
655 size = frame->size;
656 sendidx = &(frame->sendidx);
657 blocks = &(frame->blocks.opcode);
658
659 // CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop
660 if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD()>0))
661 {
662 HDMI_CEC_LOG("Detect TX FAIL in %s\n", __FUNCTION__);
663 return 3;
664 // RESET_HW_TX();
665 // ASSERT(0);
666 }
667
668 size -= ((*sendidx)+1);
669
670 if (size==0)
671 {
672 return 0;
673 }
674
675 /* CYJ:TODO duplicate (as _CEC_SendFrame())! */
676 /* fill data */
677 if (size > 4)
678 {
679 SET_HW_TX_LEN(0xf);
680 MARK_H_EOM(0);
681 MARK_D_EOM(0);
682 }
683 else if (size == 4)
684 {
685 SET_HW_TX_LEN(0xf);
686 MARK_H_EOM(0);
687 MARK_D_EOM(1);
688 }
689 else if (size == 3)
690 {
691 SET_HW_TX_LEN(0x7);
692 MARK_H_EOM(0);
693 MARK_D_EOM(1);
694 }
695 else if (size == 2)
696 {
697 SET_HW_TX_LEN(0x3);
698 MARK_H_EOM(0);
699 MARK_D_EOM(1);
700 }
701 else if (size == 1)
702 {
703 SET_HW_TX_LEN(0x1);
704 MARK_H_EOM(0);
705 MARK_D_EOM(1);
706 }
707
708 data = 0;
709 for (i=0,j=size; i<4; i++)
710 {
711 data >>= 8;
712 data |= (blocks[(*sendidx)]) << 24;
713 if (i<j)
714 {
715 (*sendidx)++;
716 size--;
717 }
718 }
719
720 /* EOM */
721 if (size == 0)
722 {
723 ENABLE_INT_FAIL(1);
724 ENABLE_INT_RB(0);
725 ENABLE_INT_LOW(0);
726 ENABLE_INT_UN(0);
727 ENABLE_INT_BS(0);
728 }
729 else
730 {
731 ENABLE_INT_FAIL(1);
732 ENABLE_INT_RB(1);
733 ENABLE_INT_LOW(1);
734 ENABLE_INT_UN(1);
735 ENABLE_INT_BS(0);
736
737 SetCECStatus(STATE_WAIT_TX_DATA_TAKEN);
738 }
739
740 FILL_TX_DATA(data);
741 HDMI_CEC_LOG("TRIGGER_TX_HW in %s, size: %x\n", __FUNCTION__, size);
742
743 CLR_TX_FINISH();
744
745 TRIGGER_TX_HW();
746
747 return errcode;
748 }
749
750 static void _CEC_Check_Active_Tx_Result(void)
751 {
752 HDMI_CEC_FUNC();
753
754 if (IsCECStatus(STATE_TXING_FRAME))
755 {
756 if (IsCECStatus(STATE_HW_RETX))
757 {
758 if (TX_FAIL_SOURCE())
759 {
760 _u1TxFailCause = FAIL_SOURCE;
761 CLR_TX_FAIL_SOURCE();
762 }
763 if ((TX_FAIL_RECORD()!=0))
764 {
765 DISABLE_ALL_TX_INT();
766
767 SetCECStatus(STATE_TX_NOACK);
768 ClrCECStatus(STATE_HW_RETX);
769
770 ClrCECStatus(STATE_TXING_FRAME);
771 if (IS_TX_FSM_FAIL())
772 {
773 HDMI_CEC_LOG( "TX NO ACK\n");
774 }
775 else
776 {
777 HDMI_CEC_LOG( "other TX error\n");
778 }
779 HDMI_CEC_LOG( "H ACK: %x, D ACK: %x\n", GET_FOLLOWER_H_ACK(), GET_FOLLOWER_D_ACK());
780
781 RESET_HW_TX();
782 }
783 }
784 else if ((ActiveTXFrame->sendidx+1) == (ActiveTXFrame->size))
785 {
786
787 if (IS_TX_FSM_IDLE() && IS_TX_FINISH())
788 {
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());
793 }
794 }
795 }
796
797 }
798
799 static CEC_FRAME_DESCRIPTION* _CEC_Get_Cur_TX_Q_Msg(void)
800 {
801 HDMI_CEC_FUNC();
802
803 if (IS_TX_Q_EMPTY())
804 {
805 return NULL;
806 }
807
808 return (&(CEC_tx_msg_queue[CEC_txQ_read_idx]));
809 }
810
811 static unsigned char _CEC_TX_Dequeue(void)
812 {
813 HDMI_CEC_FUNC();
814
815 if (IS_TX_Q_EMPTY())
816 {
817 return FALSE;
818 }
819
820 // CYJ.NOTE: no critical section
821 CEC_txQ_read_idx = (CEC_txQ_read_idx + 1) % TX_Q_SIZE;
822
823 return TRUE;
824 }
825 static void _CEC_tx_msg_notify(UINT8 result, void* tag)
826 {
827 if (result == 0x00)
828 {
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);
833 }
834 else if (result == 0x01)
835 {
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);
840 }
841 }
842 void hdmi_cec_api_get_txsts(CEC_ACK_INFO_T *pt)
843 {
844 memcpy(pt,&cec_send_result,sizeof(CEC_ACK_INFO_T));
845 }
846 static void vApiNotifyCECDataArrival(CEC_FRAME_DESCRIPTION* frame)
847 {
848 cec_receive_msg = frame;
849 vNotifyAppHdmiCecState(HDMI_CEC_GET_CMD);
850 }
851 static void PrintFrameDescription(CEC_FRAME_DESCRIPTION* frame)
852 {
853 unsigned char i;
854
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);
862 if (frame->size > 1)
863 {
864 HDMI_CEC_LOG("opcode: 0x%x\n", frame->blocks.opcode);
865 }
866 if ((frame->size > 2)&& (frame->size <= 16))
867 {
868 for (i=0; i<(frame->size-2); i++)
869 {
870 HDMI_CEC_LOG("0x%02x \n", frame->blocks.operand[i]);
871 }
872 }
873 HDMI_CEC_LOG("<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
874 }
875
876 static unsigned char _CEC_SendFrame(CEC_FRAME_DESCRIPTION* frame)
877 {
878 unsigned char errcode = 0;
879 unsigned char size;
880 unsigned char* sendidx;
881 unsigned char* blocks;
882 unsigned int data;
883 unsigned char i,j;
884 HDMI_CEC_FUNC();
885
886 if (IsCECStatus(STATE_TXING_FRAME))
887 {
888 return 1;
889 }
890 SetCECStatus(STATE_TXING_FRAME);
891
892 // CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop
893 if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD()>0))
894 {
895 HDMI_CEC_LOG("Detect TX FAIL in %s\n", __FUNCTION__);
896 //return 3;
897 RESET_HW_TX();
898 // ASSERT(0); // CAN NOT HAPPEN HERE
899 }
900
901 size = frame->size;
902 sendidx = &(frame->sendidx);
903 blocks = &(frame->blocks.opcode);
904
905 if (size==0)
906 {
907 ClrCECStatus(STATE_TXING_FRAME);
908 return 2;
909 }
910 else if (size > 16)
911 {
912 ClrCECStatus(STATE_TXING_FRAME);
913 return 2;
914 }
915
916 // CYJ.NOTE: TX HW is not idle
917 if (!IS_TX_FSM_IDLE())
918 {
919 RESET_HW_TX();
920 }
921 ActiveTXFrame = frame;
922
923 ClrCECStatus(STATE_TX_FRAME_SUCCESS);
924 ClrCECStatus(STATE_TX_NOACK);
925
926
927 /* fill header */
928 FILL_SRC_FIELD(frame->blocks.header.initiator);
929 FILL_DST_FIELD(frame->blocks.header.destination);
930 size -= 1;
931
932 // header-only
933 if (size==0)
934 {
935 SET_HW_TX_LEN(0);
936 MARK_H_EOM(1);
937 MARK_D_EOM(0);
938 // TRIGGER_TX_HW();
939 size = 0;
940 }
941
942 /* fill data */
943 if (size > 4)
944 {
945 SET_HW_TX_LEN(0xf);
946 MARK_H_EOM(0);
947 MARK_D_EOM(0);
948 }
949 else if (size == 4)
950 {
951 SET_HW_TX_LEN(0xf);
952 MARK_H_EOM(0);
953 MARK_D_EOM(1);
954 }
955 else if (size == 3)
956 {
957 SET_HW_TX_LEN(0x7);
958 MARK_H_EOM(0);
959 MARK_D_EOM(1);
960 }
961 else if (size == 2)
962 {
963 SET_HW_TX_LEN(0x3);
964 MARK_H_EOM(0);
965 MARK_D_EOM(1);
966 }
967 else if (size == 1)
968 {
969 SET_HW_TX_LEN(0x1);
970 MARK_H_EOM(0);
971 MARK_D_EOM(1);
972 }
973
974 data = 0;
975 for (i=0, j=size; i<4; i++)
976 {
977 data >>= 8;
978 data |= (blocks[(*sendidx)]) << 24;
979 if (i<j)
980 {
981 (*sendidx)++;
982 size--;
983 }
984 }
985
986 /* EOM */
987 if (size == 0)
988 {
989 ENABLE_INT_FAIL(1);
990 ENABLE_INT_RB(0);
991 ENABLE_INT_LOW(0);
992 ENABLE_INT_UN(0);
993 ENABLE_INT_BS(0);
994 }
995 else
996 {
997 ENABLE_INT_FAIL(1);
998 ENABLE_INT_RB(1);
999 ENABLE_INT_LOW(1);
1000 ENABLE_INT_UN(1);
1001 ENABLE_INT_BS(0);
1002
1003 SetCECStatus(STATE_WAIT_TX_DATA_TAKEN);
1004 }
1005
1006 FILL_TX_DATA(data);
1007 HDMI_CEC_LOG("TRIGGER_TX_HW in %s, size: %x\n", __FUNCTION__, size);
1008
1009 CLR_TX_FINISH();
1010 _u1TxFailCause = FAIL_NONE;
1011 _u1ReTxCnt = 0;
1012 TRIGGER_TX_HW();
1013
1014 return errcode;
1015 }
1016
1017 static void _CEC_TX_Queue_Loop(void)
1018 {
1019 CEC_FRAME_DESCRIPTION* frame;
1020 //HDMI_CEC_FUNC();
1021
1022 /* if the tx message queue is empty */
1023 if (IS_TX_Q_EMPTY())
1024 {
1025 return;
1026 }
1027
1028 /* if the tx is active, check the result */
1029 if (IsCECStatus(STATE_TXING_FRAME))
1030 {
1031 if(IsCECErrorFlag(ERR_TX_MISALARM)&& (TX_FAIL_RECORD()!=0)&& IS_TX_FSM_FAIL())
1032 {
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);
1038 RESET_HW_TX();
1039 }
1040
1041 _CEC_Check_Active_Tx_Result();
1042 if (IsCECStatus(STATE_TX_FRAME_SUCCESS))
1043 {
1044 HDMI_CEC_LOG( "This message is successful\n");
1045 frame = _CEC_Get_Cur_TX_Q_Msg();
1046 if (frame == NULL)
1047 {
1048 ASSERT(0);
1049 }
1050 _CEC_tx_msg_notify(0x00, frame->txtag);
1051 _CEC_TX_Dequeue();
1052 ClrCECStatus(STATE_TX_FRAME_SUCCESS);
1053 }
1054 if (IsCECStatus(STATE_TX_NOACK))
1055 {
1056 frame = _CEC_Get_Cur_TX_Q_Msg();
1057 if (frame == NULL)
1058 {
1059 ASSERT(0);
1060 }
1061 HDMI_CEC_LOG( "This message is failed: %d\n", frame->reTXcnt);
1062 frame->reTXcnt++;
1063 frame->sendidx = 0;
1064 ClrCECStatus(STATE_TX_NOACK);
1065 // CYJ.NOTE: retransmission
1066 if (frame->reTXcnt == RETX_MAX_CNT)
1067 {
1068 _u1TxFailCause = FAIL_NONE;
1069 HDMI_CEC_LOG( "ReTX reach MAX\n");
1070 _CEC_tx_msg_notify(0x01, frame->txtag);
1071 _CEC_TX_Dequeue();
1072 }
1073 }
1074 }
1075 else
1076 /* if the tx is not active, send the next message */
1077 {
1078 frame = _CEC_Get_Cur_TX_Q_Msg();
1079 if (frame == NULL)
1080 {
1081 ASSERT(0);
1082 }
1083 if (_u1TxFailCause == FAIL_SOURCE)
1084 {
1085 if (_u1ReTxCnt < 15)
1086 {
1087 _u1ReTxCnt++;
1088 return;
1089 }
1090 else
1091 {
1092 _u1ReTxCnt = 0;
1093 }
1094 }
1095 HDMI_CEC_LOG( "Send a new message\n");
1096 PrintFrameDescription(frame);
1097 _CEC_SendFrame(frame);
1098 }
1099 }
1100
1101 static CEC_FRAME_DESCRIPTION* CEC_rx_dequeue(void)
1102 {
1103 CEC_FRAME_DESCRIPTION* ret;
1104 //HDMI_CEC_FUNC();
1105
1106 /* check if queue is empty */
1107 if (IS_RX_Q_EMPTY())
1108 {
1109 return NULL;
1110 }
1111
1112 /* return next available entry for middleware */
1113 ret = &(CEC_rx_msg_queue[CEC_rxQ_read_idx]);
1114
1115 // CYJ.NOTE: no critical section
1116 CEC_rxQ_read_idx = (CEC_rxQ_read_idx + 1) % RX_Q_SIZE;
1117
1118 return ret;
1119 }
1120
1121 static unsigned char CEC_frame_validation(CEC_FRAME_DESCRIPTION* frame)
1122 {
1123 unsigned char size = frame->size;
1124 unsigned char i1ret = TRUE;
1125 HDMI_CEC_FUNC();
1126
1127 /* opcode-aware */
1128 /* CYJ.NOTE: code size issue */
1129 switch (frame->blocks.opcode)
1130 {
1131 // length == 2
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:
1148 case OPCODE_ABORT:
1149 case OPCODE_GIVE_AUDIO_STATUS:
1150 case OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS:
1151 if (size != 2)
1152 {
1153 i1ret = FALSE;
1154 }
1155 break;
1156 case OPCODE_SYSTEM_AUDIO_MODE_REQUEST:
1157 if ((size != 2) && (size != 4))
1158 {
1159 i1ret = FALSE;
1160 }
1161 break;
1162 // length == 3
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:
1169 case OPCODE_PLAY:
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:
1178 if (size != 3)
1179 {
1180 i1ret = FALSE;
1181 }
1182 break;
1183 case OPCODE_USER_CONTROL_PRESSED:
1184 if ((size != 3) && (size != 4))
1185 {
1186 i1ret = FALSE;
1187 }
1188 break;
1189 // length == 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:
1195 if (size != 4)
1196 {
1197 i1ret = FALSE;
1198 }
1199 break;
1200 // length == 5
1201 case OPCODE_REPORT_PHYSICAL_ADDRESS:
1202 case OPCODE_SET_MENU_LANGUAGE:
1203 case OPCODE_DEVICE_VENDOR_ID:
1204 if (size != 5)
1205 {
1206 i1ret = FALSE;
1207 }
1208 break;
1209 // length == 6
1210 case OPCODE_ROUTING_CHANGE:
1211 case OPCODE_SELECT_ANALOGUE_SERVICE:
1212 if (size != 6)
1213 {
1214 i1ret = FALSE;
1215 }
1216 break;
1217 // length == 9
1218 case OPCODE_SELECT_DIGITAL_SERVICE:
1219 if (size != 9)
1220 {
1221 i1ret = FALSE;
1222 }
1223 break;
1224 // length == 13
1225 case OPCODE_CLEAR_ANALOGUE_TIMER:
1226 case OPCODE_SET_ANALOGUE_TIMER:
1227 if (size != 13)
1228 {
1229 i1ret = FALSE;
1230 }
1231 break;
1232 // length == 16
1233 case OPCODE_CLEAR_DIGITAL_TIMER:
1234 case OPCODE_SET_DIGITAL_TIMER:
1235 if (size != 16)
1236 {
1237 i1ret = FALSE;
1238 }
1239 break;
1240 case OPCODE_RECORD_ON:
1241 if ((size < 3) || (size > 10))
1242 {
1243 i1ret = FALSE;
1244 }
1245 break;
1246 // length == 10 ~ 11
1247 case OPCODE_CLEAR_EXTERNAL_TIMER:
1248 case OPCODE_SET_EXTERNAL_TIMER:
1249 if ((size < 10) || (size > 11))
1250 {
1251 i1ret = FALSE;
1252 }
1253 break;
1254 case OPCODE_TIMER_STATUS:
1255 if ((size != 3) && (size != 5))
1256 {
1257 i1ret = FALSE;
1258 }
1259 break;
1260 case OPCODE_TUNER_DEVICE_STATUS:
1261 if ((size != 7) && (size != 10))
1262 {
1263 i1ret = FALSE;
1264 }
1265 break;
1266 case OPCODE_VENDOR_COMMAND:
1267 case OPCODE_VENDOR_COMMAND_WITH_ID:
1268 case OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
1269 if (size > 16)
1270 {
1271 i1ret = FALSE;
1272 }
1273 break;
1274 case OPCODE_SET_OSD_STRING:
1275 if ((size<3) || (size>16))
1276 {
1277 i1ret = FALSE;
1278 }
1279 break;
1280 case OPCODE_SET_TIMER_PROGRAM_TITLE:
1281 case OPCODE_SET_OSD_NAME:
1282 if ((size<3) || (size>16))
1283 {
1284 i1ret = FALSE;
1285 }
1286 break;
1287 }
1288 if (i1ret == FALSE)
1289 {
1290 HDMI_CEC_LOG( "receive invalid frame: %x\n", frame->blocks.opcode);
1291 PrintFrameDescription(frame);
1292 }
1293 return i1ret;
1294 }
1295
1296 static unsigned char check_and_init_tx_frame(CEC_FRAME_DESCRIPTION* frame)
1297 {
1298 unsigned char ret = 0x00;
1299 HDMI_CEC_FUNC();
1300
1301 if ((frame->size > CEC_MAX_MESG_SIZE) || (frame->size == 0))
1302 {
1303 HDMI_CEC_LOG("Tx fram size is not correct \n");
1304 ret = 0x01;
1305 }
1306
1307 // valid tx frame
1308 if (ret == 0x00)
1309 {
1310 frame->reTXcnt = 0;
1311 frame->sendidx = 0;
1312 }
1313
1314 return ret;
1315 }
1316
1317 unsigned char _CEC_TX_Enqueue(CEC_FRAME_DESCRIPTION* frame)
1318 {
1319 HDMI_CEC_FUNC();
1320 if (frame->size ==1)
1321 {
1322 HDMI_CEC_LOG("Polling LA = 0x%x \n" , (unsigned char)((frame->blocks.header.initiator << 4) | frame->blocks.header.destination));
1323 }
1324 else
1325 {
1326 HDMI_CEC_LOG("Opcode = 0x%x, size = 0x%x \n" , frame->blocks.opcode, frame->size);
1327 }
1328
1329
1330 if (check_and_init_tx_frame(frame))
1331 {
1332 return 0x01;
1333 }
1334
1335 if (IS_TX_Q_FULL())
1336 {
1337 HDMI_CEC_LOG("Tx queue is full \n");
1338 return 0x01;
1339 }
1340
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;
1344
1345 return 0x00;
1346 }
1347
1348 void hdmi_u4CecSendSLTData(unsigned char *pu1Data)
1349 {
1350 unsigned char i;
1351
1352 if (*pu1Data > 14)
1353 {
1354 *pu1Data = 14;
1355 }
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++)
1364 {
1365 CTSTestFrame.blocks.operand[i] = *(pu1Data + i + 1);
1366 }
1367 _CEC_TX_Enqueue(&CTSTestFrame);
1368
1369 }
1370
1371 void hdmi_GetSLTData(CEC_SLT_DATA* rCecSltData)
1372 {
1373 unsigned char i;
1374 CEC_FRAME_DESCRIPTION* frame;
1375 HDMI_CEC_FUNC();
1376
1377 frame = CEC_rx_dequeue();
1378
1379 if (frame == NULL)
1380 {
1381 rCecSltData->u1Size = 5;
1382 for(i = 0; i < rCecSltData->u1Size; i++)
1383 {
1384 rCecSltData->au1Data[i] = i;
1385 }
1386 ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
1387 return;
1388 }
1389
1390 if(frame->blocks.opcode == 0x01)
1391 {
1392 if (CEC_frame_validation(frame))
1393 {
1394 PrintFrameDescription(frame);
1395 }
1396
1397 rCecSltData->u1Size = frame->size - 2;
1398 if (rCecSltData->u1Size > 14)
1399 {
1400 rCecSltData->u1Size = 14;
1401 }
1402 for(i = 0; i < rCecSltData->u1Size; i++)
1403 {
1404 rCecSltData->au1Data[i] = frame->blocks.operand[i];
1405 }
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 = ");
1409
1410 for(i = 0; i < rCecSltData->u1Size; i++)
1411 {
1412 HDMI_CEC_LOG(" 0x%x ", rCecSltData->au1Data[i]);
1413 }
1414 HDMI_CEC_LOG(" \n");
1415 }
1416 }
1417
1418 void CTS_RXProcess(CEC_FRAME_DESCRIPTION* frame)
1419 {
1420 HDMI_CEC_FUNC();
1421
1422 if (frame->blocks.opcode == OPCODE_ABORT)
1423 {
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;
1433
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////////////////////////////////////
1448
1449 _CEC_TX_Enqueue(&CTSTestFrame);
1450 HDMI_CEC_LOG ("CTS Send: OPCODE_FEATURE_ABORT\n");
1451 }
1452 else if (frame->blocks.opcode == OPCODE_GIVE_PHYSICAL_ADDRESS)
1453 {
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;
1464
1465 _CEC_TX_Enqueue(&CTSTestFrame);
1466 HDMI_CEC_LOG( "CTS Send: OPCODE_REPORT_PHYSICAL_ADDRESS\n");
1467 }
1468 }
1469
1470 static void CEC_rx_msg_notify(unsigned char u1rxmode)
1471 {
1472 CEC_FRAME_DESCRIPTION* frame;
1473 //HDMI_CEC_FUNC();
1474 if(u1rxmode==CEC_SLT_MODE)
1475 return;
1476
1477 //if(u1rxmode==CEC_NORMAL_MODE)
1478 //return;
1479
1480 while (1)
1481 {
1482 if(cec_msg_report_pending == 1)
1483 {
1484 //HDMI_CEC_LOG("wait user get cmd\n");
1485 return;
1486 }
1487
1488 frame = CEC_rx_dequeue();
1489
1490 if (frame == NULL)
1491 {
1492 ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
1493 return;
1494 }
1495
1496 if (CEC_frame_validation(frame))
1497 {
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)
1503 {
1504 CTS_RXProcess(frame);
1505 }
1506 }
1507 }
1508 }
1509
1510 void hdmi_cec_mainloop(unsigned char u1rxmode)
1511 {
1512 //HDMI_CEC_FUNC();
1513 _CEC_TX_Queue_Loop();
1514
1515 // NOTE: the priority between tx and rx
1516 if (!IsCECStatus(STATE_TXING_FRAME))
1517 {
1518 CEC_rx_msg_notify(u1rxmode);
1519 }
1520
1521 }
1522
1523 unsigned char hdmi_cec_isrprocess(unsigned char u1rxmode)
1524 {
1525 unsigned char u1ReceivedDst;
1526
1527 if (HW_RX_HEADER_ARRIVED())
1528 {
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))
1534 {
1535 HDMI_CEC_LOG( "RX:H\n");
1536 if (IsCECStatus(STATE_RX_GET_NEW_HEADER))
1537 {
1538 HDMI_CEC_LOG("Lost EOM:1\n");
1539 SetCECErrorFlag(ERR_RX_LOST_EOM);
1540 }
1541 SetCECStatus(STATE_RX_GET_NEW_HEADER);
1542 }
1543 else
1544 {
1545 ClrCECStatus(STATE_RX_GET_NEW_HEADER);
1546 HDMI_CEC_LOG("RX:H False\n");
1547 }
1548 }
1549 if (HW_RX_DATA_ARRIVED())
1550 {
1551 HDMI_CEC_LOG("RX:D\n");
1552 _CEC_Receiving();
1553 }
1554 if (IS_INT_OV())
1555 {
1556 HDMI_CEC_LOG("Overflow\n");
1557 CLR_INT_OV();
1558 SetCECStatus(STATE_HW_RX_OVERFLOW);
1559 }
1560
1561 //TX_EVENT
1562 if (IsCECStatus(STATE_TXING_FRAME))
1563 {
1564 if (IS_INT_UN())
1565 {
1566 HDMI_CEC_LOG( "Underrun\n");
1567 CLR_INT_UN();
1568 SetCECErrorFlag(ERR_TX_UNDERRUN);
1569 }
1570 if (IS_INT_LOW())
1571 {
1572 HDMI_CEC_LOG( "Buffer Low\n");
1573 CLR_INT_LOW();
1574 if (!IS_INT_RB_RDY())
1575 {
1576 HDMI_CEC_LOG( "FW is slow to trigger the following blocks\n");
1577 SetCECErrorFlag(ERR_TX_BUFFER_LOW);
1578 }
1579 }
1580 if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN())
1581 {
1582 HDMI_CEC_LOG("TX Data Taken\n");
1583 _CEC_SendRemainingDataBlocks();
1584 }
1585 // CYJ.NOTE TX Failure Detection
1586 if (IS_INT_FAIL_ENABLE() && (TX_FAIL_RECORD()!=0))
1587 {
1588 DISABLE_ALL_TX_INT();
1589 SetCECStatus(STATE_HW_RETX);
1590
1591 if (TX_FAIL_MAX()|IS_TX_FSM_FAIL())
1592 {
1593 HDMI_CEC_LOG("TX Fail: %x\n", TX_FAIL_RECORD());
1594 HDMI_CEC_LOG("TX Fail MAX\n");
1595 }
1596 else
1597 {
1598 HDMI_CEC_LOG("TX Fail: %x\n", TX_FAIL_RECORD());
1599 }
1600 }
1601 HDMI_CEC_LOG("TX HW FSM: %x\n", TX_FSM_STATUS());
1602 }
1603
1604 if (IS_RX_Q_EMPTY())
1605 return 0;
1606 else
1607 return 1;
1608 }
1609
1610 void CECMWSetLA(CEC_LA_ADDRESS* prLA)
1611 {
1612 HDMI_CEC_FUNC();
1613
1614 memcpy(&_rCECLaAddr, prLA, sizeof(CEC_LA_ADDRESS));
1615
1616 ASSERT(_rCECLaAddr.ui1_num <= 3);
1617
1618 if (_rCECLaAddr.ui1_num == 0)
1619 {
1620 SET_LA3(0x0F);
1621 SET_LA2(0x0F);
1622 SET_LA1(0x0F);
1623 _rCECLaAddr.aui1_la[0] = 0x0F;
1624 _rCECLaAddr.aui1_la[1] = 0x0F;
1625 _rCECLaAddr.aui1_la[2] = 0x0F;
1626 }
1627 else if (_rCECLaAddr.ui1_num == 1)
1628 {
1629 SET_LA3(0x0F);
1630 SET_LA2(0x0F);
1631 SET_LA1(_rCECLaAddr.aui1_la[0]);
1632 _rCECLaAddr.aui1_la[1] = 0x0F;
1633 _rCECLaAddr.aui1_la[2] = 0x0F;
1634 }
1635 else if (_rCECLaAddr.ui1_num == 2)
1636 {
1637 SET_LA3(0x0F);
1638 SET_LA2(_rCECLaAddr.aui1_la[1]);
1639 SET_LA1(_rCECLaAddr.aui1_la[0]);
1640 _rCECLaAddr.aui1_la[2] = 0x0F;
1641 }
1642 else if (_rCECLaAddr.ui1_num == 3)
1643 {
1644 SET_LA3(_rCECLaAddr.aui1_la[2]);
1645 SET_LA2(_rCECLaAddr.aui1_la[1]);
1646 SET_LA1(_rCECLaAddr.aui1_la[0]);
1647 }
1648
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);
1652 }
1653
1654 void hdmi_CECMWSetLA(CEC_DRV_ADDR_CFG_T* prAddr)
1655 {
1656 CEC_LA_ADDRESS rLA;
1657
1658 HDMI_CEC_FUNC();
1659
1660 if (prAddr->ui1_la_num > 3)
1661 {
1662 return ;
1663 }
1664
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;
1670 CECMWSetLA(&rLA);
1671 }
1672
1673 void hdmi_CECMWGet(CEC_FRAME_DESCRIPTION* frame)
1674 {
1675 HDMI_CEC_FUNC();
1676 memcpy(frame, cec_receive_msg, sizeof(CEC_FRAME_DESCRIPTION));
1677 cec_msg_report_pending = 0;
1678 }
1679
1680 void hdmi_CECMWSend(CEC_SEND_MSG_T* msg)
1681 {
1682 unsigned int i4Ret;
1683 unsigned char i;
1684
1685 HDMI_CEC_FUNC();
1686
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))
1688 {
1689 HDMI_CEC_LOG("apk send msg error\n");
1690 return ;
1691 }
1692
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)
1699 {
1700 cecMwTxMsg.size = 1;
1701 }
1702 else
1703 {
1704 cecMwTxMsg.blocks.opcode = msg->t_frame_info.ui2_opcode;
1705 cecMwTxMsg.size = msg->t_frame_info.z_operand_size + 2;
1706 }
1707 for (i=0; i<cecMwTxMsg.size-2; i++)
1708 {
1709 cecMwTxMsg.blocks.operand[i] = msg->t_frame_info.aui1_operand[i];
1710 }
1711
1712 i4Ret = _CEC_TX_Enqueue(&cecMwTxMsg);
1713 if (i4Ret == 0x01)
1714 {
1715 msg->b_enqueue_ok = FALSE;
1716 HDMI_CEC_LOG("MW Set cmd fail \n");
1717 return ;
1718 }
1719 else
1720 {
1721 msg->b_enqueue_ok = TRUE;
1722 HDMI_CEC_LOG("MW Set cmd sucess \n");
1723 return ;
1724 }
1725
1726 }
1727
1728 void hdmi_CECMWSetEnableCEC(unsigned char u1EnCec)
1729 {
1730 HDMI_CEC_FUNC();
1731
1732 hdmi_cec_init();
1733
1734 if (u1EnCec == 1)
1735 {
1736 HDMI_CEC_LOG("UI ON \n");
1737 hdmi_cec_on = 1;
1738 cec_timer_wakeup();
1739 }
1740 else
1741 {
1742 HDMI_CEC_LOG("UI off \n");
1743 hdmi_cec_on = 0;
1744 DISABLE_RX_EN();
1745 DISABLE_TX_EN();
1746 }
1747 }
1748
1749 void hdmi_NotifyApiCECAddress(CEC_ADDRESS *cecaddr)
1750 {
1751 HDMI_CEC_FUNC();
1752
1753 cecaddr->ui2_pa = _rCECPhysicAddr.ui2_pa;
1754 cecaddr->ui1_la = _rCECPhysicAddr.ui1_la;
1755 }
1756
1757 void hdmi_SetPhysicCECAddress(unsigned short u2pa, unsigned char u1la)
1758 {
1759 HDMI_CEC_LOG("u2pa=%x,u1la=%x\n",u2pa,u1la);
1760
1761 _rCECPhysicAddr.ui2_pa = u2pa;
1762 _rCECPhysicAddr.ui1_la = u1la;
1763 }
1764 extern size_t hdmi_hotplugstate;
1765 void hdmi_cec_usr_cmd(unsigned int cmd, unsigned int* result)
1766 {
1767 switch(cmd)
1768 {
1769 case 0:
1770 *result = cec_msg_report_pending;
1771 break;
1772 case 1 :
1773 *result = hdmi_hotplugstate;
1774 printk("[hdmi]hdmi_hotplugstate=%d\n",hdmi_hotplugstate);
1775 break;
1776 case 2:
1777 printk("[xubo]debug irq\n");
1778 hdmi_hotplugstate = 1;
1779 break;
1780 case 3:
1781 hdmi_CECMWSetEnableCEC(1);
1782 break;
1783 case 4:
1784 hdmi_CECMWSetEnableCEC(0);
1785 break;
1786 default:
1787 break;
1788 }
1789 }
1790 #endif