mt8193cec.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. #ifdef HDMI_MT8193_SUPPORT
  2. #include <linux/interrupt.h>
  3. #include <linux/i2c.h>
  4. #include <linux/slab.h>
  5. #include <linux/irq.h>
  6. #include <linux/miscdevice.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/delay.h>
  9. #include <linux/input.h>
  10. #include <linux/workqueue.h>
  11. #include <linux/kobject.h>
  12. #ifdef CONFIG_HAS_EARLYSUSPEND
  13. #include <linux/earlysuspend.h>
  14. #endif
  15. #include <linux/platform_device.h>
  16. #include <asm/atomic.h>
  17. #include <linux/init.h>
  18. #include <linux/module.h>
  19. #include <linux/sched.h>
  20. #include <linux/kthread.h>
  21. #include <linux/bitops.h>
  22. #include <linux/kernel.h>
  23. #include <linux/byteorder/generic.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/time.h>
  26. #include <linux/rtpm_prio.h>
  27. #include <linux/dma-mapping.h>
  28. #include <linux/syscalls.h>
  29. #include <linux/reboot.h>
  30. #include <linux/vmalloc.h>
  31. #include <linux/fs.h>
  32. #include <linux/string.h>
  33. #include <linux/completion.h>
  34. #include <linux/types.h>
  35. #include <linux/types.h>
  36. #include "mach/irqs.h"
  37. #include "hdmi_drv.h"
  38. #include "mt8193hdcp.h"
  39. #include "mt8193_ctrl.h"
  40. #include "mt8193cec.h"
  41. #define ENABLE_CEC_IRQ() (mt8193_write(0x1500, 0x20))
  42. #define DISABLE_CEC_IRQ() (mt8193_write(0x1500, 0x0))
  43. #define CLR_CEC_IRQ() (mt8193_write(0x1504, 0x20))
  44. static unsigned short _CEC_Status;
  45. #define SetCECStatus(arg) (_CEC_Status |= (arg))
  46. #define ClrCECStatus(arg) (_CEC_Status &= (~(arg)))
  47. #define IsCECStatus(arg) ((_CEC_Status & (arg)) > 0)
  48. static unsigned short _CEC_ErrStatus;
  49. #define SetCECErrorFlag(arg) (_CEC_ErrStatus |= (arg))
  50. #define ClrCECErrorFlag(arg) (_CEC_ErrStatus &= (~(arg)))
  51. #define IsCECErrorFlag(arg) ((_CEC_ErrStatus & (arg)) > 0)
  52. static CEC_FRAME_DESCRIPTION ActiveRXFrame;
  53. static CEC_FRAME_DESCRIPTION CTSTestFrame;
  54. #define HDMICEC_BASE (0x1600)
  55. /*----------------------------------------------------------------------------*/
  56. unsigned int mt8193_cec_read(unsigned short u2Reg)
  57. {
  58. unsigned int u4Data;
  59. mt8193_i2c_read(HDMICEC_BASE + u2Reg, &u4Data);
  60. MT8193_CEC_LOG("[R]cec = 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
  61. return u4Data;
  62. }
  63. void mt8193_cec_write(unsigned short u2Reg, unsigned int u4Data)
  64. {
  65. MT8193_CEC_LOG("[W]cec= 0x%04x, data = 0x%08x\n", u2Reg, u4Data);
  66. mt8193_i2c_write(HDMICEC_BASE + u2Reg, u4Data);
  67. }
  68. void vRegWrite4BMsk(unsigned short reg16, unsigned int val32, unsigned int msk32)
  69. {
  70. MT8193_CEC_FUNC();
  71. val32 &= msk32;
  72. mt8193_cec_write(reg16, ((mt8193_cec_read(reg16)) & ~msk32) | val32);
  73. }
  74. unsigned int mt8193_cec_2n(unsigned int u4Data)
  75. {
  76. unsigned int u4resultvalue = 1;
  77. unsigned char u1number;
  78. /* MT8193_CEC_FUNC(); */
  79. if (u4Data == 0)
  80. return 0; /* must be not 0 */
  81. if (u4Data == 0x20)
  82. return 0xffffffff;
  83. if (u4Data > 0x20)
  84. return 0; /* must not exceed over 0x20 */
  85. for (u1number = 0; u1number < u4Data; u1number++)
  86. u4resultvalue *= 2;
  87. return (u4resultvalue - 1);
  88. }
  89. unsigned int mt8193_cec_maskvalue(unsigned int u4Width, unsigned int u4Startbit)
  90. {
  91. unsigned int u4Data = 0xffffffff, i;
  92. /* MT8193_CEC_FUNC(); */
  93. for (i = 0; i < u4Width; i++)
  94. u4Data &= (~(mt8193_cec_2n(u4Startbit + i) + 1));
  95. return u4Data;
  96. }
  97. static CEC_FRAME_DESCRIPTION CEC_rx_msg_queue[RX_Q_SIZE];
  98. static CEC_FRAME_DESCRIPTION CEC_tx_msg_queue[TX_Q_SIZE];
  99. CEC_FRAME_DESCRIPTION *ActiveTXFrame;
  100. CEC_LA_ADDRESS _rCECLaAddr;
  101. static CEC_FRAME_DESCRIPTION cecMwTxMsg;
  102. CEC_ADDRESS _rCECPhysicAddr;
  103. static unsigned char _u1TxFailCause;
  104. static unsigned char _u1ReTxCnt;
  105. static unsigned char CEC_rxQ_read_idx;
  106. static unsigned char CEC_rxQ_write_idx;
  107. static unsigned char CEC_txQ_read_idx;
  108. static unsigned char CEC_txQ_write_idx;
  109. static unsigned char _fgUICECEnable;
  110. #define IS_RX_Q_EMPTY() (CEC_rxQ_read_idx == CEC_rxQ_write_idx)
  111. #define IS_RX_Q_FULL() (((CEC_rxQ_write_idx+1)%RX_Q_SIZE) == CEC_rxQ_read_idx)
  112. #define IS_TX_Q_EMPTY() (CEC_txQ_read_idx == CEC_txQ_write_idx)
  113. #define IS_TX_Q_FULL() (((CEC_txQ_write_idx+1)%TX_Q_SIZE) == CEC_txQ_read_idx)
  114. #define u1RegRead1B(reg16) (mt8193_cec_read(reg16)&0xff)
  115. #define u4RegRead4B(reg16) (mt8193_cec_read(reg16))
  116. #define RegReadFldAlign(reg16, fld) \
  117. ((mt8193_cec_read(reg16)>>(Fld_shft(fld)))&(mt8193_cec_2n(Fld_wid(fld))))
  118. #define vRegWriteFldAlign(reg16, val, fld) (mt8193_cec_write(reg16,\
  119. (((mt8193_cec_read(reg16))&(mt8193_cec_maskvalue(Fld_wid(fld), Fld_shft(fld))))|(val<<(Fld_shft(fld))))))
  120. #define IS_INT_DATA_RDY() (RegReadFldAlign(RX_EVENT, DATA_RDY))
  121. #define IS_INT_HEADER_RDY() (RegReadFldAlign(RX_EVENT, HEADER_RDY))
  122. #define IS_INT_MODE_RDY() (RegReadFldAlign(RX_EVENT, MODE_RDY))
  123. #define IS_INT_OV() (RegReadFldAlign(RX_EVENT, OV))
  124. #define IS_INT_BR_SB_RDY() (RegReadFldAlign(RX_EVENT, BR_SB_RDY))
  125. #define IS_INT_SB_RDY() (RegReadFldAlign(RX_EVENT, SB_RDY))
  126. #define IS_INT_BR_RDY() (RegReadFldAlign(RX_EVENT, BR_RDY))
  127. #define ENABLE_INT_DATA_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_DATA)
  128. #define ENABLE_INT_HEADER_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_HEADER)
  129. #define ENABLE_INT_MODE_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_MODE)
  130. #define ENABLE_INT_OV(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_OV)
  131. #define ENABLE_INT_PULSE(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_PULSE)
  132. #define ENABLE_INT_BR_SB_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_BR_SB)
  133. #define ENABLE_INT_SB_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_SB)
  134. #define ENABLE_INT_BR_RDY(onoff) vRegWriteFldAlign(RX_EVENT, onoff, I_EN_BR)
  135. #define CLR_INT_DATA_RDY() vRegWriteFldAlign(RX_EVENT, 0, DATA_RDY)
  136. #define CLR_INT_HEADER_RDY() vRegWriteFldAlign(RX_EVENT, 0, HEADER_RDY)
  137. #define CLR_INT_MODE_RDY() vRegWriteFldAlign(RX_EVENT, 0, MODE_RDY)
  138. #define CLR_INT_OV() vRegWriteFldAlign(RX_EVENT, 0, OV)
  139. #define NOTIFY_RX_HW_DATA_TAKEN() vRegWriteFldAlign(RX_EVENT, 0, BR_RDY)
  140. #define HW_RX_DATA_ARRIVED() IS_INT_BR_RDY()
  141. #define HW_RX_HEADER_ARRIVED() IS_INT_HEADER_RDY()
  142. /* TX_EVENT */
  143. #define IS_INT_UN() (RegReadFldAlign(TX_EVENT, UN))
  144. #define IS_INT_LOW() (RegReadFldAlign(TX_EVENT, LOWB))
  145. #define IS_TX_FINISH() (RegReadFldAlign(TX_EVENT, BS))
  146. #define IS_INT_RB_RDY() (RegReadFldAlign(TX_EVENT, RB_RDY))
  147. #define ENABLE_INT_UN(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_UN)
  148. #define ENABLE_INT_FAIL(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_FAIL)
  149. #define ENABLE_INT_LOW(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_LOW)
  150. #define ENABLE_INT_BS(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_BS)
  151. #define ENABLE_INT_RB(onoff) vRegWriteFldAlign(TX_EVENT, onoff, I_EN_RB)
  152. #define CLR_INT_UN() vRegWriteFldAlign(TX_EVENT, 0, UN)
  153. #define CLR_INT_LOW() vRegWriteFldAlign(TX_EVENT, 0, LOWB)
  154. #define CLR_TX_FINISH() vRegWriteFldAlign(TX_EVENT, 0, BS)
  155. #define TRIGGER_TX_HW() vRegWriteFldAlign(TX_EVENT, 1, RB_RDY)
  156. #define IS_TX_DATA_TAKEN() (!(IS_INT_RB_RDY()))
  157. #define IS_INT_RB_ENABLE() (RegReadFldAlign(TX_EVENT, I_EN_RB))
  158. #define IS_INT_FAIL_ENABLE() (RegReadFldAlign(TX_EVENT, I_EN_FAIL))
  159. #define DISABLE_ALL_TX_INT() \
  160. do { \
  161. ENABLE_INT_FAIL(0); \
  162. ENABLE_INT_RB(0); \
  163. ENABLE_INT_LOW(0); \
  164. ENABLE_INT_UN(0); \
  165. ENABLE_INT_BS(0); \
  166. } while (0)
  167. /* RX FSM status */
  168. #define IS_RX_FSM_IDLE() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x01)
  169. #define IS_RX_FSM_START() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x02)
  170. #define IS_RX_FSM_MODE() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x04)
  171. #define IS_RX_FSM_MODE1_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x08)
  172. #define IS_RX_FSM_MODE1_ARB() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x10)
  173. #define IS_RX_FSM_MODE1_FLAG() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x20)
  174. #define IS_RX_FSM_MODE2_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x40)
  175. #define IS_RX_FSM_MODE2_CMD() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x80)
  176. #define IS_RX_FSM_MODE3_ID() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0100)
  177. #define IS_RX_FSM_MODE3_HEADER() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0200)
  178. #define IS_RX_FSM_MODE3_DATA() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0400)
  179. #define IS_RX_FSM_GENERAL() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x0800)
  180. #define IS_RX_FSM_ERROR_S() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x1000)
  181. #define IS_RX_FSM_ERROR_D() (RegReadFldAlign(RX_STATUS, RX_FSM) == 0x2000)
  182. #define RX_FSM_STATUS() (RegReadFldAlign(RX_STATUS, RX_FSM))
  183. /* TX FSM status */
  184. #define IS_TX_FSM_IDLE() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x01)
  185. #define IS_TX_FSM_INIT() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x02)
  186. #define IS_TX_FSM_EOM() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x04)
  187. #define IS_TX_FSM_RETRASMIT() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x08)
  188. #define IS_TX_FSM_FAIL() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x10)
  189. #define IS_TX_FSM_START() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x20)
  190. #define IS_TX_FSM_MODE() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x40)
  191. #define IS_TX_FSM_MODE1_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x80)
  192. #define IS_TX_FSM_MODE1_DATA() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x100)
  193. #define IS_TX_FSM_MODE2_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x200)
  194. #define IS_TX_FSM_MODE2_CMD() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x400)
  195. #define IS_TX_FSM_MODE3_ID() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x800)
  196. #define IS_TX_FSM_MODE3_HEADER() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x1000)
  197. #define IS_TX_FSM_MODE3_DATA() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x2000)
  198. #define IS_TX_FSM_GENERAL() (RegReadFldAlign(TX_STATUS, TX_FSM) == 0x4000)
  199. #define TX_FSM_STATUS() (RegReadFldAlign(TX_STATUS, TX_FSM))
  200. #define ENABLE_TX_EN() vRegWriteFldAlign(TR_CONFIG, 1, TX_EN)
  201. #define DISABLE_TX_EN() vRegWriteFldAlign(TR_CONFIG, 0, TX_EN)
  202. #define ENABLE_RX_EN() vRegWriteFldAlign(TR_CONFIG, 1, RX_EN)
  203. #define DISABLE_RX_EN() vRegWriteFldAlign(TR_CONFIG, 0, RX_EN)
  204. #define SET_HW_TX_LEN(num) vRegWriteFldAlign(TX_HD_NEXT, num, WTX_M3_DATA_MASK)
  205. #define FILL_SRC_FIELD(addr) vRegWriteFldAlign(TX_HD_NEXT, addr, WTX_SRC)
  206. #define FILL_DST_FIELD(addr) vRegWriteFldAlign(TX_HD_NEXT, addr, WTX_DST)
  207. #define MARK_H_EOM(onoff) vRegWriteFldAlign(TX_HD_NEXT, onoff, WTX_H_EOM)
  208. #define MARK_D_EOM(onoff) vRegWriteFldAlign(TX_HD_NEXT, onoff, WTX_D_EOM)
  209. #define FILL_TX_DATA(data) vRegWriteFldAlign(TX_DATA_NEXT, data, WTX_DATA)
  210. #define GET_HW_RX_LEN() (RegReadFldAlign(RX_HEADER, RXED_M3_DATA_MASK))
  211. #define GET_SRC_FIELD() (RegReadFldAlign(RX_HEADER, RXED_SRC))
  212. #define GET_DST_FIELD() (RegReadFldAlign(RX_HEADER, RXED_DST))
  213. #define GET_SRC_FIELD_RECEIVING() (RegReadFldAlign(RX_HD_NEXT, RXING_SRC))
  214. #define GET_DST_FIELD_RECEIVING() (RegReadFldAlign(RX_HD_NEXT, RXING_DST))
  215. #define IS_RX_H_EOM() (RegReadFldAlign(RX_HEADER, RXED_H_EOM))
  216. #define IS_RX_D_EOM() (RegReadFldAlign(RX_HEADER, RXED_D_EOM))
  217. #define GET_HW_RX_DATA() (RegReadFldAlign(RX_DATA, RXED_DATA))
  218. #define FLOW_CONTROL_ACK(onoff) \
  219. do {\
  220. vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_H_ACK);\
  221. vRegWriteFldAlign(RX_HD_NEXT, (!(onoff)), RXING_D_ACK);\
  222. } while (0)
  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. #define TX_FAIL_MAX() (RegReadFldAlign(TX_FAIL, RETX_MAX))
  226. #define CLR_TX_FAIL_MAX() vRegWriteFldAlign(TX_FAIL, 0, RETX_MAX)
  227. #define TX_FAIL_RECORD() u4RegRead4B(TX_FAIL)
  228. #define TX_FAIL_SOURCE() (RegReadFldAlign(TX_FAIL, SOURCE))
  229. #define CLR_TX_FAIL_SOURCE() vRegWriteFldAlign(TX_FAIL, 0, SOURCE)
  230. #define CHECK_RX_EN() (RegReadFldAlign(TR_CONFIG, RX_EN))
  231. #define SET_LA1(La1) vRegWriteFldAlign(TR_CONFIG, La1, DEVICE_ADDR)
  232. #define SET_LA2(La2) vRegWriteFldAlign(TR_CONFIG, La2, TR_DEVICE_ADDR2)
  233. #define SET_LA3(La3) vRegWriteFldAlign(TR_CONFIG, La3, TR_DEVICE_ADDR3)
  234. #define RESET_HW_TX() \
  235. do { \
  236. DISABLE_TX_EN();\
  237. ENABLE_TX_EN();\
  238. } while (0)
  239. #define GET_TX_BIT_COUNTER() (RegReadFldAlign(TX_STATUS, TX_BIT_COUNTER))
  240. /*----------------------------------------------------------------------------*/
  241. void vRegWrite4B(unsigned short u2Reg, unsigned int u4Data)
  242. {
  243. MT8193_CEC_FUNC();
  244. mt8193_cec_write(u2Reg, u4Data);
  245. }
  246. void mt8193_cec_init(void)
  247. {
  248. MT8193_CEC_FUNC();
  249. _rCECPhysicAddr.ui2_pa = 0xffff;
  250. _rCECPhysicAddr.ui1_la = 0x0;
  251. _CEC_Status = 0;
  252. _CEC_ErrStatus = 0;
  253. _u1TxFailCause = FAIL_NONE;
  254. _u1ReTxCnt = 0;
  255. CEC_rxQ_write_idx = 0;
  256. CEC_rxQ_read_idx = 0;
  257. CEC_txQ_write_idx = 0;
  258. CEC_txQ_read_idx = 0;
  259. _rCECLaAddr.aui1_la[0] = 0x0F;
  260. _rCECLaAddr.aui1_la[1] = 0x0F;
  261. _rCECLaAddr.aui1_la[2] = 0x0F;
  262. vRegWrite4B(CEC_CKGEN, 0x00020082); /* 3MHz //different from BD /100k */
  263. vRegWrite4B(TR_TEST, 0x40004019); /* Bpad enable¡BTx compared timing 0x19 */
  264. /* CYJ.NOTE TX_EN, RX_EN: disable it */
  265. vRegWrite4B(TR_CONFIG, 0x00000001);
  266. vRegWrite4B(RX_T_START_R, 0x01980154);
  267. vRegWrite4B(RX_T_START_F, 0x01e801a9);
  268. vRegWrite4B(RX_T_DATA, 0x006e00c8);
  269. vRegWrite4B(RX_T_ACK, 0x00000096);
  270. vRegWrite4B(RX_T_ERROR, 0x01680212);
  271. vRegWrite4B(TX_T_START, 0x01c20172);
  272. vRegWrite4B(TX_T_DATA_R, 0x003c0096);
  273. vRegWrite4B(TX_T_DATA_F, 0x00f000f0);
  274. vRegWrite4B(TX_ARB, 0x00000596);
  275. /* turn off interrupt of general mode */
  276. vRegWrite4B(TX_GEN_INTR, 0x00000000);
  277. vRegWrite4B(RX_CAP_90, 0x00000000);
  278. vRegWrite4B(TX_GEN_MASK, 0x00000000);
  279. vRegWrite4B(RX_GEN_WD, 0x00000000);
  280. vRegWrite4B(RX_GEN_MASK, 0x00000000);
  281. vRegWrite4B(RX_GEN_INTR, 0x00000000);
  282. FLOW_CONTROL_ACK(1);
  283. vRegWriteFldAlign(TX_HD_NEXT, 0, WTX_M3_ID);
  284. vRegWriteFldAlign(TX_HD_NEXT, 0, WTX_M1_DIR);
  285. vRegWriteFldAlign(TX_HD_NEXT, 0, WTX_M1_PAS);
  286. vRegWriteFldAlign(TX_HD_NEXT, 0, WTX_M1_NAS);
  287. vRegWriteFldAlign(TX_HD_NEXT, 0, WTX_M1_DES);
  288. vRegWriteFldAlign(TX_HD_NEXT, 3, WTX_MODE);
  289. vRegWrite4B(TR_CONFIG, 0x0fff1101);
  290. vRegWrite4BMsk(TX_EVENT, 0x00, 0xff);
  291. vRegWrite4BMsk(RX_EVENT, 0x00, 0xff);
  292. /* RX_EVENT */
  293. ENABLE_INT_OV(1);
  294. ENABLE_INT_BR_RDY(1);
  295. ENABLE_INT_HEADER_RDY(1);
  296. /* TX_EVENT */
  297. ENABLE_INT_UN(0);
  298. ENABLE_INT_LOW(0);
  299. ENABLE_INT_FAIL(0);
  300. ENABLE_INT_BS(0);
  301. ENABLE_INT_RB(0);
  302. /* la */
  303. SET_LA1(0x04);
  304. SET_LA2(0x05);
  305. SET_LA3(0x0f);
  306. }
  307. static unsigned char CEC_rx_enqueue(CEC_FRAME_DESCRIPTION *frame)
  308. {
  309. /* check if queue is full */
  310. MT8193_CEC_FUNC();
  311. if (IS_RX_Q_FULL())
  312. return FALSE;
  313. /* copy the new incoming message to rx queue */
  314. memcpy(&(CEC_rx_msg_queue[CEC_rxQ_write_idx]), frame, sizeof(CEC_FRAME_DESCRIPTION));
  315. /* CYJ.NOTE: no critical section */
  316. CEC_rxQ_write_idx = (CEC_rxQ_write_idx + 1) % RX_Q_SIZE;
  317. return TRUE;
  318. }
  319. static void _CEC_Receiving(void)
  320. {
  321. static unsigned char *size;
  322. static CEC_FRAME_DESCRIPTION *frame = &ActiveRXFrame;
  323. unsigned int data;
  324. unsigned char i, rxlen, is_d_eom, ret;
  325. MT8193_CEC_FUNC();
  326. /* no data available */
  327. if (!IS_INT_BR_RDY()) {
  328. /*ASSERT(0);*/
  329. return;
  330. }
  331. /* <polling message> only */
  332. if (GET_HW_RX_LEN() == 0) {
  333. NOTIFY_RX_HW_DATA_TAKEN();
  334. ClrCECStatus(STATE_RX_GET_NEW_HEADER); /* CM 20081210 */
  335. return;
  336. }
  337. /* new incoming message */
  338. if (IsCECStatus(STATE_RX_GET_NEW_HEADER)) {
  339. ClrCECStatus(STATE_RX_GET_NEW_HEADER);
  340. if (IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE)) {
  341. MT8193_CEC_LOG("[CEC] Lost EOM:2\n");
  342. SetCECErrorFlag(ERR_RX_LOST_EOM);
  343. }
  344. SetCECStatus(STATE_WAIT_RX_FRAME_COMPLETE);
  345. size = &(frame->size);
  346. (*size) = 0;
  347. frame->blocks.header.initiator = GET_SRC_FIELD();
  348. frame->blocks.header.destination = GET_DST_FIELD();
  349. (*size)++;
  350. }
  351. if (!IsCECStatus(STATE_WAIT_RX_FRAME_COMPLETE)) {
  352. NOTIFY_RX_HW_DATA_TAKEN();
  353. SetCECErrorFlag(ERR_RX_LOST_HEADER);
  354. return;
  355. }
  356. rxlen = GET_HW_RX_LEN();
  357. data = GET_HW_RX_DATA();
  358. is_d_eom = IS_RX_D_EOM();
  359. NOTIFY_RX_HW_DATA_TAKEN();
  360. if (rxlen == 0x3) {
  361. rxlen = 2;
  362. } else if (rxlen == 0x7) {
  363. rxlen = 3;
  364. } else if (rxlen == 0xf) {
  365. rxlen = 4;
  366. } else if (rxlen != 0x1) {
  367. MT8193_CEC_LOG("[CEC] invalid rx length occurs\n");
  368. /* assert(0); */
  369. }
  370. /* for opcode */
  371. if ((*size) == 1) {
  372. frame->blocks.opcode = data & 0xff;
  373. data >>= 8;
  374. (*size)++;
  375. rxlen--;
  376. }
  377. /* for operand */
  378. for (i = 0; i < rxlen; i++) {
  379. if ((*size) > 15) {
  380. MT8193_CEC_LOG("[CEC] Receive Data Length is wrong !\n");
  381. ; break;
  382. } else {
  383. /*ASSERT((*size) >= 2);*/
  384. frame->blocks.operand[(*size) - 2] = data & 0xff;
  385. data >>= 8;
  386. (*size)++;
  387. }
  388. }
  389. if (is_d_eom) {
  390. ClrCECStatus(STATE_WAIT_RX_FRAME_COMPLETE);
  391. SetCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
  392. /* push into rx_queue */
  393. ret = CEC_rx_enqueue(frame);
  394. if (ret == FALSE) {
  395. SetCECErrorFlag(ERR_RXQ_OVERFLOW);
  396. MT8193_CEC_LOG("[CEC] cec rx buffer overflow\n");
  397. /* ASSERT(0); */
  398. }
  399. }
  400. }
  401. static unsigned char _CEC_SendRemainingDataBlocks(void)
  402. {
  403. CEC_FRAME_DESCRIPTION *frame;
  404. unsigned char errcode = 0;
  405. unsigned char size;
  406. unsigned char *sendidx;
  407. unsigned char *blocks;
  408. unsigned int data;
  409. unsigned char i, j;
  410. MT8193_CEC_FUNC();
  411. if (!IsCECStatus(STATE_TXING_FRAME))
  412. return 0;
  413. if (IsCECStatus(STATE_WAIT_TX_DATA_TAKEN)) {
  414. if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN()) {
  415. ClrCECStatus(STATE_WAIT_TX_DATA_TAKEN);
  416. } else {
  417. /* tx buffer is not emply */
  418. return 0;
  419. }
  420. } else {
  421. return 0;
  422. }
  423. /* request current active TX frame */
  424. frame = ActiveTXFrame;
  425. size = frame->size;
  426. sendidx = &(frame->sendidx);
  427. blocks = &(frame->blocks.opcode);
  428. /* CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop */
  429. if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD() > 0)) {
  430. MT8193_CEC_LOG("[CEC] Detect TX FAIL in %s\n", __func__);
  431. return 3;
  432. /* RESET_HW_TX(); */
  433. /* ASSERT(0); */
  434. }
  435. size -= ((*sendidx) + 1);
  436. if (size == 0)
  437. return 0;
  438. /* CYJ:TODO duplicate (as _CEC_SendFrame())! */
  439. /* fill data */
  440. if (size > 4) {
  441. SET_HW_TX_LEN(0xf);
  442. MARK_H_EOM(0);
  443. MARK_D_EOM(0);
  444. } else if (size == 4) {
  445. SET_HW_TX_LEN(0xf);
  446. MARK_H_EOM(0);
  447. MARK_D_EOM(1);
  448. } else if (size == 3) {
  449. SET_HW_TX_LEN(0x7);
  450. MARK_H_EOM(0);
  451. MARK_D_EOM(1);
  452. } else if (size == 2) {
  453. SET_HW_TX_LEN(0x3);
  454. MARK_H_EOM(0);
  455. MARK_D_EOM(1);
  456. } else if (size == 1) {
  457. SET_HW_TX_LEN(0x1);
  458. MARK_H_EOM(0);
  459. MARK_D_EOM(1);
  460. }
  461. data = 0;
  462. for (i = 0, j = size; i < 4; i++) {
  463. data >>= 8;
  464. data |= (blocks[(*sendidx)]) << 24;
  465. if (i < j) {
  466. (*sendidx)++;
  467. size--;
  468. }
  469. }
  470. /* EOM */
  471. if (size == 0) {
  472. ENABLE_INT_FAIL(1);
  473. ENABLE_INT_RB(0);
  474. ENABLE_INT_LOW(0);
  475. ENABLE_INT_UN(0);
  476. ENABLE_INT_BS(0);
  477. } else {
  478. ENABLE_INT_FAIL(1);
  479. ENABLE_INT_RB(1);
  480. ENABLE_INT_LOW(1);
  481. ENABLE_INT_UN(1);
  482. ENABLE_INT_BS(0);
  483. SetCECStatus(STATE_WAIT_TX_DATA_TAKEN);
  484. }
  485. FILL_TX_DATA(data);
  486. MT8193_CEC_LOG("[CEC] TRIGGER_TX_HW in %s, size: %x\n", __func__, size);
  487. CLR_TX_FINISH();
  488. TRIGGER_TX_HW();
  489. return errcode;
  490. }
  491. static void _CEC_Check_Active_Tx_Result(void)
  492. {
  493. MT8193_CEC_FUNC();
  494. if (IsCECStatus(STATE_TXING_FRAME)) {
  495. if (IsCECStatus(STATE_HW_RETX)) {
  496. if (TX_FAIL_SOURCE()) {
  497. _u1TxFailCause = FAIL_SOURCE;
  498. CLR_TX_FAIL_SOURCE();
  499. }
  500. if ((TX_FAIL_RECORD() != 0)) {
  501. DISABLE_ALL_TX_INT();
  502. SetCECStatus(STATE_TX_NOACK);
  503. ClrCECStatus(STATE_HW_RETX);
  504. ClrCECStatus(STATE_TXING_FRAME);
  505. if (IS_TX_FSM_FAIL())
  506. MT8193_CEC_LOG("[CEC] TX NO ACK\n");
  507. else
  508. MT8193_CEC_LOG("[CEC] other TX error\n");
  509. MT8193_CEC_LOG("[CEC] H ACK: %x, D ACK: %x\n", GET_FOLLOWER_H_ACK(),
  510. GET_FOLLOWER_D_ACK());
  511. RESET_HW_TX();
  512. }
  513. } else if ((ActiveTXFrame->sendidx + 1) == (ActiveTXFrame->size)) {
  514. if (IS_TX_FSM_IDLE() && IS_TX_FINISH()) {
  515. DISABLE_ALL_TX_INT();
  516. SetCECStatus(STATE_TX_FRAME_SUCCESS);
  517. ClrCECStatus(STATE_TXING_FRAME);
  518. MT8193_CEC_LOG
  519. ("[CEC] TX is COMPLETED with: H ACK: %x and D ACK %x\n",
  520. (unsigned int)GET_FOLLOWER_H_ACK(),
  521. (unsigned int)GET_FOLLOWER_D_ACK());
  522. }
  523. }
  524. }
  525. }
  526. static CEC_FRAME_DESCRIPTION *_CEC_Get_Cur_TX_Q_Msg(void)
  527. {
  528. MT8193_CEC_FUNC();
  529. if (IS_TX_Q_EMPTY())
  530. return NULL;
  531. return (&(CEC_tx_msg_queue[CEC_txQ_read_idx]));
  532. }
  533. static unsigned char _CEC_TX_Dequeue(void)
  534. {
  535. MT8193_CEC_FUNC();
  536. if (IS_TX_Q_EMPTY())
  537. return FALSE;
  538. /* CYJ.NOTE: no critical section */
  539. CEC_txQ_read_idx = (CEC_txQ_read_idx + 1) % TX_Q_SIZE;
  540. return TRUE;
  541. }
  542. static void PrintFrameDescription(CEC_FRAME_DESCRIPTION *frame)
  543. {
  544. unsigned char i;
  545. MT8193_CEC_LOG("[CEC] >>>>>>>>>>>>>>>>>>>>>>>>\n");
  546. MT8193_CEC_LOG("[CEC] frame description:\n");
  547. MT8193_CEC_LOG("[CEC] size: 0x%x\n", frame->size);
  548. MT8193_CEC_LOG("[CEC] sendidx: 0x%x\n", frame->sendidx);
  549. MT8193_CEC_LOG("[CEC] reTXcnt: 0x%x\n", frame->reTXcnt);
  550. MT8193_CEC_LOG("[CEC] initiator: 0x%x\n", frame->blocks.header.initiator);
  551. MT8193_CEC_LOG("[CEC] destination: 0x%x\n", frame->blocks.header.destination);
  552. if (frame->size > 1)
  553. MT8193_CEC_LOG("[CEC] opcode: 0x%x\n", frame->blocks.opcode);
  554. if ((frame->size > 2) && (frame->size <= 16)) {
  555. for (i = 0; i < (frame->size - 2); i++)
  556. MT8193_CEC_LOG("0x%02x\n", frame->blocks.operand[i]);
  557. }
  558. MT8193_CEC_LOG("[CEC]<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
  559. }
  560. static unsigned char _CEC_SendFrame(CEC_FRAME_DESCRIPTION *frame)
  561. {
  562. unsigned char errcode = 0;
  563. unsigned char size;
  564. unsigned char *sendidx;
  565. unsigned char *blocks;
  566. unsigned int data;
  567. unsigned char i, j;
  568. MT8193_CEC_FUNC();
  569. if (IsCECStatus(STATE_TXING_FRAME))
  570. return 1;
  571. SetCECStatus(STATE_TXING_FRAME);
  572. /* CYJ.NOTE: Leave "TX hardware error handling" to _CEC_Mainloop */
  573. if (IS_TX_FSM_FAIL() | (TX_FAIL_RECORD() > 0)) {
  574. MT8193_CEC_LOG("[CEC] Detect TX FAIL in %s\n", __func__);
  575. /* return 3; */
  576. RESET_HW_TX();
  577. /* ASSERT(0); // CAN NOT HAPPEN HERE */
  578. }
  579. size = frame->size;
  580. sendidx = &(frame->sendidx);
  581. blocks = &(frame->blocks.opcode);
  582. if (size == 0) {
  583. ClrCECStatus(STATE_TXING_FRAME);
  584. return 2;
  585. } else if (size > 16) {
  586. ClrCECStatus(STATE_TXING_FRAME);
  587. return 2;
  588. }
  589. /* CYJ.NOTE: TX HW is not idle */
  590. if (!IS_TX_FSM_IDLE())
  591. RESET_HW_TX();
  592. ActiveTXFrame = frame;
  593. ClrCECStatus(STATE_TX_FRAME_SUCCESS);
  594. ClrCECStatus(STATE_TX_NOACK);
  595. /* fill header */
  596. FILL_SRC_FIELD(frame->blocks.header.initiator);
  597. FILL_DST_FIELD(frame->blocks.header.destination);
  598. size -= 1;
  599. /* header-only */
  600. if (size == 0) {
  601. SET_HW_TX_LEN(0);
  602. MARK_H_EOM(1);
  603. MARK_D_EOM(0);
  604. /* TRIGGER_TX_HW(); */
  605. size = 0;
  606. }
  607. /* fill data */
  608. if (size > 4) {
  609. SET_HW_TX_LEN(0xf);
  610. MARK_H_EOM(0);
  611. MARK_D_EOM(0);
  612. } else if (size == 4) {
  613. SET_HW_TX_LEN(0xf);
  614. MARK_H_EOM(0);
  615. MARK_D_EOM(1);
  616. } else if (size == 3) {
  617. SET_HW_TX_LEN(0x7);
  618. MARK_H_EOM(0);
  619. MARK_D_EOM(1);
  620. } else if (size == 2) {
  621. SET_HW_TX_LEN(0x3);
  622. MARK_H_EOM(0);
  623. MARK_D_EOM(1);
  624. } else if (size == 1) {
  625. SET_HW_TX_LEN(0x1);
  626. MARK_H_EOM(0);
  627. MARK_D_EOM(1);
  628. }
  629. data = 0;
  630. for (i = 0, j = size; i < 4; i++) {
  631. data >>= 8;
  632. data |= (blocks[(*sendidx)]) << 24;
  633. if (i < j) {
  634. (*sendidx)++;
  635. size--;
  636. }
  637. }
  638. /* EOM */
  639. if (size == 0) {
  640. ENABLE_INT_FAIL(1);
  641. ENABLE_INT_RB(0);
  642. ENABLE_INT_LOW(0);
  643. ENABLE_INT_UN(0);
  644. ENABLE_INT_BS(0);
  645. } else {
  646. ENABLE_INT_FAIL(1);
  647. ENABLE_INT_RB(1);
  648. ENABLE_INT_LOW(1);
  649. ENABLE_INT_UN(1);
  650. ENABLE_INT_BS(0);
  651. SetCECStatus(STATE_WAIT_TX_DATA_TAKEN);
  652. }
  653. FILL_TX_DATA(data);
  654. MT8193_CEC_LOG("[CEC] TRIGGER_TX_HW in %s, size: %x\n", __func__, size);
  655. CLR_TX_FINISH();
  656. _u1TxFailCause = FAIL_NONE;
  657. _u1ReTxCnt = 0;
  658. TRIGGER_TX_HW();
  659. return errcode;
  660. }
  661. static void _CEC_TX_Queue_Loop(void)
  662. {
  663. CEC_FRAME_DESCRIPTION *frame;
  664. /* MT8193_CEC_FUNC(); */
  665. /* if the tx message queue is empty */
  666. if (IS_TX_Q_EMPTY())
  667. return;
  668. /* if the tx is active, check the result */
  669. if (IsCECStatus(STATE_TXING_FRAME)) {
  670. if (IsCECErrorFlag(ERR_TX_MISALARM) && (TX_FAIL_RECORD() != 0) && IS_TX_FSM_FAIL()) {
  671. DISABLE_ALL_TX_INT();
  672. ClrCECErrorFlag(ERR_TX_MISALARM);
  673. SetCECStatus(STATE_TX_NOACK);
  674. ClrCECStatus(STATE_HW_RETX);
  675. ClrCECStatus(STATE_TXING_FRAME);
  676. RESET_HW_TX();
  677. }
  678. _CEC_Check_Active_Tx_Result();
  679. if (IsCECStatus(STATE_TX_FRAME_SUCCESS)) {
  680. MT8193_CEC_LOG("[CEC] This message is successful\n");
  681. frame = _CEC_Get_Cur_TX_Q_Msg();
  682. /*
  683. if (frame == NULL)
  684. ASSERT(0);
  685. */
  686. _CEC_TX_Dequeue();
  687. ClrCECStatus(STATE_TX_FRAME_SUCCESS);
  688. }
  689. if (IsCECStatus(STATE_TX_NOACK)) {
  690. frame = _CEC_Get_Cur_TX_Q_Msg();
  691. /*
  692. if (frame == NULL)
  693. ASSERT(0);
  694. */
  695. MT8193_CEC_LOG("[CEC] This message is failed: %d\n", frame->reTXcnt);
  696. frame->reTXcnt++;
  697. frame->sendidx = 0;
  698. ClrCECStatus(STATE_TX_NOACK);
  699. /* CYJ.NOTE: retransmission */
  700. if (frame->reTXcnt == RETX_MAX_CNT) {
  701. _u1TxFailCause = FAIL_NONE;
  702. MT8193_CEC_LOG("[CEC] ReTX reach MAX\n");
  703. _CEC_TX_Dequeue();
  704. }
  705. }
  706. } else
  707. /* if the tx is not active, send the next message */
  708. {
  709. frame = _CEC_Get_Cur_TX_Q_Msg();
  710. /*
  711. if (frame == NULL)
  712. ASSERT(0);
  713. */
  714. if (_u1TxFailCause == FAIL_SOURCE) {
  715. if (_u1ReTxCnt < 15) {
  716. _u1ReTxCnt++;
  717. ; return;
  718. } else {
  719. _u1ReTxCnt = 0;
  720. }
  721. }
  722. MT8193_CEC_LOG("[CEC] Send a new message\n");
  723. PrintFrameDescription(frame);
  724. _CEC_SendFrame(frame);
  725. }
  726. }
  727. static CEC_FRAME_DESCRIPTION *CEC_rx_dequeue(void)
  728. {
  729. CEC_FRAME_DESCRIPTION *ret;
  730. /* MT8193_CEC_FUNC(); */
  731. /* check if queue is empty */
  732. if (IS_RX_Q_EMPTY())
  733. return NULL;
  734. /* return next available entry for middleware */
  735. ret = &(CEC_rx_msg_queue[CEC_rxQ_read_idx]);
  736. /* CYJ.NOTE: no critical section */
  737. CEC_rxQ_read_idx = (CEC_rxQ_read_idx + 1) % RX_Q_SIZE;
  738. return ret;
  739. }
  740. static unsigned char CEC_frame_validation(CEC_FRAME_DESCRIPTION *frame)
  741. {
  742. unsigned char size = frame->size;
  743. unsigned char i1ret = TRUE;
  744. MT8193_CEC_FUNC();
  745. /* opcode-aware */
  746. /* CYJ.NOTE: code size issue */
  747. switch (frame->blocks.opcode) {
  748. /* length == 2 */
  749. case OPCODE_IMAGE_VIEW_ON:
  750. case OPCODE_TEXT_VIEW_ON:
  751. case OPCODE_REQUEST_ACTIVE_SOURCE:
  752. case OPCODE_STANDBY:
  753. case OPCODE_RECORD_OFF:
  754. case OPCODE_RECORD_TV_SCREEN:
  755. case OPCODE_GET_CEC_VERSION:
  756. case OPCODE_GIVE_PHYSICAL_ADDRESS:
  757. case OPCODE_GET_MENU_LANGUAGE:
  758. case OPCODE_TUNER_STEP_DECREMENT:
  759. case OPCODE_TUNER_STEP_INCREMENT:
  760. case OPCODE_GIVE_DEVICE_VENDOR_ID:
  761. case OPCODE_VENDOR_REMOTE_BUTTON_UP:
  762. case OPCODE_GIVE_OSD_NAME:
  763. case OPCODE_USER_CONTROL_RELEASED:
  764. case OPCODE_GIVE_DEVICE_POWER_STATUS:
  765. case OPCODE_ABORT:
  766. case OPCODE_GIVE_AUDIO_STATUS:
  767. case OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS:
  768. if (size != 2)
  769. i1ret = FALSE;
  770. break;
  771. case OPCODE_SYSTEM_AUDIO_MODE_REQUEST:
  772. if ((size != 2) && (size != 4))
  773. i1ret = FALSE;
  774. break;
  775. /* length == 3 */
  776. case OPCODE_RECORD_STATUS:
  777. case OPCODE_TIMER_CLEARED_STATUS:
  778. case OPCODE_CEC_VERSION:
  779. case OPCODE_DECK_CONTROL:
  780. case OPCODE_DECK_STATUS:
  781. case OPCODE_GIVE_DECK_STATUS:
  782. case OPCODE_PLAY:
  783. case OPCODE_GIVE_TUNER_DEVICE_STATUS:
  784. case OPCODE_MENU_REQUEST:
  785. case OPCODE_MENU_STATUS:
  786. case OPCODE_REPORT_POWER_STATUS:
  787. case OPCODE_REPORT_AUDIO_STATUS:
  788. case OPCODE_SET_SYSTEM_AUDIO_MODE:
  789. case OPCODE_SYSTEM_AUDIO_MODE_STATUS:
  790. case OPCODE_SET_AUDIO_RATE:
  791. if (size != 3)
  792. i1ret = FALSE;
  793. break;
  794. case OPCODE_USER_CONTROL_PRESSED:
  795. if ((size != 3) && (size != 4))
  796. i1ret = FALSE;
  797. break;
  798. /* length == 4 */
  799. case OPCODE_ACTIVE_SOURCE:
  800. case OPCODE_INACTIVE_SOURCE:
  801. case OPCODE_ROUTING_INFORMATION:
  802. case OPCODE_SET_STREAM_PATH:
  803. case OPCODE_FEATURE_ABORT:
  804. if (size != 4)
  805. i1ret = FALSE;
  806. break;
  807. /* length == 5 */
  808. case OPCODE_REPORT_PHYSICAL_ADDRESS:
  809. case OPCODE_SET_MENU_LANGUAGE:
  810. case OPCODE_DEVICE_VENDOR_ID:
  811. if (size != 5)
  812. i1ret = FALSE;
  813. break;
  814. /* length == 6 */
  815. case OPCODE_ROUTING_CHANGE:
  816. case OPCODE_SELECT_ANALOGUE_SERVICE:
  817. if (size != 6)
  818. i1ret = FALSE;
  819. break;
  820. /* length == 9 */
  821. case OPCODE_SELECT_DIGITAL_SERVICE:
  822. if (size != 9)
  823. i1ret = FALSE;
  824. break;
  825. /* length == 13 */
  826. case OPCODE_CLEAR_ANALOGUE_TIMER:
  827. case OPCODE_SET_ANALOGUE_TIMER:
  828. if (size != 13)
  829. i1ret = FALSE;
  830. break;
  831. /* length == 16 */
  832. case OPCODE_CLEAR_DIGITAL_TIMER:
  833. case OPCODE_SET_DIGITAL_TIMER:
  834. if (size != 16)
  835. i1ret = FALSE;
  836. break;
  837. case OPCODE_RECORD_ON:
  838. if ((size < 3) || (size > 10))
  839. i1ret = FALSE;
  840. break;
  841. /* length == 10 ~ 11 */
  842. case OPCODE_CLEAR_EXTERNAL_TIMER:
  843. case OPCODE_SET_EXTERNAL_TIMER:
  844. if ((size < 10) || (size > 11))
  845. i1ret = FALSE;
  846. break;
  847. case OPCODE_TIMER_STATUS:
  848. if ((size != 3) && (size != 5))
  849. i1ret = FALSE;
  850. break;
  851. case OPCODE_TUNER_DEVICE_STATUS:
  852. if ((size != 7) && (size != 10))
  853. i1ret = FALSE;
  854. break;
  855. case OPCODE_VENDOR_COMMAND:
  856. case OPCODE_VENDOR_COMMAND_WITH_ID:
  857. case OPCODE_VENDOR_REMOTE_BUTTON_DOWN:
  858. if (size > 16)
  859. i1ret = FALSE;
  860. break;
  861. case OPCODE_SET_OSD_STRING:
  862. if ((size < 3) || (size > 16))
  863. i1ret = FALSE;
  864. break;
  865. case OPCODE_SET_TIMER_PROGRAM_TITLE:
  866. case OPCODE_SET_OSD_NAME:
  867. if ((size < 3) || (size > 16))
  868. i1ret = FALSE;
  869. break;
  870. }
  871. if (i1ret == FALSE) {
  872. MT8193_CEC_LOG("[CEC] receive invalid frame: %x\n", frame->blocks.opcode);
  873. PrintFrameDescription(frame);
  874. }
  875. return i1ret;
  876. }
  877. static unsigned char check_and_init_tx_frame(CEC_FRAME_DESCRIPTION *frame)
  878. {
  879. unsigned char ret = 0x00;
  880. MT8193_CEC_FUNC();
  881. if ((frame->size > CEC_MAX_MESG_SIZE) || (frame->size == 0)) {
  882. MT8193_CEC_LOG("[CEC] Tx fram size is not correct\n");
  883. ret = 0x01;
  884. }
  885. /* valid tx frame */
  886. if (ret == 0x00) {
  887. frame->reTXcnt = 0;
  888. frame->sendidx = 0;
  889. }
  890. return ret;
  891. }
  892. unsigned char _CEC_TX_Enqueue(CEC_FRAME_DESCRIPTION *frame)
  893. {
  894. MT8193_CEC_FUNC();
  895. if (frame->size == 1) {
  896. MT8193_CEC_LOG("[CEC] Polling LA = 0x%x\n",
  897. (unsigned char) ((frame->blocks.header.initiator << 4) | frame->blocks.
  898. header.destination));
  899. } else {
  900. MT8193_CEC_LOG("[CEC] Opcode = 0x%x, size = 0x%x\n", frame->blocks.opcode,
  901. frame->size);
  902. }
  903. if (check_and_init_tx_frame(frame))
  904. return 0x01;
  905. if (IS_TX_Q_FULL()) {
  906. MT8193_CEC_LOG("[CEC] Tx queue is full\n");
  907. return 0x01;
  908. }
  909. memcpy(&(CEC_tx_msg_queue[CEC_txQ_write_idx]), frame, sizeof(CEC_FRAME_DESCRIPTION));
  910. /* CYJ.NOTE: no critical section */
  911. CEC_txQ_write_idx = (CEC_txQ_write_idx + 1) % TX_Q_SIZE;
  912. return 0x00;
  913. }
  914. void mt8193_u4CecSendSLTData(unsigned char *pu1Data)
  915. {
  916. unsigned char i;
  917. if (*pu1Data > 14)
  918. *pu1Data = 14;
  919. CTSTestFrame.size = *pu1Data + 2;
  920. CTSTestFrame.sendidx = 0;
  921. CTSTestFrame.reTXcnt = 0;
  922. CTSTestFrame.txtag = NULL;
  923. CTSTestFrame.blocks.header.destination = 0x00;
  924. CTSTestFrame.blocks.header.initiator = 0x04;
  925. CTSTestFrame.blocks.opcode = 0x01;
  926. for (i = 0; i < *pu1Data; i++)
  927. CTSTestFrame.blocks.operand[i] = *(pu1Data + i + 1);
  928. _CEC_TX_Enqueue(&CTSTestFrame);
  929. }
  930. void mt8193_GetSLTData(CEC_SLT_DATA *rCecSltData)
  931. {
  932. unsigned char i;
  933. CEC_FRAME_DESCRIPTION *frame;
  934. MT8193_CEC_FUNC();
  935. frame = CEC_rx_dequeue();
  936. if (frame == NULL) {
  937. rCecSltData->u1Size = 5;
  938. for (i = 0; i < rCecSltData->u1Size; i++)
  939. rCecSltData->au1Data[i] = i;
  940. ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
  941. return;
  942. }
  943. if (frame->blocks.opcode == 0x01) {
  944. if (CEC_frame_validation(frame))
  945. PrintFrameDescription(frame);
  946. rCecSltData->u1Size = frame->size - 2;
  947. if (rCecSltData->u1Size > 14)
  948. rCecSltData->u1Size = 14;
  949. for (i = 0; i < rCecSltData->u1Size; i++)
  950. rCecSltData->au1Data[i] = frame->blocks.operand[i];
  951. MT8193_CEC_LOG("[CEC SLT] Receive data\n");
  952. MT8193_CEC_LOG("[CEC SLT] size = 0x%x\n", rCecSltData->u1Size);
  953. MT8193_CEC_LOG("[CEC SLT] data = ");
  954. for (i = 0; i < rCecSltData->u1Size; i++)
  955. MT8193_CEC_LOG(" 0x%x ", rCecSltData->au1Data[i]);
  956. MT8193_CEC_LOG("\n");
  957. }
  958. }
  959. void CTS_RXProcess(CEC_FRAME_DESCRIPTION *frame)
  960. {
  961. MT8193_CEC_FUNC();
  962. if (frame->blocks.opcode == OPCODE_ABORT) {
  963. CTSTestFrame.size = 4;
  964. CTSTestFrame.sendidx = 0;
  965. CTSTestFrame.reTXcnt = 0;
  966. CTSTestFrame.txtag = NULL;
  967. CTSTestFrame.blocks.header.destination = frame->blocks.header.initiator;
  968. CTSTestFrame.blocks.header.initiator = 4;
  969. CTSTestFrame.blocks.opcode = OPCODE_FEATURE_ABORT;
  970. CTSTestFrame.blocks.operand[0] = OPCODE_ABORT;
  971. CTSTestFrame.blocks.operand[1] = 4;
  972. /* ///////////////////// Test////////////////////////////////// */
  973. CTSTestFrame.blocks.operand[2] = 2;
  974. CTSTestFrame.blocks.operand[3] = 3;
  975. CTSTestFrame.blocks.operand[4] = 4;
  976. CTSTestFrame.blocks.operand[5] = 5;
  977. CTSTestFrame.blocks.operand[6] = 6;
  978. CTSTestFrame.blocks.operand[7] = 7;
  979. CTSTestFrame.blocks.operand[8] = 8;
  980. CTSTestFrame.blocks.operand[9] = 9;
  981. CTSTestFrame.blocks.operand[10] = 10;
  982. CTSTestFrame.blocks.operand[11] = 11;
  983. CTSTestFrame.blocks.operand[12] = 12;
  984. CTSTestFrame.blocks.operand[13] = 13;
  985. /* /////////////////////Test//////////////////////////////////// */
  986. _CEC_TX_Enqueue(&CTSTestFrame);
  987. MT8193_CEC_LOG("[CEC] CTS Send: OPCODE_FEATURE_ABORT\n");
  988. } else if (frame->blocks.opcode == OPCODE_GIVE_PHYSICAL_ADDRESS) {
  989. CTSTestFrame.size = 5;
  990. CTSTestFrame.sendidx = 0;
  991. CTSTestFrame.reTXcnt = 0;
  992. CTSTestFrame.txtag = NULL;
  993. CTSTestFrame.blocks.header.destination = 0xf;
  994. CTSTestFrame.blocks.header.initiator = 4;
  995. CTSTestFrame.blocks.opcode = OPCODE_REPORT_PHYSICAL_ADDRESS;
  996. CTSTestFrame.blocks.operand[0] = 0x10;
  997. CTSTestFrame.blocks.operand[1] = 0x00;
  998. CTSTestFrame.blocks.operand[2] = 0x04;
  999. _CEC_TX_Enqueue(&CTSTestFrame);
  1000. MT8193_CEC_LOG("[CEC] CTS Send: OPCODE_REPORT_PHYSICAL_ADDRESS\n");
  1001. }
  1002. }
  1003. static void CEC_rx_msg_notify(unsigned char u1rxmode)
  1004. {
  1005. CEC_FRAME_DESCRIPTION *frame;
  1006. /* MT8193_CEC_FUNC(); */
  1007. if (u1rxmode == CEC_SLT_MODE)
  1008. return;
  1009. if (u1rxmode == CEC_NORMAL_MODE)
  1010. return;
  1011. while (1) {
  1012. frame = CEC_rx_dequeue();
  1013. if (frame == NULL) {
  1014. ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
  1015. return;
  1016. }
  1017. if (CEC_frame_validation(frame)) {
  1018. MT8193_CEC_LOG("[CEC} Receive message\n");
  1019. PrintFrameDescription(frame);
  1020. if (u1rxmode == CEC_CTS_MODE)
  1021. CTS_RXProcess(frame);
  1022. }
  1023. }
  1024. }
  1025. void mt8193_cec_mainloop(unsigned char u1rxmode)
  1026. {
  1027. /* MT8193_CEC_FUNC(); */
  1028. _CEC_TX_Queue_Loop();
  1029. /* NOTE: the priority between tx and rx */
  1030. if (!IsCECStatus(STATE_TXING_FRAME))
  1031. CEC_rx_msg_notify(u1rxmode);
  1032. }
  1033. unsigned char mt8193_cec_isrprocess(unsigned char u1rxmode)
  1034. {
  1035. unsigned char u1ReceivedDst;
  1036. MT8193_CEC_FUNC();
  1037. if (HW_RX_HEADER_ARRIVED()) {
  1038. u1ReceivedDst = GET_DST_FIELD_RECEIVING();
  1039. MT8193_CEC_LOG("[CEC]u1ReceivedDst = 0x%08x\n", u1ReceivedDst);
  1040. if (u1rxmode == CEC_CTS_MODE)
  1041. _rCECLaAddr.aui1_la[0] = 4;
  1042. if ((u1ReceivedDst == _rCECLaAddr.aui1_la[0])
  1043. || (u1ReceivedDst == _rCECLaAddr.aui1_la[1])
  1044. || (u1ReceivedDst == _rCECLaAddr.aui1_la[2]) || (u1ReceivedDst == 0xf)) {
  1045. MT8193_CEC_LOG("[CEC] RX:H\n");
  1046. if (IsCECStatus(STATE_RX_GET_NEW_HEADER)) {
  1047. MT8193_CEC_LOG("[CEC] Lost EOM:1\n");
  1048. SetCECErrorFlag(ERR_RX_LOST_EOM);
  1049. }
  1050. SetCECStatus(STATE_RX_GET_NEW_HEADER);
  1051. } else {
  1052. ClrCECStatus(STATE_RX_GET_NEW_HEADER);
  1053. MT8193_CEC_LOG("[CEC] RX:H False\n");
  1054. }
  1055. }
  1056. if (HW_RX_DATA_ARRIVED()) {
  1057. MT8193_CEC_LOG("[CEC] RX:D\n");
  1058. _CEC_Receiving();
  1059. }
  1060. if (IS_INT_OV()) {
  1061. MT8193_CEC_LOG("[CEC] Overflow\n");
  1062. CLR_INT_OV();
  1063. SetCECStatus(STATE_HW_RX_OVERFLOW);
  1064. }
  1065. /* TX_EVENT */
  1066. if (IsCECStatus(STATE_TXING_FRAME)) {
  1067. if (IS_INT_UN()) {
  1068. MT8193_CEC_LOG("[CEC] Underrun\n");
  1069. CLR_INT_UN();
  1070. SetCECErrorFlag(ERR_TX_UNDERRUN);
  1071. }
  1072. if (IS_INT_LOW()) {
  1073. MT8193_CEC_LOG("[CEC] Buffer Low\n");
  1074. CLR_INT_LOW();
  1075. if (!IS_INT_RB_RDY()) {
  1076. MT8193_CEC_LOG
  1077. ("[CEC] FW is slow to trigger the following blocks\n");
  1078. SetCECErrorFlag(ERR_TX_BUFFER_LOW);
  1079. }
  1080. }
  1081. if (IS_INT_RB_ENABLE() && IS_TX_DATA_TAKEN()) {
  1082. MT8193_CEC_LOG("[CEC] TX Data Taken\n");
  1083. _CEC_SendRemainingDataBlocks();
  1084. }
  1085. /* CYJ.NOTE TX Failure Detection */
  1086. if (IS_INT_FAIL_ENABLE() && (TX_FAIL_RECORD() != 0)) {
  1087. DISABLE_ALL_TX_INT();
  1088. SetCECStatus(STATE_HW_RETX);
  1089. if (TX_FAIL_MAX() | IS_TX_FSM_FAIL()) {
  1090. MT8193_CEC_LOG("[CEC] TX Fail: %x\n", TX_FAIL_RECORD());
  1091. MT8193_CEC_LOG("[CEC] TX Fail MAX\n");
  1092. } else {
  1093. MT8193_CEC_LOG("[CEC] TX Fail: %x\n", TX_FAIL_RECORD());
  1094. }
  1095. }
  1096. MT8193_CEC_LOG("[CEC] TX HW FSM: %x\n", TX_FSM_STATUS());
  1097. }
  1098. if (IS_RX_Q_EMPTY())
  1099. return 0;
  1100. else
  1101. return 1;
  1102. }
  1103. void CECMWSetLA(CEC_LA_ADDRESS *prLA)
  1104. {
  1105. MT8193_CEC_FUNC();
  1106. memcpy(&_rCECLaAddr, prLA, sizeof(CEC_LA_ADDRESS));
  1107. /*ASSERT(_rCECLaAddr.ui1_num <= 3);*/
  1108. if (_rCECLaAddr.ui1_num == 0) {
  1109. SET_LA3(0x0F);
  1110. SET_LA2(0x0F);
  1111. SET_LA1(0x0F);
  1112. _rCECLaAddr.aui1_la[0] = 0x0F;
  1113. _rCECLaAddr.aui1_la[1] = 0x0F;
  1114. _rCECLaAddr.aui1_la[2] = 0x0F;
  1115. } else if (_rCECLaAddr.ui1_num == 1) {
  1116. SET_LA3(0x0F);
  1117. SET_LA2(0x0F);
  1118. SET_LA1(_rCECLaAddr.aui1_la[0]);
  1119. _rCECLaAddr.aui1_la[1] = 0x0F;
  1120. _rCECLaAddr.aui1_la[2] = 0x0F;
  1121. } else if (_rCECLaAddr.ui1_num == 2) {
  1122. SET_LA3(0x0F);
  1123. SET_LA2(_rCECLaAddr.aui1_la[1]);
  1124. SET_LA1(_rCECLaAddr.aui1_la[0]);
  1125. _rCECLaAddr.aui1_la[2] = 0x0F;
  1126. } else if (_rCECLaAddr.ui1_num == 3) {
  1127. SET_LA3(_rCECLaAddr.aui1_la[2]);
  1128. SET_LA2(_rCECLaAddr.aui1_la[1]);
  1129. SET_LA1(_rCECLaAddr.aui1_la[0]);
  1130. }
  1131. MT8193_CEC_LOG("MW Set LA & PA\n");
  1132. MT8193_CEC_LOG("LA num = 0x%x , LA = 0x%x 0x%x 0x%x\n", _rCECLaAddr.ui1_num,
  1133. _rCECLaAddr.aui1_la[0], _rCECLaAddr.aui1_la[1], _rCECLaAddr.aui1_la[2]);
  1134. MT8193_CEC_LOG("PA = %04x\n", _rCECLaAddr.ui2_pa);
  1135. }
  1136. void mt8193_CECMWSetLA(CEC_DRV_ADDR_CFG_T *prAddr)
  1137. {
  1138. CEC_LA_ADDRESS rLA;
  1139. MT8193_CEC_FUNC();
  1140. if (prAddr->ui1_la_num > 3)
  1141. return;
  1142. rLA.ui1_num = prAddr->ui1_la_num;
  1143. rLA.aui1_la[0] = prAddr->e_la[0];
  1144. rLA.aui1_la[1] = prAddr->e_la[1];
  1145. rLA.aui1_la[2] = prAddr->e_la[2];
  1146. rLA.ui2_pa = prAddr->ui2_pa;
  1147. CECMWSetLA(&rLA);
  1148. }
  1149. void mt8193_CECMWGet(CEC_FRAME_DESCRIPTION *frame)
  1150. {
  1151. unsigned char i;
  1152. CEC_FRAME_DESCRIPTION *frame1;
  1153. MT8193_CEC_FUNC();
  1154. frame1 = CEC_rx_dequeue();
  1155. if (frame1 == NULL) {
  1156. frame->blocks.operand[14] = GET_CMD_ERR;
  1157. frame->size = 5;
  1158. frame->sendidx = 1;
  1159. frame->reTXcnt = 1;
  1160. frame->txtag = NULL;
  1161. frame->blocks.header.destination = 1;
  1162. frame->blocks.header.initiator = 1;
  1163. frame->blocks.opcode = frame1->blocks.opcode;
  1164. for (i = 0; i < 14; i++)
  1165. frame->blocks.operand[i] = i;
  1166. ClrCECStatus(STATE_RX_COMPLETE_NEW_FRAME);
  1167. return;
  1168. }
  1169. if (CEC_frame_validation(frame1)) {
  1170. MT8193_CEC_LOG("app get message\n");
  1171. PrintFrameDescription(frame1);
  1172. }
  1173. frame->size = frame1->size;
  1174. frame->sendidx = frame1->sendidx;
  1175. frame->reTXcnt = frame1->reTXcnt;
  1176. frame->txtag = NULL;
  1177. frame->blocks.header.destination = frame1->blocks.header.destination;
  1178. frame->blocks.header.initiator = frame1->blocks.header.initiator;
  1179. frame->blocks.opcode = frame1->blocks.opcode;
  1180. for (i = 0; i < 14; i++)
  1181. frame->blocks.operand[i] = frame1->blocks.operand[i];
  1182. if (IS_RX_Q_EMPTY())
  1183. frame->blocks.operand[14] = GET_CMD_EMPTY;
  1184. else
  1185. frame->blocks.operand[14] = GET_CMD_UNEMPTY;
  1186. }
  1187. void mt8193_CECMWSend(CEC_SEND_MSG_T *msg)
  1188. {
  1189. unsigned int i4Ret;
  1190. unsigned char i;
  1191. MT8193_CEC_FUNC();
  1192. if ((msg->t_frame_info.ui1_init_addr > 0xf) || (msg->t_frame_info.ui1_dest_addr > 0xf)
  1193. || (msg->t_frame_info.z_operand_size > LOCAL_CEC_MAX_OPERAND_SIZE))
  1194. return;
  1195. cecMwTxMsg.txtag = NULL;
  1196. cecMwTxMsg.blocks.header.initiator = msg->t_frame_info.ui1_init_addr;
  1197. cecMwTxMsg.blocks.header.destination = msg->t_frame_info.ui1_dest_addr;
  1198. cecMwTxMsg.sendidx = 0;
  1199. cecMwTxMsg.reTXcnt = 0;
  1200. if (msg->t_frame_info.ui2_opcode == 0xffff) {
  1201. cecMwTxMsg.size = 1;
  1202. } else {
  1203. cecMwTxMsg.blocks.opcode = msg->t_frame_info.ui2_opcode;
  1204. cecMwTxMsg.size = msg->t_frame_info.z_operand_size + 2;
  1205. }
  1206. for (i = 0; i < cecMwTxMsg.size - 2; i++)
  1207. cecMwTxMsg.blocks.operand[i] = msg->t_frame_info.aui1_operand[i];
  1208. i4Ret = _CEC_TX_Enqueue(&cecMwTxMsg);
  1209. if (i4Ret == 0x01) {
  1210. msg->b_enqueue_ok = FALSE;
  1211. MT8193_CEC_LOG("MW Set cmd fail\n");
  1212. ; return;
  1213. } else {
  1214. msg->b_enqueue_ok = TRUE;
  1215. MT8193_CEC_LOG("MW Set cmd success\n");
  1216. ; return;
  1217. }
  1218. }
  1219. void mt8193_CECMWSetEnableCEC(unsigned char u1EnCec)
  1220. {
  1221. MT8193_CEC_FUNC();
  1222. if (u1EnCec == 1) {
  1223. MT8193_CEC_LOG("UI ON\n");
  1224. _fgUICECEnable = 1;
  1225. } else {
  1226. MT8193_CEC_LOG("UI off\n");
  1227. _fgUICECEnable = 0;
  1228. }
  1229. }
  1230. void mt8193_NotifyApiCECAddress(CEC_ADDRESS *cecaddr)
  1231. {
  1232. MT8193_CEC_FUNC();
  1233. cecaddr->ui2_pa = _rCECPhysicAddr.ui2_pa;
  1234. cecaddr->ui1_la = _rCECPhysicAddr.ui1_la;
  1235. }
  1236. void mt8193_SetPhysicCECAddress(unsigned short u2pa, unsigned char u1la)
  1237. {
  1238. MT8193_CEC_FUNC();
  1239. _rCECPhysicAddr.ui2_pa = u2pa;
  1240. _rCECPhysicAddr.ui1_la = u1la;
  1241. }
  1242. #endif