import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / hdmi / Sii8338 / si_drv_mhl_tx.c
CommitLineData
6fa3eb70
S
1#ifndef __KERNEL__
2#include <string.h>
3#include "hal_local.h"
4#include "si_common.h"
5#else
6#ifdef DEBUG
7#define TRACE_INT_TIME
8#endif
9#ifdef TRACE_INT_TIME
10#include <linux/jiffies.h>
11#endif
12#include <linux/string.h>
13#endif
14#include <linux/delay.h>
15#include "si_cra.h"
16#include "si_cra_cfg.h"
17#include "si_mhl_defs.h"
18#include "si_mhl_tx_api.h"
19#include "si_mhl_tx_base_drv_api.h"
20#include "si_8338_regs.h"
21#include "si_drv_mhl_tx.h"
22#include "si_platform.h"
23#include "smartbook.h"
24#include <linux/hrtimer.h>
25#include <linux/ktime.h>
26#include <mach/mt_gpio.h>
27#include <cust_gpio_usage.h>
28#include <cust_eint.h>
29#include "si_drv_mdt_tx.h"
30#include "si_mdt_inputdev.h"
31///#include "hdmitx_i2c.h"
32#include "hdmi_cust.h"
33
34static ktime_t hr_timer_AbortTimer_CHK_ktime;
35unsigned long delay_in_ms;
36#define MS_TO_NS(x) (x * 1E6L)
37extern struct hrtimer hr_timer_AbortTimer_CHK;
38
39#define SILICON_IMAGE_ADOPTER_ID 322
40#define POWER_STATE_D3 3
41#define POWER_STATE_D0_NO_MHL 2
42#define POWER_STATE_D0_MHL 0
43#define POWER_STATE_FIRST_INIT 0xFF
44#define TX_HW_RESET_PERIOD 10
45#define TX_HW_RESET_DELAY 100
46static uint8_t fwPowerState = POWER_STATE_FIRST_INIT;
47static bool_t mscCmdInProgress;
48bool_t mscAbortFlag = false;
49static uint8_t dsHpdStatus;
50#define WriteByteCBUS(offset, value) SiiRegWrite(TX_PAGE_CBUS | (uint16_t)offset, value)
51#define ReadByteCBUS(offset) SiiRegRead(TX_PAGE_CBUS | (uint16_t)offset)
52#define SET_BIT(offset, bitnumber) SiiRegModify(offset, (1<<bitnumber), (1<<bitnumber))
53#define CLR_BIT(offset, bitnumber) SiiRegModify(offset, (1<<bitnumber), 0x00)
54#define DISABLE_DISCOVERY SiiRegModify(TX_PAGE_3 | 0x0010, BIT0, 0)
55#define ENABLE_DISCOVERY SiiRegModify(TX_PAGE_3 | 0x0010, BIT0, BIT0)
56#define STROBE_POWER_ON SiiRegModify(TX_PAGE_3 | 0x0010, BIT1, 0)
57#define INTR_1_DESIRED_MASK (BIT7|BIT6)
58#define UNMASK_INTR_1_INTERRUPTS SiiRegWrite(TX_PAGE_L0 | 0x0075, INTR_1_DESIRED_MASK)
59#define MASK_INTR_1_INTERRUPTS SiiRegWrite(TX_PAGE_L0 | 0x0075, 0x00)
60#define INTR_2_DESIRED_MASK (BIT1)
61#define UNMASK_INTR_2_INTERRUPTS SiiRegWrite(TX_PAGE_L0 | 0x0076, INTR_2_DESIRED_MASK)
62#define INTR_4_DESIRED_MASK (BIT0 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6)
63#define UNMASK_INTR_4_INTERRUPTS SiiRegWrite(TX_PAGE_3 | 0x0022, INTR_4_DESIRED_MASK)
64#define MASK_INTR_4_INTERRUPTS SiiRegWrite(TX_PAGE_3 | 0x0022, 0x00)
65#define INTR_5_DESIRED_MASK 0 /* (BIT2 | BIT3 | BIT4) */
66#define UNMASK_INTR_5_INTERRUPTS SiiRegWrite(TX_PAGE_3 | 0x0024, INTR_5_DESIRED_MASK)
67#define MASK_INTR_5_INTERRUPTS SiiRegWrite(TX_PAGE_3 | 0x0024, 0x00)
68#define INTR_CBUS1_DESIRED_MASK (BIT2 | BIT3 | BIT4 | BIT5 | BIT6)
69#define UNMASK_CBUS1_INTERRUPTS SiiRegWrite(TX_PAGE_CBUS | 0x0009, INTR_CBUS1_DESIRED_MASK)
70#define MASK_CBUS1_INTERRUPTS SiiRegWrite(TX_PAGE_CBUS | 0x0009, 0x00)
71#define INTR_CBUS2_DESIRED_MASK (BIT0 | BIT2 | BIT3)
72#define UNMASK_CBUS2_INTERRUPTS SiiRegWrite(TX_PAGE_CBUS | 0x001F, INTR_CBUS2_DESIRED_MASK)
73#define MASK_CBUS2_INTERRUPTS SiiRegWrite(TX_PAGE_CBUS | 0x001F, 0x00)
74#define I2C_INACCESSIBLE -1
75#define I2C_ACCESSIBLE 1
76#define SIZE_AVI_INFOFRAME 17
77static void Int1Isr(void);
78static int Int4Isr(void);
79static void Int5Isr(void);
80static void MhlCbusIsr(void);
81static void CbusReset(void);
82static void SwitchToD0(void);
83void SwitchToD3(void);
84static void WriteInitialRegisterValues(void);
85static void InitCBusRegs(void);
86static void ForceUsbIdSwitchOpen(void);
87static void ReleaseUsbIdSwitchOpen(void);
88static void MhlTxDrvProcessConnection(void);
89static void MhlTxDrvProcessDisconnection(void);
90static bool_t tmdsPowRdy;
91video_data_t video_data;
92static AVMode_t AVmode = { VM_INVALID, AUD_INVALID };
93
94static void AudioVideoIsr(bool_t force_update);
95static uint8_t CalculateInfoFrameChecksum(uint8_t *infoFrameData);
96static void SendAviInfoframe(void);
97static void ProcessScdtStatusChange(void);
98static void SetAudioMode(inAudioTypes_t audiomode);
99static void SetACRNValue(void);
100static void SendAudioInfoFrame(void);
101void SiiMhlTxHwReset(uint16_t hwResetPeriod, uint16_t hwResetDelay);
102
103#ifdef __KERNEL__
104static SiiOsTimer_t MscAbortTimer;
105static void SiiMhlMscAbortTimerCB(void *pArg)
106{
107 SiiOsTimerDelete(MscAbortTimer);
108 MscAbortTimer = NULL;
109 mscAbortFlag = false;
110 SiiMhlTriggerSoftInt();
111}
112
113uint8_t SiiCheckDevice(uint8_t dev)
114{
115#ifdef _RGB_BOARD
116 if (HalI2cReadByte(0x60, 0x70) == 0xff)
117 return false;
118#endif
119 if (dev == 0) {
120 if (POWER_STATE_D3 != fwPowerState && HalI2cReadByte(0x9a, 0x21) == 0xff)
121 return false;
122 } else if (dev == 1) {
123 if (POWER_STATE_D3 == fwPowerState)
124 return false;
125 }
126 return true;
127}
128
129void SiiMhlTriggerSoftInt(void)
130{
131 SiiRegBitsSet(TX_PAGE_3 | 0x0020, BIT3, true);
132 HalTimerWait(5);
133 SiiRegBitsSet(TX_PAGE_3 | 0x0020, BIT3, false);
134}
135#endif
136
137#ifdef MDT_SUPPORT
138enum mdt_state g_state_for_mdt = IDLE;
139extern struct msc_request g_prior_msc_request;
140#endif
141
142static void Int1Isr(void)
143{
144 uint8_t regIntr1;
145 regIntr1 = SiiRegRead(TX_PAGE_L0 | 0x0071);
146 if (regIntr1) {
147 SiiRegWrite(TX_PAGE_L0 | 0x0071, regIntr1);
148 if (BIT6 & regIntr1) {
149 uint8_t cbusStatus;
150 cbusStatus = SiiRegRead(TX_PAGE_CBUS | 0x000D);
151 TX_DEBUG_PRINT(("Drv: dsHpdStatus =%02X\n", (int)dsHpdStatus));
152 if (BIT6 & (dsHpdStatus ^ cbusStatus)) {
153 uint8_t status = cbusStatus & BIT6;
154 TX_DEBUG_PRINT(("Drv: Downstream HPD changed to: %02X\n",
155 (int)cbusStatus));
156 SiiMhlTxNotifyDsHpdChange(status);
157 if (status) {
158 AudioVideoIsr(true);
159 }
160 dsHpdStatus = cbusStatus;
161 }
162 }
163 if (BIT7 & regIntr1) {
164 TX_DEBUG_PRINT(("MHL soft interrupt triggered\n"));
165 }
166 }
167}
168
169static int Int2Isr(void)
170{
171 if (SiiRegRead(TX_PAGE_L0 | 0x0072) & INTR_2_DESIRED_MASK) {
172 SiiRegWrite(TX_PAGE_L0 | 0x0072, INTR_2_DESIRED_MASK);
173 if (SiiRegRead(TX_PAGE_L0 | 0x0009) & BIT1) {
174 TX_DEBUG_PRINT(("PCLK is STABLE\n"));
175 if (tmdsPowRdy) {
176 SendAudioInfoFrame();
177 SendAviInfoframe();
178 }
179 }
180 }
181 return 0;
182}
183
184bool_t SiiMhlTxChipInitialize(void)
185{
186 unsigned int initState = 0, g_chipRevId = 0;
187 tmdsPowRdy = false;
188 mscCmdInProgress = false;
189 dsHpdStatus = 0;
190 fwPowerState = POWER_STATE_D0_NO_MHL;
191 SI_OS_DISABLE_DEBUG_CHANNEL(SII_OSAL_DEBUG_SCHEDULER);
192 /* memset(&video_data, 0x00, sizeof(video_data)); */
193 video_data.inputColorSpace = COLOR_SPACE_RGB;
194 video_data.outputColorSpace = COLOR_SPACE_RGB;
195 video_data.outputVideoCode = 2;
196 video_data.inputcolorimetryAspectRatio = 0x18;
197 video_data.outputcolorimetryAspectRatio = 0x18;
198 video_data.output_AR = 0;
199 /* SiiMhlTxHwReset(TX_HW_RESET_PERIOD,TX_HW_RESET_DELAY); */
200 /* SiiCraInitialize(); */
201
202 g_chipRevId = SiiRegRead(TX_PAGE_L0 | 0x04);
203
204 initState = (SiiRegRead(TX_PAGE_L0 | 0x03) << 8) | SiiRegRead(TX_PAGE_L0 | 0x02);
205 TX_DEBUG_PRINT(("Drv: SiiMhlTxChipInitialize:%04X,g_chipRevId=0x%x\n", initState,
206 g_chipRevId));
207 if ((initState & 0xFF) != 0x52) {
208 SwitchToD3();
209 return false;
210 }
211 WriteInitialRegisterValues();
212#ifndef __KERNEL__
213 SiiOsMhlTxInterruptEnable();
214#endif
215 SwitchToD3();
216 if (0xFFFF == initState) /* 0x8356 */
217 {
218 return false;
219 }
220 return true;
221}
222
223typedef enum {
224 HDMI_STATE_NO_DEVICE,
225 HDMI_STATE_ACTIVE,
226 HDMI_STATE_DPI_ENABLE
227} HDMI_STATE;
228extern void hdmi_state_callback(HDMI_STATE state);
229
230
231void SiiMhlTxDeviceIsr(void)
232{
233 uint8_t intMStatus, i;
234#ifdef TRACE_INT_TIME
235 unsigned long K1;
236 unsigned long K2;
237 printk("-------------------SiiMhlTxDeviceIsr start -----------------\n");
238 K1 = get_jiffies_64();
239#endif
240 i = 0;
241 do {
242 TX_DEBUG_PRINT(("Drv: SiiMhlTxDeviceIsr %d\n", fwPowerState));
243#ifdef MDT_SUPPORT
244 if (g_state_for_mdt != IDLE) {
245 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d,HalGpioGetTxIntPin22222222222=%d#######################\n",g_state_for_mdt,HalGpioGetTxIntPin())); */
246
247 while ((sii8338_irq_for_mdt(&g_state_for_mdt) == MDT_EVENT_HANDLED)
248 || (g_state_for_mdt != WAIT_FOR_REQ_WRT)) {
249 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d\n",g_state_for_mdt)); */
250 Int4Isr();
251 if (fwPowerState == POWER_STATE_D3)
252 return;
253 } /* &&(SiiRegRead(TX_PAGE_L0| 0x0070)&0x01));// */
254 /* && (HalGpioGetTxIntPin() == MHL_INT_ASSERTED_VALUE)); */
255 /* { */
256
257 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d,HalGpioGetTxIntPin=%d@@@@@@@@@@@@@@@@@@@@@@\n",g_state_for_mdt,HalGpioGetTxIntPin())); */
258 /* if (HalGpioGetTxIntPin() != MHL_INT_ASSERTED_VALUE) { */
259 /* MHL_log_event(IRQ_RECEIVED, 1, HalGpioGetTxIntPin()); */
260 /* if(!(SiiRegRead(TX_PAGE_L0| 0x0070)&0x01)) */
261 /* return; */
262 /* } */
263 /* } */
264 }
265 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d,HalGpioGetTxIntPin3333333333333=%d#######################\n",g_state_for_mdt,HalGpioGetTxIntPin())); */
266
267 MHL_log_event(ISR_FULL_BEGIN, 0, HalGpioGetTxIntPin());
268#endif
269
270 if (POWER_STATE_D0_MHL != fwPowerState) {
271
272 if (I2C_INACCESSIBLE == Int4Isr()) {
273 TX_DEBUG_PRINT(("Drv: I2C_INACCESSIBLE in Int4Isr in not D0 mode\n"));
274 return;
275 }
276 } else if (POWER_STATE_D0_MHL == fwPowerState) {
277
278#if 0
279 TX_DEBUG_PRINT(("********* EXITING ISR *************\n"));
280 TX_DEBUG_PRINT(("Drv: INT1 Status = %02X\n",
281 (int)SiiRegRead((TX_PAGE_L0 | 0x0071))));
282 TX_DEBUG_PRINT(("Drv: INT2 Status = %02X\n",
283 (int)SiiRegRead((TX_PAGE_L0 | 0x0072))));
284 TX_DEBUG_PRINT(("Drv: INT3 Status = %02X\n",
285 (int)SiiRegRead((TX_PAGE_L0 | 0x0073))));
286 TX_DEBUG_PRINT(("Drv: INT4 Status = %02X\n",
287 (int)SiiRegRead(TX_PAGE_3 | 0x0021)));
288 TX_DEBUG_PRINT(("Drv: INT5 Status = %02X\n",
289 (int)SiiRegRead(TX_PAGE_3 | 0x0023)));
290
291
292 TX_DEBUG_PRINT(("Drv: cbusInt Status = %02X\n",
293 (int)SiiRegRead(TX_PAGE_CBUS | 0x0008)));
294
295 TX_DEBUG_PRINT(("Drv: CBUS INTR_2: 0x1E: %02X\n",
296 (int)SiiRegRead(TX_PAGE_CBUS | 0x001E)));
297 TX_DEBUG_PRINT(("Drv: A0 INT Set = %02X\n",
298 (int)SiiRegRead((TX_PAGE_CBUS | 0x00A0))));
299 TX_DEBUG_PRINT(("Drv: A1 INT Set = %02X\n",
300 (int)SiiRegRead((TX_PAGE_CBUS | 0x00A1))));
301 TX_DEBUG_PRINT(("Drv: A2 INT Set = %02X\n",
302 (int)SiiRegRead((TX_PAGE_CBUS | 0x00A2))));
303 TX_DEBUG_PRINT(("Drv: A3 INT Set = %02X\n",
304 (int)SiiRegRead((TX_PAGE_CBUS | 0x00A3))));
305
306 TX_DEBUG_PRINT(("Drv: B0 STATUS Set = %02X\n",
307 (int)SiiRegRead((TX_PAGE_CBUS | 0x00B0))));
308 TX_DEBUG_PRINT(("Drv: B1 STATUS Set = %02X\n",
309 (int)SiiRegRead((TX_PAGE_CBUS | 0x00B1))));
310 TX_DEBUG_PRINT(("Drv: B2 STATUS Set = %02X\n",
311 (int)SiiRegRead((TX_PAGE_CBUS | 0x00B2))));
312 TX_DEBUG_PRINT(("Drv: B3 STATUS Set = %02X\n",
313 (int)SiiRegRead((TX_PAGE_CBUS | 0x00B3))));
314
315 TX_DEBUG_PRINT(("Drv: E0 STATUS Set = %02X\n",
316 (int)SiiRegRead((TX_PAGE_CBUS | 0x00E0))));
317 TX_DEBUG_PRINT(("Drv: E1 STATUS Set = %02X\n",
318 (int)SiiRegRead((TX_PAGE_CBUS | 0x00E1))));
319 TX_DEBUG_PRINT(("Drv: E2 STATUS Set = %02X\n",
320 (int)SiiRegRead((TX_PAGE_CBUS | 0x00E2))));
321 TX_DEBUG_PRINT(("Drv: E3 STATUS Set = %02X\n",
322 (int)SiiRegRead((TX_PAGE_CBUS | 0x00E3))));
323
324 TX_DEBUG_PRINT(("Drv: F0 INT Set = %02X\n",
325 (int)SiiRegRead((TX_PAGE_CBUS | 0x00F0))));
326 TX_DEBUG_PRINT(("Drv: F1 INT Set = %02X\n",
327 (int)SiiRegRead((TX_PAGE_CBUS | 0x00F1))));
328 TX_DEBUG_PRINT(("Drv: F2 INT Set = %02X\n",
329 (int)SiiRegRead((TX_PAGE_CBUS | 0x00F2))));
330 TX_DEBUG_PRINT(("Drv: F3 INT Set = %02X\n",
331 (int)SiiRegRead((TX_PAGE_CBUS | 0x00F3))));
332 TX_DEBUG_PRINT(("********* END OF EXITING ISR *************\n"));
333#endif
334 if (I2C_INACCESSIBLE == Int4Isr()) {
335 TX_DEBUG_PRINT(("Drv: I2C_INACCESSIBLE in Int4Isr in D0 mode\n"));
336 return;
337 }
338 MhlCbusIsr();
339 Int5Isr();
340 Int1Isr();
341 Int2Isr();
342 }
343 if (POWER_STATE_D3 != fwPowerState) {
344 MhlTxProcessEvents();
345 }
346 intMStatus = SiiRegRead(TX_PAGE_L0 | 0x0070);
347 if (0xFF == intMStatus) {
348 intMStatus = 0;
349 TX_DEBUG_PRINT(("Drv: EXITING ISR DUE TO intMStatus - 0xFF loop = [%02X] intMStatus = [%02X]\n\n", (int)i, (int)intMStatus));
350 }
351 i++;
352 intMStatus &= 0x01;
353 if (i > 60) {
354 TX_DEBUG_PRINT(("force exit SiiMhlTxDeviceIsr\n"));
355 break;
356 } else if (i > 50) {
357 TX_DEBUG_PRINT(("something error in SiiMhlTxDeviceIsr\n"));
358 }
359 } while (intMStatus);
360#ifdef TRACE_INT_TIME
361 K2 = get_jiffies_64();
362 printk("-------------------SiiMhlTxDeviceIsr last %d ms----------------\n", (int)(K2 - K1));
363#endif
364}
365
366void SiiExtDeviceIsr(void)
367{
368 if (fwPowerState <= POWER_STATE_D0_NO_MHL) {
369#ifdef TRACE_INT_TIME
370 unsigned long K1;
371 unsigned long K2;
372 K1 = get_jiffies_64();
373#endif
374 AudioVideoIsr(false);
375#ifdef TRACE_INT_TIME
376 K2 = get_jiffies_64();
377#endif
378 } else {
379 TX_DEBUG_PRINT(("in D3 mode , SiiExtDeviceIsr not handled\n"));
380 }
381}
382
383void SiiMhlTxDrvTmdsControl(bool_t enable)
384{
385 if (enable) {
386#ifdef MDT_SUPPORT
387 mdt_init();
388#endif
389 tmdsPowRdy = true;
390 SiiRegModify(TX_PAGE_L1 | 0x2F, BIT0, SET_BITS);
391 if (1) /* (SiiVideoInputIsValid()) */
392 {
393 SiiRegModify(TX_PAGE_L0 | 0x0080, BIT4, SET_BITS);
394 SendAudioInfoFrame();
395 SendAviInfoframe();
396 TX_DEBUG_PRINT(("TMDS Output Enabled\n"));
397 /* Timon */
398#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
399 SiiHandshakeCommand(Init);
400#endif
401 } else {
402 TX_DEBUG_PRINT(("TMDS Output not Enabled due to invalid input\n"));
403 }
404 } else {
405 SiiRegModify(TX_PAGE_L0 | 0x0080, BIT4, CLEAR_BITS);
406 SiiRegModify(TX_PAGE_L1 | 0x2F, BIT0, CLEAR_BITS);
407 tmdsPowRdy = false;
408 TX_DEBUG_PRINT(("TMDS Ouput Disabled\n"));
409#ifdef MDT_SUPPORT
410 mdt_deregister();
411#endif
412 }
413}
414
415void SiiMhlTxDrvNotifyEdidChange(void)
416{
417 TX_DEBUG_PRINT(("SiiMhlTxDrvNotifyEdidChange\n"));
418 SiiDrvMhlTxReadEdid();
419}
420
421bool_t SiiMhlTxDrvSendCbusCommand(cbus_req_t *pReq)
422{
423 bool_t success = true;
424 uint8_t i, startbit;
425 if ((POWER_STATE_D0_MHL != fwPowerState) || (mscCmdInProgress)) {
426 TX_DEBUG_PRINT(("Error: fwPowerState: %02X, or CBUS(0x0A):%02X mscCmdInProgress = %d\n", (int)fwPowerState, (int)SiiRegRead(TX_PAGE_CBUS | 0x000A), (int)mscCmdInProgress));
427 return false;
428 }
429 mscCmdInProgress = true;
430 TX_DEBUG_PRINT(("Sending MSC command %02X, %02X, %02X\n",
431 (int)pReq->command,
432 (int)((MHL_MSC_MSG ==
433 pReq->command) ? pReq->payload_u.msgData[0] : pReq->offsetData),
434 (int)((MHL_MSC_MSG ==
435 pReq->command) ? pReq->payload_u.msgData[1] : pReq->payload_u.
436 msgData[0])));
437 SiiRegWrite(TX_PAGE_CBUS | 0x0013, pReq->offsetData);
438 SiiRegWrite(TX_PAGE_CBUS | 0x0014, pReq->payload_u.msgData[0]);
439 startbit = 0x00;
440 switch (pReq->command) {
441 case MHL_SET_INT:
442 startbit = 0x01 << 3;
443 break;
444 case MHL_WRITE_STAT:
445 startbit = 0x01 << 3;
446 break;
447 case MHL_READ_DEVCAP:
448 startbit = 0x01 << 2;
449 break;
450 case MHL_GET_STATE:
451 case MHL_GET_VENDOR_ID:
452 case MHL_SET_HPD:
453 case MHL_CLR_HPD:
454 case MHL_GET_SC1_ERRORCODE:
455 case MHL_GET_DDC_ERRORCODE:
456 case MHL_GET_MSC_ERRORCODE:
457 case MHL_GET_SC3_ERRORCODE:
458 SiiRegWrite(TX_PAGE_CBUS | 0x0013, pReq->command);
459 startbit = 0x01 << 0;
460 break;
461 case MHL_MSC_MSG:
462 SiiRegWrite(TX_PAGE_CBUS | 0x0015, pReq->payload_u.msgData[1]);
463 SiiRegWrite(TX_PAGE_CBUS | 0x0013, pReq->command);
464 startbit = 0x01 << 1;
465 break;
466 case MHL_WRITE_BURST:
467 SiiRegWrite(TX_PAGE_CBUS | 0x0020, pReq->length - 1);
468 uint8_t *pData = pReq->payload_u.msgData;
469 TX_DEBUG_PRINT(("\nWriting data into scratchpad\n\n"));
470 for (i = 0; i < pReq->length; i++) {
471 SiiRegWrite(REG_CBUS_SCRATCHPAD_0 + i, *pData++);
472 }
473 startbit = MSC_START_BIT_WRITE_BURST;
474 break;
475 default:
476 success = false;
477 break;
478 }
479 if (success) {
480 SiiRegWrite(TX_PAGE_CBUS | 0x0012, startbit);
481 } else {
482 TX_DEBUG_PRINT(("\nSiiMhlTxDrvSendCbusCommand failed\n\n"));
483 }
484 return (success);
485}
486
487bool_t SiiMhlTxDrvCBusBusy(void)
488{
489 return mscCmdInProgress ? true : false;
490}
491
492static void WriteInitialRegisterValues(void)
493{
494 TX_DEBUG_PRINT(("WriteInitialRegisterValues\n"));
495 SiiRegWrite(TX_PAGE_L1 | 0x003D, 0x3F);
496 SiiRegWrite(TX_PAGE_3 | 0x0035, 0xBC);
497 SiiRegWrite(TX_PAGE_3 | 0x0031, 0x3C);
498 SiiRegWrite(TX_PAGE_3 | 0x0033, 0xC8);
499 SiiRegWrite(TX_PAGE_3 | 0x0036, 0x03);
500 SiiRegWrite(TX_PAGE_3 | 0x0037, 0x0A);
501 SiiRegWrite(TX_PAGE_L0 | 0x0080, 0x08);
502 SiiRegWrite(TX_PAGE_L0 | 0x00F7, 0x03);
503 SiiRegWrite(TX_PAGE_L0 | 0x00F8, 0x8C);
504#ifdef MHL_SET_24PIN_MODE
505 SiiRegWrite(TX_PAGE_L0 | 0x0008, 0x35);
506#else
507 SiiRegWrite(TX_PAGE_L0 | 0x0008, 0x31);
508#endif
509 SiiRegWrite(TX_PAGE_3 | 0x0014, 0x57);
510 SiiRegWrite(TX_PAGE_3 | 0x0018, 0x04); /* //0x24 -->0x4 for some smartbook will disconnect. */
511 SiiRegWrite(TX_PAGE_3 | 0x0010, 0x27);
512 SiiRegWrite(TX_PAGE_3 | 0x0012, 0x86);
513 CbusReset();
514 InitCBusRegs();
515 SiiRegModify(TX_PAGE_L0 | 0x00C7, BIT5, SET_BITS);
516 SiiRegModify(TX_PAGE_L1 | 0x2F, BIT2, SET_BITS);
517}
518
519static void InitCBusRegs(void)
520{
521 SiiRegWrite(TX_PAGE_CBUS | 0x0007, 0xF2);
522 SiiRegWrite(TX_PAGE_CBUS | 0x0030, 0x01);
523 SiiRegWrite(TX_PAGE_CBUS | 0x0031, 0x2D);
524 SiiRegWrite(TX_PAGE_CBUS | 0x0036, 0x0a);
525 SiiRegWrite(TX_PAGE_CBUS | 0x0040, 0x03);
526 SiiRegWrite(TX_PAGE_CBUS | 0x002E, 0x11);
527 SiiRegWrite(TX_PAGE_CBUS | 0x0022, 0x0F);
528#define DEVCAP_REG(x) (TX_PAGE_CBUS | 0x0080 | DEVCAP_OFFSET_##x)
529 SiiRegWrite(DEVCAP_REG(DEV_STATE), DEVCAP_VAL_DEV_STATE);
530 SiiRegWrite(DEVCAP_REG(MHL_VERSION), DEVCAP_VAL_MHL_VERSION);
531 SiiRegWrite(DEVCAP_REG(DEV_CAT), DEVCAP_VAL_DEV_CAT);
532 SiiRegWrite(DEVCAP_REG(ADOPTER_ID_H), DEVCAP_VAL_ADOPTER_ID_H);
533 SiiRegWrite(DEVCAP_REG(ADOPTER_ID_L), DEVCAP_VAL_ADOPTER_ID_L);
534 SiiRegWrite(DEVCAP_REG(VID_LINK_MODE), DEVCAP_VAL_VID_LINK_MODE);
535 SiiRegWrite(DEVCAP_REG(AUD_LINK_MODE), DEVCAP_VAL_AUD_LINK_MODE);
536 SiiRegWrite(DEVCAP_REG(VIDEO_TYPE), DEVCAP_VAL_VIDEO_TYPE);
537 SiiRegWrite(DEVCAP_REG(LOG_DEV_MAP), DEVCAP_VAL_LOG_DEV_MAP);
538 SiiRegWrite(DEVCAP_REG(BANDWIDTH), DEVCAP_VAL_BANDWIDTH);
539 SiiRegWrite(DEVCAP_REG(FEATURE_FLAG), DEVCAP_VAL_FEATURE_FLAG);
540 SiiRegWrite(DEVCAP_REG(DEVICE_ID_H), DEVCAP_VAL_DEVICE_ID_H);
541 SiiRegWrite(DEVCAP_REG(DEVICE_ID_L), DEVCAP_VAL_DEVICE_ID_L);
542 SiiRegWrite(DEVCAP_REG(SCRATCHPAD_SIZE), DEVCAP_VAL_SCRATCHPAD_SIZE);
543 SiiRegWrite(DEVCAP_REG(INT_STAT_SIZE), DEVCAP_VAL_INT_STAT_SIZE);
544 SiiRegWrite(DEVCAP_REG(RESERVED), DEVCAP_VAL_RESERVED);
545}
546
547static void ForceUsbIdSwitchOpen(void)
548{
549 DISABLE_DISCOVERY;
550 SiiRegModify(TX_PAGE_3 | 0x0015, BIT6, BIT6);
551 SiiRegWrite(TX_PAGE_3 | 0x0012, 0x86);
552}
553
554static void ReleaseUsbIdSwitchOpen(void)
555{
556 HalTimerWait(15);
557 SiiRegModify(TX_PAGE_3 | 0x0015, BIT6, 0x00);
558 ENABLE_DISCOVERY;
559}
560
561void SiiMhlTxDrvProcessRgndMhl(void)
562{
563 SiiRegModify(TX_PAGE_3 | 0x0018, BIT0, BIT0);
564}
565
566void ProcessRgnd(void)
567{
568 uint8_t rgndImpedance;
569 rgndImpedance = SiiRegRead(TX_PAGE_3 | 0x001C) & 0x03;
570 TX_DEBUG_PRINT(("RGND = %02X :\n", (int)rgndImpedance));
571 if (0x02 == rgndImpedance) {
572 TX_DEBUG_PRINT(("(MHL Device)\n"));
573 SiiMhlTxNotifyRgndMhl();
574 } else {
575 SiiRegModify(TX_PAGE_3 | 0x0018, BIT3, BIT3);
576 TX_DEBUG_PRINT(("(Non-MHL Device)\n"));
577 }
578}
579
580void SwitchToD0(void)
581{
582 TX_DEBUG_PRINT(("Switch to D0\n"));
583 WriteInitialRegisterValues();
584 STROBE_POWER_ON;
585 fwPowerState = POWER_STATE_D0_NO_MHL;
586 AudioVideoIsr(true);
587}
588
589
590extern void CBusQueueReset(void);
591void SwitchToD3(void)
592{
593 if (POWER_STATE_D3 != fwPowerState) {
594 TX_DEBUG_PRINT(("Switch To D3\n"));
595 SiiRegWrite(TX_PAGE_2 | 0x0001, 0x03);
596 SiiRegWrite(TX_PAGE_3 | 0x0030, 0xD0);
597
598
599 SiiRegWrite(TX_PAGE_L0 | 0x0071, 0xFF);
600 SiiRegWrite(TX_PAGE_L0 | 0x0072, 0xFF);
601 SiiRegWrite(TX_PAGE_3 | 0x0021, 0xBF);
602 SiiRegWrite(TX_PAGE_3 | 0x0023, 0xFF);
603 SiiRegWrite(TX_PAGE_CBUS | 0x0008, 0xFF);
604 SiiRegWrite(TX_PAGE_CBUS | 0x001E, 0xFF);
605
606
607 ForceUsbIdSwitchOpen();
608 /* HalTimerWait(50); */
609 ReleaseUsbIdSwitchOpen();
610
611
612 CLR_BIT(TX_PAGE_L1 | 0x003D, 0);
613 CBusQueueReset();
614#ifdef MDT_SUPPORT /* MDT initialization. */
615 /* SiiRegWrite(TX_PAGE_CBUS | 0x00F0, */
616 /* MHL_INT_REQ_WRT | MHL_INT_DCAP_CHG); // handle DSCR_CHG as part of REQ_WRT */
617
618 g_state_for_mdt = IDLE;
619 g_prior_msc_request.offset = 0;
620 g_prior_msc_request.first_data = 0;
621#endif
622 fwPowerState = POWER_STATE_D3;
623 }
624}
625
626void ForceSwitchToD3(void)
627{
628#ifdef MDT_SUPPORT /* MDT initialization. */
629 /* SiiRegWrite(TX_PAGE_CBUS | 0x00F0, */
630 /* MHL_INT_REQ_WRT | MHL_INT_DCAP_CHG); // handle DSCR_CHG as part of REQ_WRT */
631
632 g_state_for_mdt = IDLE;
633 g_prior_msc_request.offset = 0;
634 g_prior_msc_request.first_data = 0;
635#endif
636
637 CLR_BIT(TX_PAGE_L1 | 0x003D, 0);
638 CBusQueueReset();
639 fwPowerState = POWER_STATE_D3;
640}
641
642static int Int4Isr(void)
643{
644 uint8_t int4Status;
645 int4Status = SiiRegRead(TX_PAGE_3 | 0x0021);
646 if (!int4Status) {
647 } else if (0xFF == int4Status) {
648 return I2C_INACCESSIBLE;
649 } else {
650 TX_DEBUG_PRINT(("INT4 Status = %02X\n", (int)int4Status));
651 if (int4Status & BIT0) {
652 ProcessScdtStatusChange();
653 }
654 if (int4Status & BIT2) {
655 MhlTxDrvProcessConnection();
656 } else if (int4Status & BIT3) {
657 TX_DEBUG_PRINT(("uUSB-A type device detected.\n"));
658 SiiRegWrite(TX_PAGE_3 | 0x001C, 0x80);
659 SwitchToD3();
660 return I2C_INACCESSIBLE;
661 }
662 if (int4Status & BIT5) {
663 MhlTxDrvProcessDisconnection();
664 return I2C_INACCESSIBLE;
665 }
666 if ((POWER_STATE_D0_MHL != fwPowerState) && (int4Status & BIT6)) {
667 SwitchToD0();
668 ProcessRgnd();
669 }
670 if (fwPowerState != POWER_STATE_D3) {
671 if (int4Status & BIT4) {
672 TX_DEBUG_PRINT(("CBus Lockout\n"));
673 ForceUsbIdSwitchOpen();
674 ReleaseUsbIdSwitchOpen();
675 }
676 }
677 }
678 SiiRegWrite(TX_PAGE_3 | 0x0021, int4Status);
679 return I2C_ACCESSIBLE;
680}
681
682static void Int5Isr(void)
683{
684 uint8_t int5Status;
685 int5Status = SiiRegRead(TX_PAGE_3 | 0x0023);
686 if (int5Status) {
687#if 0 /* (SYSTEM_BOARD == SB_STARTER_KIT_X01) */
688 if ((int5Status & BIT3) || (int5Status & BIT2)) {
689 TX_DEBUG_PRINT(("** Apply MHL FIFO Reset\n"));
690 SiiRegModify(TX_PAGE_3 | 0x0000, BIT4, SET_BITS);
691 SiiRegModify(TX_PAGE_3 | 0x0000, BIT4, CLEAR_BITS);
692 }
693#endif
694 if (int5Status & BIT4) {
695 TX_DEBUG_PRINT(("** PXL Format changed\n"));
696 }
697 SiiRegWrite(TX_PAGE_3 | 0x0023, int5Status);
698 }
699}
700
701static void MhlTxDrvProcessConnection(void)
702{
703 TX_DEBUG_PRINT(("MHL Cable Connected. CBUS:0x0A = %02X\n",
704 (int)SiiRegRead(TX_PAGE_CBUS | 0x000A)));
705 if (POWER_STATE_D0_MHL == fwPowerState) {
706 return;
707 }
708 SiiRegWrite(TX_PAGE_3 | 0x0030, 0x10);
709 fwPowerState = POWER_STATE_D0_MHL;
710
711/* change TMDS termination to 50 ohm termination(default) */
712/* bits 1:0 set to 00 */
713 SiiRegWrite(TX_PAGE_2 | 0x0001, 0x00);
714
715 ENABLE_DISCOVERY;
716 SiiMhlTxNotifyConnection(true);
717}
718
719static void MhlTxDrvProcessDisconnection(void)
720{
721 TX_DEBUG_PRINT(("MhlTxDrvProcessDisconnection\n"));
722 SiiRegWrite(TX_PAGE_3 | 0x0021, SiiRegRead(TX_PAGE_3 | 0x0021));
723 dsHpdStatus &= ~BIT6;
724 SiiRegWrite(TX_PAGE_CBUS | 0x000D, dsHpdStatus);
725 SiiMhlTxNotifyDsHpdChange(0);
726 if (POWER_STATE_D0_MHL == fwPowerState) {
727 SiiMhlTxNotifyConnection(false);
728 }
729 SwitchToD3();
730}
731
732void CbusReset(void)
733{
734 uint8_t idx;
735 TX_DEBUG_PRINT(("CBUS reset!!!\n"));
736 SET_BIT(TX_PAGE_3 | 0x0000, 3);
737 HalTimerWait(2);
738 CLR_BIT(TX_PAGE_3 | 0x0000, 3);
739 mscCmdInProgress = false;
740 UNMASK_INTR_4_INTERRUPTS;
741#if (SYSTEM_BOARD == SB_STARTER_KIT_X01)
742 UNMASK_INTR_1_INTERRUPTS;
743 UNMASK_INTR_2_INTERRUPTS;
744 UNMASK_INTR_5_INTERRUPTS;
745#else
746 MASK_INTR_1_INTERRUPTS;
747 MASK_INTR_5_INTERRUPTS;
748#endif
749 UNMASK_CBUS1_INTERRUPTS;
750 UNMASK_CBUS2_INTERRUPTS;
751 for (idx = 0; idx < 4; idx++) {
752 WriteByteCBUS((0xE0 + idx), 0xFF);
753 WriteByteCBUS((0xF0 + idx), 0xFF);
754 }
755#ifdef MDT_SUPPORT /* MDT initialization. */
756 SiiRegWrite(TX_PAGE_CBUS | 0x00F0, MHL_INT_REQ_WRT | MHL_INT_DCAP_CHG); /* handle DSCR_CHG as part of REQ_WRT */
757
758 g_state_for_mdt = IDLE;
759 g_prior_msc_request.offset = 0;
760 g_prior_msc_request.first_data = 0;
761#endif
762}
763
764static uint8_t CBusProcessErrors(uint8_t intStatus)
765{
766 uint8_t result = 0;
767 uint8_t abortReason = 0;
768
769 intStatus &= (BIT6 | BIT5 | BIT2);
770 if (intStatus) {
771 if (intStatus & BIT2) {
772 abortReason |= SiiRegRead(TX_PAGE_CBUS | 0x000B);
773 TX_DEBUG_PRINT(("CBUS:: DDC ABORT happened. Clearing 0x0C\n"));
774 SiiRegWrite(TX_PAGE_CBUS | 0x000B, 0xFF);
775 }
776 if (intStatus & BIT5) {
777 abortReason |= SiiRegRead(TX_PAGE_CBUS | 0x000D);
778 TX_DEBUG_PRINT(("CBUS:: MSC Requester ABORTED. Clearing 0x0D\n"));
779 SiiRegWrite(TX_PAGE_CBUS | 0x000D, 0xFF);
780 }
781 if (intStatus & BIT6) {
782 abortReason |= SiiRegRead(TX_PAGE_CBUS | 0x000E);
783 TX_DEBUG_PRINT(("CBUS:: MSC Responder ABORT. Clearing 0x0E\n"));
784 SiiRegWrite(TX_PAGE_CBUS | 0x000E, 0xFF);
785 }
786 if (abortReason & (BIT0 | BIT1 | BIT2 | BIT3 | BIT4 | BIT7)) {
787 TX_DEBUG_PRINT(("CBUS:: Reason for ABORT is ....0x%02X\n",
788 (int)abortReason));
789 if (abortReason & (0x01 << 0)) {
790 TX_DEBUG_PRINT(("Retry threshold exceeded\n"));
791 }
792 if (abortReason & (0x01 << 1)) {
793 TX_DEBUG_PRINT(("Protocol Error\n"));
794 }
795 if (abortReason & (0x01 << 2)) {
796 TX_DEBUG_PRINT(("Translation layer timeout\n"));
797 }
798 if (abortReason & (0x01 << 3)) {
799 TX_DEBUG_PRINT(("Undefined opcode\n"));
800 }
801 if (abortReason & (0x01 << 4)) {
802 TX_DEBUG_PRINT(("Undefined offset\n"));
803 }
804 if (abortReason & (0x01 << 5)) {
805 TX_DEBUG_PRINT(("Opposite device is busy\n"));
806 }
807 if (abortReason & (0x01 << 7)) {
808#ifndef __KERNEL__
809 HalTimerSet(TIMER_ABORT, T_ABORT_NEXT);
810 mscAbortFlag = true;
811#else
812 if (MscAbortTimer) {
813 SiiOsTimerDelete(MscAbortTimer);
814 MscAbortTimer = NULL;
815 }
816 mscAbortFlag = true;
817 /* SiiOsTimerCreate("Abort Time Out", SiiMhlMscAbortTimerCB, NULL, true, */
818 /* 2000, false, &MscAbortTimer); */
819 delay_in_ms = 2000L;
820 hr_timer_AbortTimer_CHK_ktime = ktime_set(0, MS_TO_NS(delay_in_ms));
821 printk(KERN_INFO
822 "Starting timer to fire in hr_timer_AbortTimer_CHK %ldms (%ld)\n",
823 delay_in_ms, jiffies);
824 hrtimer_start(&hr_timer_AbortTimer_CHK,
825 hr_timer_AbortTimer_CHK_ktime, HRTIMER_MODE_REL);
826#endif
827 TX_DEBUG_PRINT(("Peer sent an abort, start 2s timer abort_next\n"));
828 }
829 }
830 }
831 return (result);
832}
833
834void SiiMhlTxDrvGetScratchPad(uint8_t startReg, uint8_t *pData, uint8_t length)
835{
836 int i;
837 for (i = 0; i < length; ++i, ++startReg) {
838 *pData++ = SiiRegRead((TX_PAGE_CBUS | 0x00C0) + startReg);
839 }
840}
841
842static void MhlCbusIsr(void)
843{
844 uint8_t cbusInt;
845 uint8_t gotData[4];
846 uint8_t i;
847 cbusInt = SiiRegRead(TX_PAGE_CBUS | 0x001E);
848 if (cbusInt == 0xFF) {
849 return;
850 }
851 if (cbusInt) {
852#ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
853 if (BIT0 & cbusInt) {
854 SiiMhlTxMscWriteBurstDone(cbusInt);
855 }
856#endif
857 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d^^^^^^^^^^^^^^^^^^^^\n",g_state_for_mdt)); */
858#ifdef MDT_SUPPORT
859 if ((g_state_for_mdt != WAIT_FOR_WRITE_BURST_COMPLETE)
860 && (g_state_for_mdt != WAIT_FOR_REQ_WRT)
861 && (g_state_for_mdt != WAIT_FOR_GRT_WRT_COMPLETE)) {
862
863 if (BIT0 & cbusInt) {
864 SiiMhlTxMscWriteBurstDone(cbusInt);
865
866 g_state_for_mdt = WAIT_FOR_REQ_WRT;
867 SiiRegWrite(TX_PAGE_CBUS | 0x00A0,
868 (MHL_INT_REQ_WRT | MHL_INT_DSCR_CHG));
869 /* TX_DEBUG_PRINT(("g_state_for_mdt=%d$$$$$$$$$$$$$$$$$$$$$$$$\n",g_state_for_mdt)); */
870
871 }
872#endif /* MTK_SMARTBOOK_SUPPORt */
873 /* } */
874 if (cbusInt & BIT2) {
875 uint8_t intr[4] = { 0 };
876 TX_DEBUG_PRINT(("MHL INTR Received\n"));
877 SiiRegReadBlock(TX_PAGE_CBUS | 0x00A0, intr, 4);
878 SiiMhlTxGotMhlIntr(intr[0], intr[1]);
879 SiiRegWriteBlock(TX_PAGE_CBUS | 0x00A0, intr, 4);
880 }
881#ifdef MDT_SUPPORT
882 }
883#endif
884 if (cbusInt & BIT3) {
885 uint8_t status[4] = { 0 };
886 TX_DEBUG_PRINT(("MHL STATUS Received\n"));
887 for (i = 0; i < 4; ++i) {
888 status[i] = SiiRegRead((TX_PAGE_CBUS | 0x00B0) + i);
889 SiiRegWrite(((TX_PAGE_CBUS | 0x00B0) + i), 0xFF);
890 }
891 SiiMhlTxGotMhlStatus(status[0], status[1]);
892 }
893#ifdef MDT_SUPPORT
894 if ((g_state_for_mdt == WAIT_FOR_WRITE_BURST_COMPLETE)
895 || (g_state_for_mdt == WAIT_FOR_REQ_WRT)
896 || (g_state_for_mdt == WAIT_FOR_GRT_WRT_COMPLETE))
897 {
898 SiiRegWrite(TX_PAGE_CBUS | 0x001E, (cbusInt & 0xFE));
899 /* /TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X,g_state_for_mdt=%d\n", (int) (cbusInt&0xFE),g_state_for_mdt)); */
900 } else
901#endif
902 {
903 SiiRegWrite(TX_PAGE_CBUS | 0x001E, cbusInt);
904 TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X\n", (int)cbusInt));
905 }
906 }
907 cbusInt = SiiRegRead(TX_PAGE_CBUS | 0x0008);
908 if (cbusInt) {
909#ifdef MDT_SUPPORT
910 if ((g_state_for_mdt == WAIT_FOR_WRITE_BURST_COMPLETE)
911 || (g_state_for_mdt == WAIT_FOR_REQ_WRT)
912 || (g_state_for_mdt == WAIT_FOR_GRT_WRT_COMPLETE)) {
913 SiiRegWrite(TX_PAGE_CBUS | 0x0008, (cbusInt & 0xEF));
914 /* /TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X,g_state_for_mdt=%d\n", (int) (cbusInt&0xEF),g_state_for_mdt)); */
915 } else
916#endif
917 {
918 SiiRegWrite(TX_PAGE_CBUS | 0x0008, cbusInt);
919 /* /TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X,g_state_for_mdt=%d\n", (int) cbusInt,g_state_for_mdt)); */
920 }
921 }
922 if ((cbusInt & BIT3)) {
923 uint8_t mscMsg[2];
924 TX_DEBUG_PRINT(("MSC_MSG Received\n"));
925 mscMsg[0] = SiiRegRead(TX_PAGE_CBUS | 0x0018);
926 mscMsg[1] = SiiRegRead(TX_PAGE_CBUS | 0x0019);
927 TX_DEBUG_PRINT(("MSC MSG: %02X %02X\n", (int)mscMsg[0], (int)mscMsg[1]));
928 SiiMhlTxGotMhlMscMsg(mscMsg[0], mscMsg[1]);
929 }
930 if (cbusInt & (BIT6 | BIT5 | BIT2)) {
931 gotData[0] = CBusProcessErrors(cbusInt);
932 mscCmdInProgress = false;
933 }
934#ifdef MDT_SUPPORT
935 if ((g_state_for_mdt != WAIT_FOR_WRITE_BURST_COMPLETE)
936 && (g_state_for_mdt != WAIT_FOR_REQ_WRT)
937 && (g_state_for_mdt != WAIT_FOR_GRT_WRT_COMPLETE))
938#endif
939 {
940 if (cbusInt & BIT4) {
941 TX_DEBUG_PRINT(("MSC_REQ_DONE\n"));
942 mscCmdInProgress = false;
943 SiiMhlTxMscCommandDone(SiiRegRead(TX_PAGE_CBUS | 0x0016));
944 }
945 }
946 if (cbusInt & BIT7) {
947 TX_DEBUG_PRINT(("Parity error count reaches 15\n"));
948 SiiRegWrite(TX_PAGE_CBUS | 0x0038, 0x00);
949 }
950}
951
952static void ProcessScdtStatusChange(void)
953{
954}
955
956void SiiMhlTxDrvPowBitChange(bool_t enable)
957{
958 if (enable) {
959 SiiRegModify(TX_PAGE_3 | 0x0017, BIT2, SET_BITS);
960 TX_DEBUG_PRINT(("POW bit 0->1, set DISC_CTRL8[2] = 1\n"));
961 }
962}
963
964void SiMhlTxDrvSetClkMode(uint8_t clkMode)
965{
966 TX_DEBUG_PRINT(("SiMhlTxDrvSetClkMode:0x%02x\n", (int)clkMode));
967}
968
969static void SendAviInfoframe(void)
970{
971 uint8_t ifData[SIZE_AVI_INFOFRAME];
972 extern uint8_t VIDEO_CAPABILITY_D_BLOCK_found;
973 ifData[0] = 0x82;
974 ifData[1] = 0x02;
975 ifData[2] = 0x0D;
976 ifData[3] = 0x00;
977 ifData[4] = video_data.outputColorSpace << 5;
978 ifData[5] = video_data.outputcolorimetryAspectRatio;
979
980 if (VIDEO_CAPABILITY_D_BLOCK_found) {
981 ifData[6] = 0x04;
982 TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found = true, limited range\n"));
983 } else {
984 ifData[6] = 0x00;
985 TX_DEBUG_PRINT(("VIDEO_CAPABILITY_D_BLOCK_found= false. defult range\n"));
986 }
987 /* ifData[4] = video_data.outputColorSpace << 5; */
988 ifData[7] = video_data.inputVideoCode;
989 TX_DEBUG_PRINT(("video_data.inputVideoCode:0x%02x, video_data.outputVideoCode=0x%x\n",
990 (int)video_data.inputVideoCode, video_data.outputVideoCode));
991
992 /* ifData[7] = video_data.outputVideoCode; */
993 ifData[8] = 0x00;
994 ifData[9] = 0x00;
995 ifData[10] = 0x00;
996 ifData[11] = 0x00;
997 ifData[12] = 0x00;
998 ifData[13] = 0x00;
999 ifData[14] = 0x00;
1000 ifData[15] = 0x00;
1001 ifData[16] = 0x00;
1002 ifData[3] = CalculateInfoFrameChecksum(ifData);
1003 SiiRegModify(TX_PAGE_L1 | 0x3E, BIT0 | BIT1, CLEAR_BITS);
1004 SiiRegWriteBlock(TX_PAGE_L1 | 0x0040, ifData, SIZE_AVI_INFOFRAME);
1005 SiiRegModify(TX_PAGE_L1 | 0x3E, BIT0 | BIT1, SET_BITS);
1006}
1007
1008static uint8_t CalculateInfoFrameChecksum(uint8_t *infoFrameData)
1009{
1010 uint8_t i, checksum;
1011 checksum = 0x00;
1012 for (i = 0; i < SIZE_AVI_INFOFRAME; i++) {
1013 checksum += infoFrameData[i];
1014 }
1015 checksum = 0x100 - checksum;
1016 return checksum;
1017}
1018
1019PLACE_IN_CODE_SEG const audioConfig_t audioData[AUD_TYP_NUM] = {
1020 {0x11, 0x40, 0x0E, 0x03, 0x00, 0x05},
1021 {0x11, 0x40, 0x0A, 0x01, 0x00, 0x05},
1022 {0x11, 0x40, 0x02, 0x00, 0x00, 0x05},
1023 {0x11, 0x40, 0x0C, 0x03, 0x00, 0x05},
1024 {0x11, 0x40, 0x08, 0x01, 0x00, 0x05},
1025 {0x11, 0x40, 0x00, 0x00, 0x00, 0x05},
1026 {0x11, 0x40, 0x03, 0x00, 0x00, 0x05},
1027 {0x11, 0x40, 0x0E, 0x03, 0x03, 0x05},
1028 {0x11, 0x40, 0x0A, 0x01, 0x03, 0x05},
1029 {0x11, 0x40, 0x02, 0x00, 0x03, 0x05},
1030 {0x11, 0x40, 0x0C, 0x03, 0x03, 0x05},
1031 {0x11, 0x40, 0x08, 0x01, 0x03, 0x05},
1032 {0x11, 0x40, 0x00, 0x00, 0x03, 0x05},
1033 {0x11, 0x40, 0x03, 0x00, 0x03, 0x05},
1034 {0xF1, 0x40, 0x0E, 0x00, 0x03, 0x07},
1035 {0x03, 0x00, 0x00, 0x00, 0x00, 0x05}
1036};
1037
1038static void SetAudioMode(inAudioTypes_t audiomode)
1039{
1040 if (audiomode >= AUD_TYP_NUM)
1041 audiomode = I2S_48;
1042 SiiRegWrite(TX_PAGE_L1 | 0x2F, audioData[audiomode].regAUD_path);
1043 SiiRegWrite(TX_PAGE_L1 | 0x14, audioData[audiomode].regAUD_mode);
1044 SiiRegWrite(TX_PAGE_L1 | 0x1D, audioData[audiomode].regAUD_ctrl);
1045 SiiRegWrite(TX_PAGE_L1 | 0x21, audioData[audiomode].regAUD_freq);
1046 SiiRegWrite(TX_PAGE_L1 | 0x23, audioData[audiomode].regAUD_src);
1047 SiiRegWrite(TX_PAGE_L1 | 0x28, audioData[audiomode].regAUD_tdm_ctrl);
1048/* SiiRegWrite(TX_PAGE_L1 | 0x22, 0x0B); */
1049/* 0x02 for word length=16bits */
1050 SiiRegWrite(TX_PAGE_L1 | 0x22, 0x02);
1051 SiiRegWrite(TX_PAGE_L1 | 0x24, 0x02);
1052
1053 SiiRegWrite(TX_PAGE_L1 | 0x15, 0x00);
1054 /* 0x7A:0x24 = 0x0B for word lenth is defult 24bit */
1055
1056 TX_DEBUG_PRINT(("SiiRegRead(TX_PAGE_L1 | 0x21)=0x%x\n", SiiRegRead(TX_PAGE_L1 | 0x21)));
1057 TX_DEBUG_PRINT(("SiiRegRead(TX_PAGE_L1 | 0x1D)=0x%x\n", SiiRegRead(TX_PAGE_L1 | 0x1D)));
1058}
1059
1060static void SetACRNValue(void)
1061{
1062 uint8_t audioFs;
1063 if ((SiiRegRead(TX_PAGE_L1 | 0x14) & BIT1) && !(SiiRegRead(TX_PAGE_L1 | 0x15) & BIT1))
1064 audioFs = SiiRegRead(TX_PAGE_L1 | 0x18) & 0x0F;
1065 else
1066 audioFs = SiiRegRead(TX_PAGE_L1 | 0x21) & 0x0F;
1067 switch (audioFs) {
1068 case 0x03:
1069 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_32k >> 16));
1070 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_32k >> 8));
1071 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_32k));
1072 break;
1073 case 0x00:
1074 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_44k >> 16));
1075 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_44k >> 8));
1076 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_44k));
1077 break;
1078 case 0x02:
1079 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_48k >> 16));
1080 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_48k >> 8));
1081 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_48k));
1082 break;
1083 case 0x08:
1084 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_88k >> 16));
1085 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_88k >> 8));
1086 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_88k));
1087 break;
1088 case 0x0A:
1089 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_96k >> 16));
1090 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_96k >> 8));
1091 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_96k));
1092 break;
1093 case 0x0C:
1094 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_176k >> 16));
1095 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_176k >> 8));
1096 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_176k));
1097 break;
1098 case 0x0E:
1099 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_192k >> 16));
1100 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_192k >> 8));
1101 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_192k));
1102 break;
1103 default:
1104 SiiRegWrite(TX_PAGE_L1 | 0x05, (uint8_t) (ACR_N_value_default >> 16));
1105 SiiRegWrite(TX_PAGE_L1 | 0x04, (uint8_t) (ACR_N_value_default >> 8));
1106 SiiRegWrite(TX_PAGE_L1 | 0x03, (uint8_t) (ACR_N_value_default));
1107 break;
1108 }
1109 SiiRegModify(TX_PAGE_L1 | 0x2F, BIT2, CLEAR_BITS);
1110}
1111
1112static void SendAudioInfoFrame(void)
1113{
1114 SiiRegModify(TX_PAGE_L1 | 0x3E, BIT4 | BIT5, CLEAR_BITS);
1115 SiiRegWrite(TX_PAGE_L1 | 0x80, 0x84);
1116 SiiRegWrite(TX_PAGE_L1 | 0x81, 0x01);
1117 SiiRegWrite(TX_PAGE_L1 | 0x82, 0x0A);
1118 SiiRegWrite(TX_PAGE_L1 | 0x83, 0x70);
1119 SiiRegWrite(TX_PAGE_L1 | 0x84, 0x01);
1120 SiiRegWrite(TX_PAGE_L1 | 0x8D, 0x00);
1121 SiiRegModify(TX_PAGE_L1 | 0x3E, BIT4 | BIT5, SET_BITS);
1122}
1123
1124static void AudioVideoIsr(bool_t force_update)
1125{
1126 AVModeChange_t mode_change = { false, false };
1127 /* static AVMode_t mode = {VM_INVALID, AUD_INVALID}; */
1128 if (force_update) {
1129 if (1) /* (SiiVideoInputIsValid()) */
1130 {
1131 TX_DEBUG_PRINT(("SiiVideoInputIsValid,audio_changed,video_changed\n"));
1132 mode_change.audio_change = true;
1133 mode_change.video_change = true;
1134 }
1135 } else {
1136 TX_DEBUG_PRINT(("force_update=false...............\n"));
1137 /* AVModeDetect(&mode_change, &AVmode); */
1138 }
1139 if (mode_change.audio_change) {
1140 TX_DEBUG_PRINT(("SetAudioMode & SetACRNValue\n"));
1141 /* SetAudioMode(mode.audio_mode); */
1142 SetAudioMode(AVmode.audio_mode);
1143 SetACRNValue();
1144 }
1145 if (mode_change.video_change) /* && SiiVideoInputIsValid()) */
1146 {
1147 TX_DEBUG_PRINT(("mode_change.video_changed =true\n "));
1148 SiiRegModify(TX_PAGE_L0 | 0x00C7, BIT5, SET_BITS);
1149 SiiRegModify(TX_PAGE_3 | 0x0000, BIT0, SET_BITS);
1150 /* video_data.outputColorSpace = video_data.inputColorSpace; */
1151 video_data.outputVideoCode = video_data.inputVideoCode;
1152 video_data.outputcolorimetryAspectRatio = video_data.inputcolorimetryAspectRatio;
1153 SiiRegModify(TX_PAGE_3 | 0x0000, BIT0, CLEAR_BITS);
1154 SiiRegModify(TX_PAGE_L0 | 0x00C7, BIT5, CLEAR_BITS);
1155 }
1156 if ((mode_change.video_change || mode_change.audio_change) && tmdsPowRdy) {
1157 if (1) /* (SiiVideoInputIsValid()) */
1158 {
1159 SiiRegModify(TX_PAGE_L0 | 0x0080, BIT4, SET_BITS);
1160 SendAudioInfoFrame();
1161 TX_DEBUG_PRINT(("((mode_change.video_change || mode_change.audio_change) && tmdsPowRdy)\n"));
1162 SendAviInfoframe();
1163 } else {
1164 SiiRegModify(TX_PAGE_L0 | 0x0080, BIT4, CLEAR_BITS);
1165 TX_DEBUG_PRINT(("TMDS Ouput Disabled due to invalid input\n"));
1166 }
1167 }
1168}
1169
1170#if 0 /* /!defined GPIO_MHL_RST_B_PIN */
1171#error GPIO_MHL_RST_B_PIN no defined
1172#endif
1173
1174void SiiMhlTxHwResetKeepLow(void)
1175{
1176 printk("%s,%d\n", __func__, __LINE__);
1177#ifdef GPIO_MHL_RST_B_PIN
1178 mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ZERO);
1179#else
1180 printk("%s,%d Error: GPIO_MHL_RST_B_PIN is not defined\n", __func__, __LINE__);
1181#endif
1182}
1183
1184void SiiMhlTxHwReset(uint16_t hwResetPeriod, uint16_t hwResetDelay)
1185{
1186#ifdef GPIO_MHL_RST_B_PIN
1187 printk("%s,%d\n", __func__, __LINE__);
1188 mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ONE);
1189 msleep(hwResetPeriod);
1190 mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ZERO);
1191 msleep(hwResetPeriod);
1192 mt_set_gpio_out(GPIO_MHL_RST_B_PIN, GPIO_OUT_ONE);
1193 msleep(hwResetDelay);
1194#else
1195 printk("%s,%d Error: GPIO_MHL_RST_B_PIN is not defined\n", __func__, __LINE__);
1196#endif
1197}
1198
1199#if 0
1200/* mt6577 */
1201void SiiMhlTxHwGpioSuspend(void)
1202{
1203 int i;
1204 u32 gpio[] = {
1205 GPIO19, GPIO20, GPIO21, GPIO22, GPIO23,
1206 GPIO24, GPIO25, GPIO26, GPIO27, GPIO28,
1207 GPIO29, GPIO30, GPIO31, GPIO32, GPIO33,
1208 GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
1209 GPIO39, GPIO40, GPIO41, GPIO42, GPIO43,
1210 GPIO44, GPIO45, GPIO46, GPIO53, GPIO54,
1211 GPIO55,
1212 };
1213
1214 printk("%s,%d\n", __func__, __LINE__);
1215
1216 for (i = 0; i < ARRAY_SIZE(gpio); i++) {
1217 mt_set_gpio_mode(gpio[i], GPIO_MODE_00);
1218 mt_set_gpio_dir(gpio[i], GPIO_DIR_IN);
1219 mt_set_gpio_pull_select(gpio[i], GPIO_PULL_DOWN);
1220 mt_set_gpio_pull_enable(gpio[i], GPIO_PULL_ENABLE);
1221 }
1222}
1223#else
1224void SiiMhlTxHwGpioSuspend(void)
1225{
1226#ifdef MHL_SET_GPIO_MODE
1227 int i;
1228 u32 gpio[] = {
1229 GPIO143, GPIO144, GPIO145, GPIO146, GPIO147,
1230 GPIO148, GPIO149, GPIO150, GPIO151, GPIO152,
1231 GPIO153, GPIO154, GPIO155, GPIO156, GPIO157,
1232 GPIO158, GPIO159, GPIO160, GPIO161, GPIO162,
1233 GPIO163, GPIO164, GPIO165, GPIO166, GPIO167,
1234 GPIO168, GPIO169, GPIO170, GPIO120, GPIO121,
1235 GPIO122,
1236 };
1237 printk("%s,%d\n", __func__, __LINE__);
1238 for (i = 0; i < ARRAY_SIZE(gpio); i++) {
1239 mt_set_gpio_mode(gpio[i], GPIO_MODE_00);
1240 mt_set_gpio_dir(gpio[i], GPIO_DIR_IN);
1241 mt_set_gpio_pull_select(gpio[i], GPIO_PULL_DOWN);
1242 mt_set_gpio_pull_enable(gpio[i], GPIO_PULL_ENABLE);
1243 }
1244#endif
1245}
1246#endif
1247
1248#if 0
1249/* mt6577 */
1250void SiiMhlTxHwGpioResume(void)
1251{
1252 int i;
1253 u32 gpio_rgb[] = {
1254 GPIO19, GPIO20, GPIO21, GPIO22, GPIO23,
1255 GPIO24, GPIO25, GPIO26, GPIO27, GPIO28,
1256 GPIO29, GPIO30, GPIO31, GPIO32, GPIO33,
1257 GPIO34, GPIO35, GPIO36, GPIO37, GPIO38,
1258 GPIO39, GPIO40, GPIO41, GPIO42, GPIO43,
1259 GPIO44, GPIO45, GPIO46
1260 };
1261
1262 u32 gpio_i2s[] = { GPIO53, GPIO54, GPIO55 };
1263
1264 printk("%s,%d\n", __func__, __LINE__);
1265
1266 for (i = 0; i < ARRAY_SIZE(gpio_rgb); i++) {
1267 mt_set_gpio_mode(gpio_rgb[i], GPIO_MODE_01);
1268 mt_set_gpio_pull_enable(gpio_rgb[i], GPIO_PULL_DISABLE);
1269 }
1270
1271 for (i = 0; i < ARRAY_SIZE(gpio_i2s); i++) {
1272 mt_set_gpio_mode(gpio_i2s[i], GPIO_MODE_04);
1273 mt_set_gpio_pull_select(gpio_i2s[i], GPIO_PULL_DOWN);
1274 mt_set_gpio_pull_enable(gpio_i2s[i], GPIO_PULL_ENABLE);
1275 }
1276}
1277#else
1278void SiiMhlTxHwGpioResume(void)
1279{
1280#ifdef MHL_SET_GPIO_MODE
1281 int i;
1282 u32 gpio_rgb[] = {
1283 GPIO143, GPIO144, GPIO145, GPIO146, GPIO147,
1284 GPIO148, GPIO149, GPIO150, GPIO151, GPIO152,
1285 GPIO153, GPIO154, GPIO155, GPIO156, GPIO157,
1286 GPIO158, GPIO159, GPIO160, GPIO161, GPIO162,
1287 GPIO163, GPIO164, GPIO165, GPIO166, GPIO167,
1288 GPIO168, GPIO169, GPIO170
1289 };
1290 u32 gpio_i2s[] = { GPIO120, GPIO121, GPIO122 };
1291 printk("%s,%d\n", __func__, __LINE__);
1292 for (i = 0; i < ARRAY_SIZE(gpio_rgb); i++) {
1293 mt_set_gpio_mode(gpio_rgb[i], GPIO_MODE_01);
1294 mt_set_gpio_pull_enable(gpio_rgb[i], GPIO_PULL_DISABLE);
1295 }
1296
1297 for (i = 0; i < ARRAY_SIZE(gpio_i2s); i++) {
1298 mt_set_gpio_mode(gpio_i2s[i], GPIO_MODE_01);
1299 mt_set_gpio_pull_select(gpio_i2s[i], GPIO_PULL_DOWN);
1300 mt_set_gpio_pull_enable(gpio_i2s[i], GPIO_PULL_ENABLE);
1301 }
1302#endif
1303}
1304#endif
1305
1306
1307#if defined(USE_PROC) && defined(__KERNEL__)
1308void drv_mhl_seq_show(struct seq_file *s)
1309{
1310 int gpio_value;
1311 switch (fwPowerState) {
1312 case POWER_STATE_D3:
1313 seq_puts(s, "MHL POWER STATE [D3]\n");
1314 break;
1315 case POWER_STATE_D0_NO_MHL:
1316 seq_puts(s, "MHL POWER STATE [D0_NO_MHL]\n");
1317 break;
1318 case POWER_STATE_D0_MHL:
1319 seq_puts(s, "MHL POWER STATE [D0_MHL]\n");
1320 break;
1321 case POWER_STATE_FIRST_INIT:
1322 seq_puts(s, "MHL POWER STATE [FIRST_INIT]\n");
1323 break;
1324 default:
1325 break;
1326 }
1327 if (tmdsPowRdy)
1328 seq_puts(s, "TMDS [ON]\n");
1329 else
1330 seq_puts(s, "TMDS [OFF]\n");
1331 HalGpioGetPin(GPIO_SRC_VBUS_ON, &gpio_value);
1332 if (gpio_value)
1333 seq_puts(s, "SRC BUS [ON]\n");
1334 else
1335 seq_puts(s, "SRC BUS [OFF]\n");
1336 HalGpioGetPin(GPIO_SINK_VBUS_ON, &gpio_value);
1337 if (gpio_value)
1338 seq_puts(s, "SINK BUS [ON]\n");
1339 else
1340 seq_puts(s, "SINK BUS [OFF]\n");
1341}
1342#endif
1343
1344/* ------------------------------------------------------------------------------ */
1345/* Function Name: siHdmiTx_VideoSel() */
1346/* Function Description: Select output video mode */
1347/* */
1348/* Accepts: Video mode */
1349/* Returns: none */
1350/* Globals: none */
1351/* ------------------------------------------------------------------------------ */
1352void siHdmiTx_VideoSel(int vmode)
1353{
1354 int AspectRatio = 0;
1355 video_data.inputColorSpace = COLOR_SPACE_RGB;
1356 video_data.outputColorSpace = COLOR_SPACE_RGB;
1357 video_data.inputVideoCode = vmode;
1358 /* siHdmiTx.ColorDepth = VMD_COLOR_DEPTH_8BIT; */
1359 /* siHdmiTx.SyncMode = EXTERNAL_HSVSDE; */
1360
1361 switch (vmode) {
1362 case HDMI_480I60_4X3:
1363 case HDMI_576I50_4X3:
1364 AspectRatio = VMD_ASPECT_RATIO_4x3;
1365 break;
1366
1367 case HDMI_480I60_16X9:
1368 case HDMI_576I50_16X9:
1369 AspectRatio = VMD_ASPECT_RATIO_16x9;
1370 break;
1371
1372 case HDMI_480P60_4X3:
1373 case HDMI_576P50_4X3:
1374 case HDMI_640X480P:
1375 AspectRatio = VMD_ASPECT_RATIO_4x3;
1376 break;
1377
1378 case HDMI_480P60_16X9:
1379 case HDMI_576P50_16X9:
1380 AspectRatio = VMD_ASPECT_RATIO_16x9;
1381 break;
1382
1383 case HDMI_720P60:
1384 case HDMI_720P50:
1385 case HDMI_1080I60:
1386 case HDMI_1080I50:
1387 case HDMI_1080P24:
1388 case HDMI_1080P25:
1389 case HDMI_1080P30:
1390 AspectRatio = VMD_ASPECT_RATIO_16x9;
1391 break;
1392
1393 default:
1394 break;
1395 }
1396 if (AspectRatio == VMD_ASPECT_RATIO_4x3)
1397 video_data.inputcolorimetryAspectRatio = 0x18;
1398 else
1399 video_data.inputcolorimetryAspectRatio = 0x28;
1400 video_data.input_AR = AspectRatio;
1401
1402}
1403
1404/* ------------------------------------------------------------------------------ */
1405/* Function Name: siHdmiTx_AudioSel() */
1406/* Function Description: Select output audio mode */
1407/* */
1408/* Accepts: Audio Fs */
1409/* Returns: none */
1410/* Globals: none */
1411/* ------------------------------------------------------------------------------ */
1412void siHdmiTx_AudioSel(int AduioMode)
1413{
1414 AVmode.audio_mode = AduioMode;
1415 /*
1416 siHdmiTx.AudioChannels = ACHANNEL_2CH;
1417 siHdmiTx.AudioFs = Afs;
1418 siHdmiTx.AudioWordLength = ALENGTH_24BITS;
1419 siHdmiTx.AudioI2SFormat = (MCLK256FS << 4) |SCK_SAMPLE_RISING_EDGE |0x00; //last num 0x00-->0x02
1420 */
1421}
1422
1423/* ------------------------------------------------------------------------------ */
1424/* Function Name: siMhlTx_AudioSet() */
1425/* Function Description: Set the 9022/4 audio interface to basic audio. */
1426/* */
1427/* Accepts: none */
1428/* Returns: Success message if audio changed successfully. */
1429/* Error Code if resolution change failed */
1430/* Globals: mhlTxAv */
1431/* ------------------------------------------------------------------------------ */
1432uint8_t siMhlTx_AudioSet(void)
1433{
1434 TX_DEBUG_PRINT(("[MHL]: >>siMhlTx_AudioSet()\n"));
1435
1436 /* SetAudioMute(AUDIO_MUTE_MUTED); // mute output */
1437 SetAudioMode(AVmode.audio_mode);
1438 SetACRNValue();
1439 return 0;
1440}
1441
1442/* ------------------------------------------------------------------------------ */
1443/* Function Name: siMhlTx_VideoAudioSet() */
1444/* Function Description: Set the 9022/4 video resolution */
1445/* */
1446/* Accepts: none */
1447/* Returns: Success message if video resolution changed successfully. */
1448/* Error Code if resolution change failed */
1449/* Globals: mhlTxAv */
1450/* ------------------------------------------------------------------------------ */
1451/* ============================================================ */
1452#define T_RES_CHANGE_DELAY 128 /* delay between turning TMDS bus off and changing output resolution */
1453
1454uint8_t siMhlTx_VideoAudioSet(void)
1455{
1456 TX_DEBUG_PRINT(("[MHL]: >>siMhlTx_VideoAudioSet()\n"));
1457
1458 SiiRegModify(TX_PAGE_L1 | 0xDF, BIT0, SET_BITS);
1459
1460 SiiMhlTxDrvTmdsControl(false);
1461 HalTimerWait(T_RES_CHANGE_DELAY); /* allow control InfoFrames to pass through to the sink device. */
1462 /* siMhlTx_AudioSet(); */
1463 AudioVideoIsr(true);
1464 /* siMhlTx_Init(); */
1465 SiiRegModify(TX_PAGE_L1 | 0xDF, BIT0, CLEAR_BITS);
1466 SiiMhlTxTmdsEnable();
1467 return 0;
1468}