2 * Copyright (C) 2009 NXP N.V., All Rights Reserved.
3 * This source code and any compilation or derivative thereof is the proprietary
4 * information of NXP N.V. and is confidential in nature. Under no circumstances
5 * is this software to be exposed to or placed under an Open Source License of
6 * any type without the expressed written permission of NXP N.V.
8 * \file tmbslTDA9989_misc.c
10 * \version %version: 3 %
15 /*============================================================================*/
17 /*============================================================================*/
26 #ifndef TMFL_LINUX_OS_KERNEL_DRIVER
27 #define TMFL_LINUX_OS_KERNEL_DRIVER
31 #ifdef TMFL_LINUX_OS_KERNEL_DRIVER
32 #include <linux/kernel.h>
35 #include "tmbslHdmiTx_types.h"
36 #include "tmbslTDA9989_Functions.h"
37 #include "tmbslTDA9989_local.h"
38 #include "tmbslTDA9989_HDCP_l.h"
39 #include "tmbslTDA9989_State_l.h"
40 #include "tmbslTDA9989_InOut_l.h"
41 #include "tmbslTDA9989_Edid_l.h"
42 #include "tmbslTDA9989_Misc_l.h"
44 /*============================================================================*/
45 /* TYPES DECLARATIONS */
46 /*============================================================================*/
48 /*============================================================================*/
49 /* CONSTANTS DECLARATIONS EXPORTED */
50 /*============================================================================*/
52 /*============================================================================*/
53 /* CONSTANTS DECLARATIONS */
54 /*============================================================================*/
56 /** Preset default values for an object instance */
57 static tmHdmiTxobject_t kHdmiTxInstanceDefault
= {
58 ST_UNINITIALIZED
, /* state */
59 0, /* nIgnoredEvents */
62 (ptmbslHdmiTxSysFunc_t
) 0, /* sysFuncWrite */
63 (ptmbslHdmiTxSysFunc_t
) 0, /* sysFuncRead */
64 (ptmbslHdmiTxSysFuncEdid_t
) 0, /* sysFuncEdidRead */
65 (ptmbslHdmiTxSysFuncTimer_t
) 0, /* sysFuncTimer */
66 { /* funcIntCallbacks[] */
67 (ptmbslHdmiTxCallback_t
) 0},
68 0, /* InterruptsEnable */
69 { /* uSupportedVersions[] */
71 E_DEV_VERSION_TDA19989
,
72 E_DEV_VERSION_TDA19989_N2
,
73 E_DEV_VERSION_TDA19988
,
74 E_DEV_VERSION_LIST_END
},
75 E_DEV_VERSION_LIST_END
, /* uDeviceVersion */
76 E_DEV_VERSION_LIST_END
, /* uDeviceFeatures */
77 (tmbslHdmiTxPowerState_t
) tmPowerOff
, /* ePowerState */
78 False
, /* EdidAlternateAddr */
79 HDMITX_SINK_DVI
, /* sinkType */
80 HDMITX_SINK_DVI
, /* EdidSinkType */
81 False
, /* EdidSinkAi */
84 0, /* EdidCeaXVYCCFlags */
86 False
, /* latency_available */
87 False
, /* Ilatency_available */
88 0, /* Edidvideo_latency */
89 0, /* Edidaudio_latency */
90 0, /* EdidIvideo_latency */
91 0}, /* EdidIaudio_latency */
94 0, /* maximum supported TMDS clock */
95 0, /* content type Graphics (text) */
96 0, /* content type Photo */
97 0, /* content type Cinema */
98 0, /* content type Game */
99 0, /* additional video format */
100 0, /* 3D support by the HDMI Sink */
101 0, /* 3D multi strctures present */
102 0, /* additional info for the values in the image size area */
103 0, /* total length of 3D video formats */
104 0, /* total length of extended video formats */
105 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* max_len-10, ie: 31-10=21 */
108 HDMITX_EDID_NOT_READ
, /* EdidStatus */
110 { /* EdidDTD: *//* * NUMBER_DTD_STORED */
111 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*1 */
112 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*2 */
113 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*3 */
114 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*4 */
115 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*5 */
116 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*6 */
117 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*7 */
118 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*8 */
119 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /*9 */
120 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /*10 */
122 { /* EdidMonitorDescriptor */
123 False
, /* bDescRecord */
124 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* uMonitorName[EDID_MONITOR_DESCRIPTOR_SIZE] */
127 False
, /* bDescRecord */
128 0, /* uMinVerticalRate */
129 0, /* uMaxVerticalRate */
130 0, /* uMinHorizontalRate */
131 0, /* uMaxHorizontalRate */
132 0 /* uMaxSupportedPixelClk */
135 False
, /* bDescRecord */
136 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* uOtherDescriptor[EDID_MONITOR_DESCRIPTOR_SIZE] */
142 {0, 0, 0} /* {ModeChans, Freqs, Byte3} */
148 0, /* EdidBlockCnt */
149 0, /* EdidSourceAddress */
150 0, /* EdidBlockRequested */
151 False
, /* EdidReadStarted */
156 { /* EDIDBasicDisplayParam */
157 0, /* uVideoInputDef */
158 0, /* uMaxHorizontalSize */
159 0, /* uMaxVerticalSize */
161 0, /* uFeatureSupport */
163 #ifdef TMFL_HDCP_SUPPORT
164 False
, /* HDCPIgnoreEncrypt */
165 0, /* HdcpPortAddress */
166 HDMITX_HDCP_TXMODE_NOT_SET
, /* HdcpTxMode */
167 HDMITX_HDCP_OPTION_DEFAULT
, /* HdcpOptions */
171 0, /* HdcpFsmState */
172 0, /* HdcpT0FailState */
174 {0, 0, 0, 0, 0}, /* HdcpAksv */
175 (ptmHdmiTxFunc_t
) 0, /* HdcpFuncScheduled */
176 0, /* HdcpFuncRemainingMs */
177 0, /* HdcpCheckIntervalMs */
178 0, /* HdcpCheckRemainingMs */
179 0, /* HdcpCheckNum */
180 0, /* HdcpChecksToDo */
181 #endif /* TMFL_HDCP_SUPPORT */
182 HDMITX_VFMT_NULL
, /* vinFmt */
183 HDMITX_VFMT_NULL
, /* voutFmt */
184 HDMITX_PIXRATE_DOUBLE
, /* pixRate */
185 HDMITX_VINMODE_RGB444
, /* vinMode */
186 HDMITX_VOUTMODE_RGB444
, /* voutMode */
187 HDMITX_VFREQ_INVALID
, /* voutFreq */
188 HDMITX_SCAMODE_OFF
, /* scaMode */
189 HDMITX_UPSAMPLE_AUTO
, /* upsampleMode */
190 HDMITX_PIXREP_MIN
, /* pixelRepeatCount */
191 HDMITX_HOTPLUG_INVALID
, /* hotPlugStatus */
192 HDMITX_RX_SENSE_INVALID
, /* rxSenseStatus */
193 E_PAGE_INVALID
, /* curRegPage */
195 /* These match power-up defaults. shadowReg[]: */
196 0x00, /* E_SP00_INT_FLAGS_0 */
197 0x00, /* E_SP00_INT_FLAGS_1 */
198 0x00, /* E_SP00_INT_FLAGS_2 */
199 0x01, /* E_SP00_VIP_CNTRL_0 */
200 0x24, /* E_SP00_VIP_CNTRL_1 */
201 0x56, /* E_SP00_VIP_CNTRL_2 */
202 0x17, /* E_SP00_VIP_CNTRL_3 */
203 0x01, /* E_SP00_VIP_CNTRL_4 */
204 0x00, /* E_SP00_VIP_CNTRL_5 */
205 0x05, /* E_SP00_MAT_CONTRL */
206 0x00, /* E_SP00_TBG_CNTRL_0 */
207 0x00, /* E_SP00_TBG_CNTRL_1 */
208 0x00, /* E_SP00_HVF_CNTRL_0 */
209 0x00, /* E_SP00_HVF_CNTRL_1 */
210 0x00, /* E_SP00_TIMER_H */
211 0x00, /* E_SP00_DEBUG_PROBE */
212 0x00 /* E_SP00_AIP_CLKSEL */
213 , 0x00 /* E_SP01_SC_VIDFORMAT */
214 , 0x00 /* E_SP01_SC_CNTRL */
215 , 0x00 /* E_SP01_TBG_CNTRL_0 */
216 #ifdef TMFL_HDCP_SUPPORT
217 , 0x00 /* E_SP12_CTRL */
218 , 0x00 /* E_SP12_BCAPS */
219 #endif /* TMFL_HDCP_SUPPORT */
221 False
, /* Init prevFilterPattern to false */
222 False
, /* Init prevPattern to false */
223 False
, /* bInitialized */
229 * Table of shadow registers, as packed Shad/Page/Addr codes.
230 * This allows shadow index values to be searched for using register page
231 * and address values.
233 static UInt16 kShadowReg
[E_SNUM
] = { /* Shadow Index Packed Shad/Page/Addr */
234 E_REG_P00_INT_FLAGS_0_RW
, /* E_SP00_INT_FLAGS_0 */
235 E_REG_P00_INT_FLAGS_1_RW
, /* E_SP00_INT_FLAGS_1 */
236 E_REG_P00_INT_FLAGS_2_RW
, /* E_SP00_INT_FLAGS_2 */
237 E_REG_P00_VIP_CNTRL_0_W
, /* E_SP00_VIP_CNTRL_0 */
238 E_REG_P00_VIP_CNTRL_1_W
, /* E_SP00_VIP_CNTRL_1 */
239 E_REG_P00_VIP_CNTRL_2_W
, /* E_SP00_VIP_CNTRL_2 */
240 E_REG_P00_VIP_CNTRL_3_W
, /* E_SP00_VIP_CNTRL_3 */
241 E_REG_P00_VIP_CNTRL_4_W
, /* E_SP00_VIP_CNTRL_4 */
242 E_REG_P00_VIP_CNTRL_5_W
, /* E_SP00_VIP_CNTRL_5 */
243 E_REG_P00_MAT_CONTRL_W
, /* E_SP00_MAT_CONTRL */
244 E_REG_P00_TBG_CNTRL_0_W
, /* E_SP00_TBG_CNTRL_0 */
245 E_REG_P00_TBG_CNTRL_1_W
, /* E_SP00_TBG_CNTRL_1 */
246 E_REG_P00_HVF_CNTRL_0_W
, /* E_SP00_HVF_CNTRL_0 */
247 E_REG_P00_HVF_CNTRL_1_W
, /* E_SP00_HVF_CNTRL_1 */
248 E_REG_P00_TIMER_H_W
, /* E_SP00_TIMER_H */
249 E_REG_P00_DEBUG_PROBE_W
, /* E_SP00_DEBUG_PROBE */
250 E_REG_P00_AIP_CLKSEL_W
, /* E_SP00_AIP_CLKSEL */
251 E_REG_P01_SC_VIDFORMAT_W
, /* E_SP01_SC_VIDFORMAT */
252 E_REG_P01_SC_CNTRL_W
, /* E_SP01_SC_CNTRL */
253 E_REG_P01_TBG_CNTRL_0_W
/* E_SP01_TBG_CNTRL_0 */
254 #ifdef TMFL_HDCP_SUPPORT
255 , E_REG_P12_CTRL_W
/* E_SP12_CTRL */
256 , E_REG_P12_BCAPS_W
/* E_SP12_BCAPS */
257 #endif /* TMFL_HDCP_SUPPORT */
262 * Table of registers to switch to low power (standby)
264 static tmHdmiTxRegMaskVal_t kPowerOff[] =
266 {E_REG_P02_TEST2_RW, E_MASKREG_P02_TEST2_pwd1v8, 1},
267 {E_REG_P02_PLL_SCG1_RW, E_MASKREG_P02_PLL_SCG1_scg_fdn, 1},
268 {E_REG_P02_PLL_SERIAL_1_RW, E_MASKREG_P02_PLL_SERIAL_1_srl_fdn, 1},
269 {E_REG_P02_PLL_DE_RW, E_MASKREG_P02_PLL_DE_pllde_fdn, 1},
270 {E_REG_P02_BUFFER_OUT_RW, E_MASKREG_P02_BUFFER_OUT_srl_force, 2},
271 {E_REG_P02_SEL_CLK_RW, E_MASKREG_P02_SEL_CLK_ena_sc_clk, 0},
272 {E_REG_P00_CCLK_ON_RW, E_MASKREG_P00_CCLK_ON_cclk_on, 0},
277 * Table of registers to switch to normal power (resume)
279 static tmHdmiTxRegMaskVal_t kPowerOn[] =
281 {E_REG_P02_TEST2_RW, E_MASKREG_P02_TEST2_pwd1v8, 0},
282 {E_REG_P02_PLL_SERIAL_1_RW, E_MASKREG_P02_PLL_SERIAL_1_srl_fdn, 0},
283 {E_REG_P02_PLL_DE_RW, E_MASKREG_P02_PLL_DE_pllde_fdn, 0},
284 {E_REG_P02_PLL_SCG1_RW, E_MASKREG_P02_PLL_SCG1_scg_fdn, 0},
285 {E_REG_P02_SEL_CLK_RW, E_MASKREG_P02_SEL_CLK_ena_sc_clk, 1},
286 {E_REG_P02_BUFFER_OUT_RW, E_MASKREG_P02_BUFFER_OUT_srl_force, 0},
287 {E_REG_P00_TBG_CNTRL_0_W, E_MASKREG_P00_TBG_CNTRL_0_sync_once,0},
288 {E_REG_P00_CCLK_ON_RW, E_MASKREG_P00_CCLK_ON_cclk_on, 1},
293 static tmbslHdmiTxCallbackInt_t kITCallbackPriority
[HDMITX_CALLBACK_INT_NUM
] = {
294 HDMITX_CALLBACK_INT_R0
, /**< R0 interrupt */
295 HDMITX_CALLBACK_INT_ENCRYPT
, /**< HDCP encryption switched off */
296 HDMITX_CALLBACK_INT_HPD
, /**< Transition on HPD input */
297 HDMITX_CALLBACK_INT_T0
, /**< HDCP state machine in state T0 */
298 HDMITX_CALLBACK_INT_BCAPS
, /**< BCAPS available */
299 HDMITX_CALLBACK_INT_BSTATUS
, /**< BSTATUS available */
300 HDMITX_CALLBACK_INT_SHA_1
, /**< sha-1(ksv,bstatus,m0)=V' */
301 HDMITX_CALLBACK_INT_PJ
, /**< pj=pj' check fails */
302 HDMITX_CALLBACK_INT_SW_INT
, /**< SW DEBUG interrupt */
303 HDMITX_CALLBACK_INT_RX_SENSE
, /**< RX SENSE interrupt */
304 HDMITX_CALLBACK_INT_EDID_BLK_READ
,
305 /**< EDID BLK READ interrupt */
306 HDMITX_CALLBACK_INT_VS_RPT
, /**< VS interrupt */
307 HDMITX_CALLBACK_INT_PLL_LOCK
/** PLL LOCK not present on TDA9984 */
312 #ifdef TMFL_TDA9989_PIXEL_CLOCK_ON_DDC
315 0, /* HDMITX_VFMT_NO_CHANGE */
316 4, /* HDMITX_VFMT_01_640x480p_60Hz */
317 4, /* HDMITX_VFMT_02_720x480p_60Hz */
318 4, /* HDMITX_VFMT_03_720x480p_60Hz */
319 12, /* HDMITX_VFMT_04_1280x720p_60Hz */
320 12, /* HDMITX_VFMT_05_1920x1080i_60Hz */
321 4, /* HDMITX_VFMT_06_720x480i_60Hz */
322 4, /* HDMITX_VFMT_07_720x480i_60Hz */
323 4, /* HDMITX_VFMT_08_720x240p_60Hz */
324 4, /* HDMITX_VFMT_09_720x240p_60Hz */
325 4, /* HDMITX_VFMT_10_720x480i_60Hz */
326 4, /* HDMITX_VFMT_11_720x480i_60Hz */
327 4, /* HDMITX_VFMT_12_720x240p_60Hz */
328 4, /* HDMITX_VFMT_13_720x240p_60Hz */
329 4, /* HDMITX_VFMT_14_1440x480p_60Hz */
330 4, /* HDMITX_VFMT_15_1440x480p_60Hz */
331 12, /* HDMITX_VFMT_16_1920x1080p_60Hz */
332 4, /* HDMITX_VFMT_17_720x576p_50Hz */
333 4, /* HDMITX_VFMT_18_720x576p_50Hz */
334 12, /* HDMITX_VFMT_19_1280x720p_50Hz */
335 12, /* HDMITX_VFMT_20_1920x1080i_50Hz */
336 4, /* HDMITX_VFMT_21_720x576i_50Hz */
337 4, /* HDMITX_VFMT_22_720x576i_50Hz */
338 4, /* HDMITX_VFMT_23_720x288p_50Hz */
339 4, /* HDMITX_VFMT_24_720x288p_50Hz */
340 4, /* HDMITX_VFMT_25_720x576i_50Hz */
341 4, /* HDMITX_VFMT_26_720x576i_50Hz */
342 4, /* HDMITX_VFMT_27_720x288p_50Hz */
343 4, /* HDMITX_VFMT_28_720x288p_50Hz */
344 4, /* HDMITX_VFMT_29_1440x576p_50Hz */
345 4, /* HDMITX_VFMT_30_1440x576p_50Hz */
346 12, /* HDMITX_VFMT_31_1920x1080p_50Hz */
347 12, /* HDMITX_VFMT_32_1920x1080p_24Hz */
348 12, /* HDMITX_VFMT_33_1920x1080p_25Hz */
349 12, /* HDMITX_VFMT_34_1920x1080p_30Hz */
354 0, /* HDMITX_VFMT_NO_CHANGE */
355 44, /* HDMITX_VFMT_01_640x480p_60Hz */
356 44, /* HDMITX_VFMT_02_720x480p_60Hz */
357 44, /* HDMITX_VFMT_03_720x480p_60Hz */
358 44, /* HDMITX_VFMT_04_1280x720p_60Hz */
359 44, /* HDMITX_VFMT_05_1920x1080i_60Hz */
360 44, /* HDMITX_VFMT_06_720x480i_60Hz */
361 44, /* HDMITX_VFMT_07_720x480i_60Hz */
362 44, /* HDMITX_VFMT_08_720x240p_60Hz */
363 44, /* HDMITX_VFMT_09_720x240p_60Hz */
364 44, /* HDMITX_VFMT_10_720x480i_60Hz */
365 44, /* HDMITX_VFMT_11_720x480i_60Hz */
366 44, /* HDMITX_VFMT_12_720x240p_60Hz */
367 44, /* HDMITX_VFMT_13_720x240p_60Hz */
368 44, /* HDMITX_VFMT_14_1440x480p_60Hz */
369 44, /* HDMITX_VFMT_15_1440x480p_60Hz */
370 44, /* HDMITX_VFMT_16_1920x1080p_60Hz */
371 44, /* HDMITX_VFMT_17_720x576p_50Hz */
372 44, /* HDMITX_VFMT_18_720x576p_50Hz */
373 44, /* HDMITX_VFMT_19_1280x720p_50Hz */
374 44, /* HDMITX_VFMT_20_1920x1080i_50Hz */
375 44, /* HDMITX_VFMT_21_720x576i_50Hz */
376 44, /* HDMITX_VFMT_22_720x576i_50Hz */
377 44, /* HDMITX_VFMT_23_720x288p_50Hz */
378 44, /* HDMITX_VFMT_24_720x288p_50Hz */
379 44, /* HDMITX_VFMT_25_720x576i_50Hz */
380 44, /* HDMITX_VFMT_26_720x576i_50Hz */
381 44, /* HDMITX_VFMT_27_720x288p_50Hz */
382 44, /* HDMITX_VFMT_28_720x288p_50Hz */
383 44, /* HDMITX_VFMT_29_1440x576p_50Hz */
384 44, /* HDMITX_VFMT_30_1440x576p_50Hz */
385 44, /* HDMITX_VFMT_31_1920x1080p_50Hz */
386 44, /* HDMITX_VFMT_32_1920x1080p_24Hz */
387 44, /* HDMITX_VFMT_33_1920x1080p_25Hz */
388 44, /* HDMITX_VFMT_34_1920x1080p_30Hz */
391 #endif /* TMFL_TDA9989_PIXEL_CLOCK_ON_DDC */
394 /*============================================================================*/
395 /* FUNCTIONS DECLARATIONS */
396 /*============================================================================*/
398 /*============================================================================*/
399 /* VARIABLES DECLARATIONS */
400 /*============================================================================*/
402 #ifdef TMFL_HDCP_SUPPORT
403 static UInt32 sgBcapsCounter
;
404 #endif /* TMFL_HDCP_SUPPORT */
406 #define TDA19989_DDC_SPEED_FACTOR 39
408 static Bool gMiscInterruptHpdRxEnable
= False
; /* Enable HPD and RX sense IT after */
409 /* first call done by init function */
410 static UInt8 int_level
= 0xFF;
411 /*============================================================================*/
412 /* FUNCTION PROTOTYPES */
413 /*============================================================================*/
415 /*============================================================================*/
416 /* tmbslTDA9989Deinit */
417 /*============================================================================*/
418 tmErrorCode_t
tmbslTDA9989Deinit(tmUnitSelect_t txUnit
) {
419 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
420 tmErrorCode_t err
; /* Error code */
421 UInt8 EnableModeMask
= 0; /* Local Variable */
423 /* Check unit parameter and point to its object */
424 err
= checkUnitSetDis(txUnit
, &pDis
);
425 RETIF(err
!= TM_OK
, err
)
427 /* patch to get successfull soft reset even if powerstate has been set to standby mode */
428 /*Write data in ENAMODS CEC Register */
429 EnableModeMask
= 0x40;
430 EnableModeMask
|= E_MASKREG_CEC_ENAMODS_ena_hdmi
; /*Enable HDMI Mode */
431 EnableModeMask
&= ~E_MASKREG_CEC_ENAMODS_dis_fro
; /* Enable FRO */
432 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, EnableModeMask
);
435 /* Hold the device in reset to disable it */
436 err
= setHwRegisterField(pDis
, E_REG_P00_MAIN_CNTRL0_RW
,
437 E_MASKREG_P00_MAIN_CNTRL0_sr
, 1);
440 /* patch to get successfull soft reset even if powerstate has been set to standby mode */
441 EnableModeMask
&= ~E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Disable HDMI Mode */
442 EnableModeMask
&= ~E_MASKREG_CEC_ENAMODS_ena_rxs
; /* Reset RxSense Mode */
443 EnableModeMask
|= E_MASKREG_CEC_ENAMODS_dis_fro
; /* Disable FRO */
444 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, EnableModeMask
);
447 /* Clear the Initialized flag to destroy the device instance */
448 pDis
->bInitialized
= False
;
450 setState(pDis
, EV_DEINIT
);
454 /*============================================================================*/
455 /* tmbslTDA9989HotPlugGetStatus */
456 /*============================================================================*/
457 tmErrorCode_t
tmbslTDA9989HotPlugGetStatus(tmUnitSelect_t txUnit
, tmbslHdmiTxHotPlug_t
*pHotPlugStatus
, Bool client
/* Used to determine whether the request comes from the application */
459 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
460 tmErrorCode_t err
; /* Error code */
461 UInt8 regVal
; /* Register value */
463 /* Check unit parameter and point to its object */
464 err
= checkUnitSetDis(txUnit
, &pDis
);
465 RETIF(err
!= TM_OK
, err
)
467 /* Check remaining parameters */
468 RETIF_BADPARAM(pHotPlugStatus
== (tmbslHdmiTxHotPlug_t
*) 0)
470 /* Read HPD RXS level */
471 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, ®Val
);
472 RETIF(err
!= TM_OK
, err
)
474 /* Read Hot Plug input status to know the actual level that caused the interrupt */
476 *pHotPlugStatus
= (regVal
& E_MASKREG_CEC_RXSHPDLEV_hpd_level
) ?
477 HDMITX_HOTPLUG_ACTIVE
: HDMITX_HOTPLUG_INACTIVE
;
480 *pHotPlugStatus
= pDis
->hotPlugStatus
;
486 /*============================================================================*/
487 /* tmbslTDA9989RxSenseGetStatus */
488 /*============================================================================*/
489 tmErrorCode_t
tmbslTDA9989RxSenseGetStatus(tmUnitSelect_t txUnit
, tmbslHdmiTxRxSense_t
*pRxSenseStatus
, Bool client
/* Used to determine whether the request comes from the application */
491 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
492 tmErrorCode_t err
; /* Error code */
493 UInt8 regVal
; /* Register value */
495 /* Check unit parameter and point to its object */
496 err
= checkUnitSetDis(txUnit
, &pDis
);
497 RETIF(err
!= TM_OK
, err
)
499 /* Check remaining parameters */
500 RETIF_BADPARAM(pRxSenseStatus
== (tmbslHdmiTxRxSense_t
*) 0)
503 /* Read HPD RXS level */
504 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, ®Val
);
505 RETIF(err
!= TM_OK
, err
)
508 /*Read RXS_FIL status to know the actual level that caused the interrupt */
510 *pRxSenseStatus
= (regVal
& E_MASKREG_CEC_RXSHPDLEV_rxs_level
) ?
511 HDMITX_RX_SENSE_ACTIVE
: HDMITX_RX_SENSE_INACTIVE
;
513 *pRxSenseStatus
= pDis
->rxSenseStatus
;
519 /*============================================================================*/
520 /* tmbslTDA9989HwGetRegisters */
521 /*============================================================================*/
523 tmbslTDA9989HwGetRegisters
524 (tmUnitSelect_t txUnit
, Int regPage
, Int regAddr
, UInt8
*pRegBuf
, Int nRegs
) {
525 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
526 tmErrorCode_t err
; /* Error code */
527 Int i
; /* Loop index */
528 UInt8 newRegPage
; /* The register's new page number */
529 UInt8 regShad
; /* Index to the register's shadow copy */
530 UInt16 regShadPageAddr
; /* Packed shadowindex/page/address */
531 tmbslHdmiTxSysArgs_t sysArgs
; /* Arguments passed to system function */
533 /* Check unit parameter and point to its object */
534 err
= checkUnitSetDis(txUnit
, &pDis
);
535 RETIF(err
!= TM_OK
, err
)
537 /* Check remaining parameters */
538 RETIF_BADPARAM((regPage
< kPageIndexToPage
[E_PAGE_00
])
539 || ((regPage
> kPageIndexToPage
[E_PAGE_02
])
540 && (regPage
< kPageIndexToPage
[E_PAGE_09
]))
541 || ((regPage
> kPageIndexToPage
[E_PAGE_09
])
542 && (regPage
< kPageIndexToPage
[E_PAGE_11
]))
543 || (regPage
> kPageIndexToPage
[E_PAGE_12
]))
544 RETIF_BADPARAM((regAddr
< E_REG_MIN_ADR
) || (regAddr
>= E_REG_CURPAGE_ADR_W
))
545 RETIF_BADPARAM(pRegBuf
== (pUInt8
) 0)
546 RETIF_BADPARAM((nRegs
< 1) || ((nRegs
+ regAddr
) > E_REG_CURPAGE_ADR_W
))
548 /* Set page register if required */
549 newRegPage
= (UInt8
) regPage
;
550 if (pDis
->curRegPage
!= newRegPage
) {
551 /* All non-OK results are errors */
552 sysArgs
.slaveAddr
= pDis
->uHwAddress
;
553 sysArgs
.firstRegister
= E_REG_CURPAGE_ADR_W
;
555 sysArgs
.pData
= &newRegPage
;
556 err
= pDis
->sysFuncWrite(&sysArgs
);
557 RETIF(err
!= TM_OK
, TMBSL_ERR_HDMI_I2C_WRITE
)
558 pDis
->curRegPage
= newRegPage
;
561 /* Read each register in the range. nRegs must start at 1 or more */
562 for (; nRegs
> 0; pRegBuf
++, regAddr
++, nRegs
--) {
563 /* Find shadow register index.
564 * This loop is not very efficient, but it is assumed that this API
565 * will not be used often. The alternative is to use a huge sparse
566 * array indexed by page and address and containing the shadow index.
569 for (i
= 0; i
< E_SNUM
; i
++) {
570 /* Check lookup table for match with page and address */
571 regShadPageAddr
= kShadowReg
[i
];
572 if ((SPA2PAGE(regShadPageAddr
) == newRegPage
)
573 && (SPA2ADDR(regShadPageAddr
) == regAddr
)) {
574 /* Found page and address - look up the shadow index */
575 regShad
= SPA2SHAD(regShadPageAddr
);
579 /* Read the shadow register if available, as device registers that
580 * are shadowed cannot be read directly */
581 if (regShad
!= E_SNONE
) {
582 *pRegBuf
= pDis
->shadowReg
[regShad
];
584 /* Read the device register - all non-OK results are errors.
585 * Note that some non-shadowed registers are also write-only and
587 sysArgs
.slaveAddr
= pDis
->uHwAddress
;
588 sysArgs
.firstRegister
= (UInt8
) regAddr
;
590 sysArgs
.pData
= pRegBuf
;
591 err
= pDis
->sysFuncRead(&sysArgs
);
592 RETIF(err
!= TM_OK
, TMBSL_ERR_HDMI_I2C_READ
)
599 /*============================================================================*/
600 /* tmbslTDA9989HwGetVersion */
601 /*============================================================================*/
603 tmErrorCode_t
tmbslTDA9989HwGetVersion(tmUnitSelect_t txUnit
, pUInt8 pHwVersion
) {
604 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
605 tmErrorCode_t err
; /* Error code */
608 /* Check unit parameter and point to its object */
609 err
= checkUnitSetDis(txUnit
, &pDis
);
610 RETIF(err
!= TM_OK
, err
)
612 /* Check remaining parameters */
613 RETIF_BADPARAM(pHwVersion
== (pUInt8
) 0)
615 /* Get MSB version Value */
616 err
= getHwRegister(pDis
, E_REG_P00_VERSION_MSB_RW
, ®Val
);
617 RETIF(err
!= TM_OK
, err
)
621 *pHwVersion
= (UInt8
) (BSLHDMITX_TDA9989
);
624 *pHwVersion
= (UInt8
) (BSLHDMITX_TDA19989
);
627 *pHwVersion
= (UInt8
) (BSLHDMITX_TDA19988
);
630 *pHwVersion
= (UInt8
) (BSLHDMITX_UNKNOWN
);
638 /*============================================================================*/
639 /* tmbslTDA9989HwHandleInterrupt */
640 /* RETIF_REG_FAIL NOT USED HERE AS ALL ERRORS SHOULD BE TRAPPED IN ALL BUILDS */
641 /*============================================================================*/
642 tmErrorCode_t
tmbslTDA9989HwHandleInterrupt(tmUnitSelect_t txUnit
) {
643 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
644 tmErrorCode_t err
; /* Error code */
645 UInt8 regVal
; /* Register value */
646 UInt8 regVal1
; /* Register value */
647 UInt16 fInterruptStatus
; /* Interrupt flags */
648 UInt16 fInterruptMask
; /* Mask to test each interrupt bit */
649 tmbslHdmiTxRxSense_t newRxs_fil
; /* Latest copy of rx_sense */
650 Int i
; /* Loop counter */
651 tmbslHdmiTxHotPlug_t newHpdIn
; /* Latest copy of hpd input */
652 Bool sendEdidCallback
;
653 Bool hpdOrRxsLevelHasChanged
= False
;
655 /* Check unit parameter and point to its object */
656 err
= checkUnitSetDis(txUnit
, &pDis
);
657 RETIF(err
!= TM_OK
, err
)
659 fInterruptStatus
= 0;
660 sendEdidCallback
= False
;
664 /* Read HPD RXS int status */
665 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINT_R
, ®Val
);
666 RETIF(err
!= TM_OK
, err
);
668 /* Read HPD RXS level */
669 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, ®Val1
);
670 RETIF(err
!= TM_OK
, err
);
672 if (int_level
!= 0xFF) { /* init should be done */
673 /* check multi-transition */
674 if ((regVal
== 0) && (int_level
!= regVal1
)) {
675 #ifdef TMFL_LINUX_OS_KERNEL_DRIVER
676 pr_debug("HDMI Int multi-transition\n");
678 err
= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, 0x00);
679 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
,
680 E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
|
681 E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
);
682 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, ®Val1
);
683 RETIF(err
!= TM_OK
, err
)
688 /* Read Hot Plug input status to know the actual level that caused the interrupt */
689 newHpdIn
= (regVal1
& E_MASKREG_CEC_RXSHPDLEV_hpd_level
) ?
690 HDMITX_HOTPLUG_ACTIVE
: HDMITX_HOTPLUG_INACTIVE
;
692 /*Read RXS_FIL status to know the actual level that caused the interrupt */
693 newRxs_fil
= (regVal1
& E_MASKREG_CEC_RXSHPDLEV_rxs_level
) ?
694 HDMITX_RX_SENSE_ACTIVE
: HDMITX_RX_SENSE_INACTIVE
;
696 /*Fill fInterruptStatus with HPD Interrupt flag */
698 if (newHpdIn
!= pDis
->hotPlugStatus
) {
699 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_HPD
);
700 /* Yes: save new HPD level */
701 pDis
->hotPlugStatus
= newHpdIn
;
702 hpdOrRxsLevelHasChanged
= True
;
705 /*Fill fInterruptStatus with RX Sense Interrupt flag */
706 if (newRxs_fil
!= pDis
->rxSenseStatus
) {
707 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_RX_SENSE
);
708 /* Yes: save new rxSense level */
709 pDis
->rxSenseStatus
= newRxs_fil
;
710 hpdOrRxsLevelHasChanged
= True
;
715 /* is it HDMI interrupt ? */
716 err
= getCECHwRegister(pDis
, E_REG_CEC_INTERRUPTSTATUS_R
, ®Val
);
717 RETIF(err
!= TM_OK
, err
)
719 /* there is no HDMI int to handle, give up */
720 if ((regVal
& E_MASKREG_CEC_INTERRUPTSTATUS_hdmi_int
) == 0x00) {
722 if (hpdOrRxsLevelHasChanged
== True
) {
730 /************************************************************************************************/
731 /***********************************End of Temporary code****************************************/
732 /************************************************************************************************/
734 /* Do only if HDMI is On */
735 if (pDis
->ePowerState
== tmPowerOn
) {
736 /* Read the main interrupt flags register to determine the source(s)
737 * of the interrupt. (The device resets these register flags after they
740 err
= getHwRegister(pDis
, E_REG_P00_INT_FLAGS_0_RW
, ®Val
);
741 RETIF(err
!= TM_OK
, err
)
742 #ifdef TMFL_HDCP_SUPPORT
744 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_encrypt
) != 0) {
745 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_ENCRYPT
);
747 #endif /* TMFL_HDCP_SUPPORT */
749 /* get TO interrupt Flag */
750 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_t0
) != 0) {
751 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_T0
);
753 #ifdef TMFL_HDCP_SUPPORT
755 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_bcaps
) != 0) {
756 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_BCAPS
);
758 /* TDA19989 N1 only */
759 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
761 /* WA: HDCP ATC Test 1B_03 */
765 if (sgBcapsCounter
== 49) {
767 /* force a T0 interrupt */
769 fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_T0
);
773 /* TDA19989 N1 only */
777 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_bstatus
) != 0) {
778 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_BSTATUS
);
780 /* TDA19989 N1 only */
781 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
783 /* WA: HDCP ATC Test 1B_03 */
787 /* TDA19989 N1 only */
791 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_sha_1
) != 0) {
792 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_SHA_1
);
796 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_pj
) != 0) {
797 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_PJ
);
801 if ((regVal
& E_MASKREG_P00_INT_FLAGS_0_r0
) != 0) {
802 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_R0
);
804 /* TDA19989 N1 only */
805 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
807 /* WA: HDCP ATC Test 1B_03 */
811 /* TDA19989 N1 only */
813 #endif /* TMFL_HDCP_SUPPORT */
816 err
= getHwRegister(pDis
, E_REG_P00_INT_FLAGS_1_RW
, ®Val
);
817 RETIF(err
!= TM_OK
, err
)
820 /* Read the software interrupt flag */
821 if ((regVal
& E_MASKREG_P00_INT_FLAGS_1_sw_int
) != 0) {
822 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_SW_INT
);
825 /* Read the VS_rpt interrupt flag */
826 if (((pDis
->InterruptsEnable
& E_MASKREG_P00_INT_FLAGS_1_vs_rpt
) != 0) &&
827 ((regVal
& E_MASKREG_P00_INT_FLAGS_1_vs_rpt
) != 0)
829 fInterruptStatus
= fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_VS_RPT
);
832 /* Read INT_FLAGS_2 interrupt flag register.
833 *(The device resets these register flags after they
834 * have been read.) */
835 err
= getHwRegister(pDis
, E_REG_P00_INT_FLAGS_2_RW
, ®Val
);
836 RETIF(err
!= TM_OK
, err
)
838 /* Has the EDID_blk_rd interrupt occurs */
839 if ((regVal
& E_MASKREG_P00_INT_FLAGS_2_edid_blk_rd
) != 0) {
841 fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_EDID_BLK_READ
);
846 /* Handle the HPD Interrupt */
847 if ((fInterruptStatus
& (1 << HDMITX_CALLBACK_INT_HPD
)) != 0) {
848 /* Callback disable on first tmbslTDA9989HwHandleInterrupt call */
849 if (gMiscInterruptHpdRxEnable
) {
850 /* Reset EDID status */
851 err
= ClearEdidRequest(txUnit
);
853 /* Reset all simultaneous HDCP interrupts on hot plug,
854 * preserving only the high-priority hpd interrupt rx_sense and sw interrupt for debug*/
855 fInterruptStatus
&= (1 << HDMITX_CALLBACK_INT_HPD
) |
856 (1 << HDMITX_CALLBACK_INT_RX_SENSE
) | (1 << HDMITX_CALLBACK_INT_SW_INT
);
858 if (pDis
->ePowerState
== tmPowerOn
) {
859 if ((pDis
->hotPlugStatus
== HDMITX_HOTPLUG_ACTIVE
)) {
861 /* TDA19989 N1 only */
862 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
864 err
= tmbslTDA9989Reset(txUnit
);
865 RETIF(err
!= TM_OK
, err
)
867 err
= hotPlugRestore(txUnit
);
868 RETIF(err
!= TM_OK
, err
)
871 /* TDA19989 N1 only */
872 else { /* TDA19989 N2 */
877 #ifdef TMFL_TDA9989_PIXEL_CLOCK_ON_DDC
879 err
= tmbslTDA9989Reset(txUnit
);
880 RETIF(err
!= TM_OK
, err
)
882 err
= hotPlugRestore(txUnit
);
883 RETIF(err
!= TM_OK
, err
)
884 #endif /* TMFL_TDA9989_PIXEL_CLOCK_ON_DDC */
885 setState(pDis
, EV_PLUGGEDIN
);
887 setState(pDis
, EV_UNPLUGGED
);
892 /* Clear HPD status if level has not changed */
893 fInterruptStatus
&= ~(1 << HDMITX_CALLBACK_INT_HPD
);
895 if (fInterruptStatus
& (1 << HDMITX_CALLBACK_INT_EDID_BLK_READ
)) {
896 err
= EdidBlockAvailable(txUnit
, &sendEdidCallback
);
897 RETIF(err
!= TM_OK
, err
)
898 if (sendEdidCallback
== False
) {
899 /* Read EDID not finished clear callback */
900 fInterruptStatus
&= ~(1 << HDMITX_CALLBACK_INT_EDID_BLK_READ
);
902 #ifdef TMFL_TDA9989_PIXEL_CLOCK_ON_DDC
904 if ((pDis
->vinFmt
== HDMITX_VFMT_16_1920x1080p_60Hz
)
905 || (pDis
->vinFmt
== HDMITX_VFMT_31_1920x1080p_50Hz
)) {
907 err
= setHwRegisterField(pDis
,
908 E_REG_P02_PLL_SERIAL_3_RW
,
909 E_MASKREG_P02_PLL_SERIAL_3_srl_ccir
,
913 #endif /* TMFL_TDA9989_PIXEL_CLOCK_ON_DDC */
920 /*Handle RxSense Interrupt */
921 if ((fInterruptStatus
& (1 << HDMITX_CALLBACK_INT_RX_SENSE
)) != 0) {
922 /* Callback disable on first tmbslTDA9989HwHandleInterrupt call */
923 if (gMiscInterruptHpdRxEnable
) {
926 fInterruptStatus
&= (1 << HDMITX_CALLBACK_INT_HPD
) |
927 (1 << HDMITX_CALLBACK_INT_RX_SENSE
) | (1 << HDMITX_CALLBACK_INT_SW_INT
);
929 if (pDis
->rxSenseStatus
== HDMITX_RX_SENSE_ACTIVE
) {
930 setState(pDis
, EV_SINKON
);
932 setState(pDis
, EV_SINKOFF
);
936 /* Clear RX_sense IT if level has not changed */
937 fInterruptStatus
&= ~(1 << HDMITX_CALLBACK_INT_RX_SENSE
);
940 /* Ignore other simultaneous HDCP interrupts if T0 interrupt,
941 * preserving any hpd interrupt */
943 if (fInterruptStatus
& (1 << HDMITX_CALLBACK_INT_T0
)) {
944 if (pDis
->EdidReadStarted
) {
946 #ifdef TMFL_HDCP_SUPPORT
947 err
= getHwRegister(pDis
, E_REG_P12_TX0_RW
, ®Val
);
948 RETIF(err
!= TM_OK
, err
)
950 /* EDID read failure */
951 if ((regVal
& E_MASKREG_P12_TX0_sr_hdcp
) != 0) {
953 #endif /* TMFL_HDCP_SUPPORT */
956 /* Reset EDID status */
957 err
= ClearEdidRequest(txUnit
);
958 RETIF(err
!= TM_OK
, err
)
960 /* enable EDID callback */
962 (UInt16
) (fInterruptStatus
& (~(1 << HDMITX_CALLBACK_INT_T0
)));
964 fInterruptStatus
| (1 << HDMITX_CALLBACK_INT_EDID_BLK_READ
);
966 #ifdef TMFL_HDCP_SUPPORT
968 #endif /* TMFL_HDCP_SUPPORT */
971 fInterruptStatus
&= ((1 << HDMITX_CALLBACK_INT_HPD
)
972 | (1 << HDMITX_CALLBACK_INT_T0
)
973 | (1 << HDMITX_CALLBACK_INT_RX_SENSE
)
974 | (1 << HDMITX_CALLBACK_INT_SW_INT
)
981 /* For each interrupt flag that is set, check the corresponding registered
982 * callback function pointer in the Device Instance Structure
983 * funcIntCallbacks array.
986 for (i
= 0; i
< HDMITX_CALLBACK_INT_NUM
; i
++) {
987 if (i
!= HDMITX_CALLBACK_INT_PLL_LOCK
) { /* PLL LOCK not present on TDA9989 */
990 fInterruptMask
= fInterruptMask
<< ((UInt16
) kITCallbackPriority
[i
]);
992 if (fInterruptStatus
& fInterruptMask
) {
993 /* IF a registered callback pointer is non-null THEN call it. */
994 if (pDis
->funcIntCallbacks
[kITCallbackPriority
[i
]] !=
995 (ptmbslHdmiTxCallback_t
) 0) {
996 pDis
->funcIntCallbacks
[kITCallbackPriority
[i
]] (txUnit
);
1005 /*============================================================================*/
1006 /* tmbslTDA9989FlagSwInt */
1007 /* Use only for debug to flag the software debug interrupt */
1008 /*============================================================================*/
1009 tmErrorCode_t
tmbslTDA9989FlagSwInt(tmUnitSelect_t txUnit
, UInt32 uSwInt
) {
1010 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1011 tmErrorCode_t err
; /* Error code */
1013 DUMMY_ACCESS(uSwInt
);
1015 /* Check unit parameter and point to its object */
1016 err
= checkUnitSetDis(txUnit
, &pDis
);
1017 RETIF(err
!= TM_OK
, err
)
1019 err
= setHwRegister(pDis
, E_REG_P00_SW_INT_W
, E_MASKREG_P00_SW_INT_sw_int
);
1025 /*============================================================================*/
1026 /* tmbslTDA9989HwSetRegisters */
1027 /*============================================================================*/
1030 tmbslTDA9989HwSetRegisters
1031 (tmUnitSelect_t txUnit
, Int regPage
, Int regAddr
, UInt8
*pRegBuf
, Int nRegs
) {
1032 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1033 tmErrorCode_t err
; /* Error code */
1034 Int i
; /* Loop index */
1035 UInt8 newRegPage
; /* The register's new page number */
1036 UInt8 regShad
; /* Index to the register's shadow copy */
1037 UInt16 regShadPageAddr
; /* Packed shadowindex/page/address */
1038 tmbslHdmiTxSysArgs_t sysArgs
; /* Arguments passed to system function */
1040 /* Check unit parameter and point to its object */
1041 err
= checkUnitSetDis(txUnit
, &pDis
);
1042 RETIF(err
!= TM_OK
, err
)
1044 /* Check remaining parameters */
1045 RETIF_BADPARAM((regPage
< kPageIndexToPage
[E_PAGE_00
])
1046 || ((regPage
> kPageIndexToPage
[E_PAGE_02
])
1047 && (regPage
< kPageIndexToPage
[E_PAGE_11
]))
1048 || (regPage
> kPageIndexToPage
[E_PAGE_12
]))
1049 RETIF_BADPARAM((regAddr
< E_REG_MIN_ADR
) || (regAddr
>= E_REG_CURPAGE_ADR_W
))
1050 RETIF_BADPARAM(pRegBuf
== (pUInt8
) 0)
1051 RETIF_BADPARAM((nRegs
< 0) || ((nRegs
+ regAddr
) > E_REG_CURPAGE_ADR_W
))
1053 /* Set page register if required */
1054 newRegPage
= (UInt8
) regPage
;
1055 if (pDis
->curRegPage
!= newRegPage
) {
1056 /* All non-OK results are errors */
1057 sysArgs
.slaveAddr
= pDis
->uHwAddress
;
1058 sysArgs
.firstRegister
= E_REG_CURPAGE_ADR_W
;
1059 sysArgs
.lenData
= 1;
1060 sysArgs
.pData
= &newRegPage
;
1061 err
= pDis
->sysFuncWrite(&sysArgs
);
1062 RETIF(err
!= TM_OK
, TMBSL_ERR_HDMI_I2C_WRITE
)
1063 pDis
->curRegPage
= newRegPage
;
1066 /* Write each register in the range. nRegs = 0 is ok, to allow only
1067 * the page register to be written if required (above)
1069 for (; nRegs
> 0; pRegBuf
++, regAddr
++, nRegs
--) {
1070 /* Find shadow register index.
1071 * This loop is not very efficient, but it is assumed that this API
1072 * will not be used often. The alternative is to use a huge sparse
1073 * array indexed by page and address and containing the shadow index.
1075 for (i
= 0; i
< E_SNUM
; i
++) {
1076 /* Check lookup table for match with page and address */
1077 regShadPageAddr
= kShadowReg
[i
];
1078 if ((SPA2PAGE(regShadPageAddr
) == newRegPage
)
1079 && (SPA2ADDR(regShadPageAddr
) == regAddr
)) {
1080 /* Found index - write the shadow register */
1081 regShad
= SPA2SHAD(regShadPageAddr
);
1082 pDis
->shadowReg
[regShad
] = *pRegBuf
;
1086 /* Write the device register - all non-OK results are errors */
1087 sysArgs
.slaveAddr
= pDis
->uHwAddress
;
1088 sysArgs
.firstRegister
= (UInt8
) regAddr
;
1089 sysArgs
.lenData
= 1;
1090 sysArgs
.pData
= pRegBuf
;
1091 err
= pDis
->sysFuncWrite(&sysArgs
);
1092 RETIF(err
!= TM_OK
, TMBSL_ERR_HDMI_I2C_WRITE
)
1099 /*============================================================================*/
1100 /* tmbslTDA9989HwStartup */
1101 /*============================================================================*/
1103 tmbslTDA9989HwStartup(void
1105 pr_debug("%s\n", __func__
);
1106 /* Reset device instance data for when compiler doesn't do it */
1107 lmemset(&gHdmiTxInstance
, 0, sizeof(gHdmiTxInstance
));
1110 /*============================================================================*/
1111 /* tmbslTDA9989Init */
1112 /* RETIF_REG_FAIL NOT USED HERE AS ALL ERRORS SHOULD BE TRAPPED IN ALL BUILDS */
1113 /*============================================================================*/
1116 (tmUnitSelect_t txUnit
,
1118 ptmbslHdmiTxSysFunc_t sysFuncWrite
,
1119 ptmbslHdmiTxSysFunc_t sysFuncRead
,
1120 ptmbslHdmiTxSysFuncEdid_t sysFuncEdidRead
,
1121 ptmbslHdmiTxSysFuncTimer_t sysFuncTimer
,
1122 tmbslHdmiTxCallbackList_t
*funcIntCallbacks
,
1123 Bool bEdidAltAddr
, tmbslHdmiTxVidFmt_t vinFmt
, tmbslHdmiTxPixRate_t pixRate
) {
1124 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1125 tmErrorCode_t err
; /* Error code */
1126 Int i
; /* Loop index */
1127 Bool bFound
; /* T=found, F=not found */
1128 UInt8 EnableIntMask
= 0; /* Mask used to enable HPD and RX Sense interrupt */
1129 UInt8 EnableModeMask
; /* Mask used to Set HDMI and RxSense modes */
1130 UInt16 val16Bits
; /* Value on 16 bit */
1131 UInt8 regVal
; /* Register value */
1133 pr_debug("%s\n", __func__
);
1134 /* Check unit parameter and point to its object */
1135 RETIF(txUnit
< tmUnit0
, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER
)
1136 RETIF(txUnit
>= HDMITX_UNITS_MAX
, TMBSL_ERR_HDMI_BAD_UNIT_NUMBER
)
1137 pDis
= &gHdmiTxInstance
[txUnit
];
1139 /* IF the bInitialized flag is set THEN return (only Init does this) */
1140 RETIF(pDis
->bInitialized
, TMBSL_ERR_HDMI_INIT_FAILED
)
1142 /* Check remaining parameters */
1143 RETIF_BADPARAM(uHwAddress
< HDMITX_SLAVE_ADDRESS_MIN
)
1144 RETIF_BADPARAM(uHwAddress
> HDMITX_SLAVE_ADDRESS_MAX
)
1145 RETIF_BADPARAM(sysFuncWrite
== (ptmbslHdmiTxSysFunc_t
) 0)
1146 RETIF_BADPARAM(sysFuncRead
== (ptmbslHdmiTxSysFunc_t
) 0)
1147 /*RETIF_BADPARAM(sysFuncEdidRead == (ptmbslHdmiTxSysFuncEdid_t)0) *//*Previously on TDA9983 */
1148 /*RETIF_BADPARAM(sysFuncTimer == (ptmbslHdmiTxSysFuncTimer_t)0) */
1149 RETIF_BADPARAM((bEdidAltAddr
!= True
) && (bEdidAltAddr
!= False
))
1150 RETIF_BADPARAM(!IS_VALID_FMT(vinFmt
))
1151 RETIF_BADPARAM(pixRate
>= HDMITX_PIXRATE_INVALID
)
1153 /* Set all Device Instance Structure members to default values */
1154 lmemcpy(pDis
, &kHdmiTxInstanceDefault
, sizeof(*pDis
));
1156 /* Copy txUnit, uHwAddress, sysFuncWrite and sysFuncRead values to
1157 * the defaulted Device Instance Structure BEFORE FIRST DEVICE ACCESS.
1159 pDis
->txUnit
= txUnit
;
1161 /* Unit test build can't support 127 device sets of dummy registers, so use
1162 * smaller range instead, indexed by unit number not I2C address */
1163 pDis
->uHwAddress
= (UInt8
) txUnit
;
1165 /* Store actual I2C address */
1166 pDis
->uHwAddress
= uHwAddress
;
1168 pDis
->sysFuncWrite
= sysFuncWrite
;
1169 pDis
->sysFuncRead
= sysFuncRead
;
1170 pDis
->sysFuncEdidRead
= sysFuncEdidRead
;
1171 pDis
->sysFuncTimer
= sysFuncTimer
;
1173 /* IF the funcIntCallbacks array pointer is defined
1174 * THEN for each funcIntCallbacks pointer that is not null:
1175 * - Copy the pointer to the Device Instance Structure
1176 * funcIntCallbacks array.
1179 for (i
= 0; i
< HDMITX_CALLBACK_INT_NUM
; i
++) {
1180 if ((funcIntCallbacks
!= (tmbslHdmiTxCallbackList_t
*) 0)
1181 && (funcIntCallbacks
->funcCallback
[i
] != (ptmbslHdmiTxCallback_t
) 0)) {
1182 pDis
->funcIntCallbacks
[i
] = funcIntCallbacks
->funcCallback
[i
];
1184 pDis
->funcIntCallbacks
[i
] = (ptmbslHdmiTxCallback_t
) 0;
1188 /* Set the EDID alternate address flag if needed */
1189 pDis
->bEdidAlternateAddr
= bEdidAltAddr
;
1191 /* *****************************************************************************************// */
1192 /* *****************************************************************************************// */
1193 /* **********************Enable HDMI and RxSense************************/// */
1196 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, 0x40);
1203 /*Read data out of ENAMODS CEC Register */
1204 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &EnableModeMask
);
1206 /*Enable required modes */
1207 EnableModeMask
|= E_MASKREG_CEC_ENAMODS_ena_hdmi
; /*Enable HDMI Mode */
1208 EnableModeMask
|= E_MASKREG_CEC_ENAMODS_ena_rxs
; /*Enable RxSense Mode */
1209 EnableModeMask
&= ~E_MASKREG_CEC_ENAMODS_dis_fro
; /* Enable FRO */
1211 /*Write data in ENAMODS CEC Register */
1212 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, EnableModeMask
);
1214 pDis
->ePowerState
= (tmbslHdmiTxPowerState_t
) tmPowerOn
;
1216 /* Set the bInitialized flag to enable other APIs */
1217 pDis
->bInitialized
= True
;
1219 /* Reset the device */
1220 err
= tmbslTDA9989Reset(txUnit
);
1221 RETIF(err
!= TM_OK
, err
)
1222 /* ***************************************************************************************// */
1223 /* ****************Get Device Version and Capabilities************************************// */
1224 /* Read the device version register to uDeviceVersion in the
1225 * Device Instance Structure
1227 err
= getHwRegister(pDis
, E_REG_P00_VERSION_R
, ®Val
);
1228 RETIF(err
!= TM_OK
, err
)
1230 /* Copy N4 features bits to DIS */
1231 pDis
->uDeviceFeatures
= regVal
&
1232 (E_MASKREG_P00_VERSION_not_h
| E_MASKREG_P00_VERSION_not_s
);
1234 pDis
->uDeviceVersion
= regVal
;
1236 /* Get MSB version Value */
1237 err
= getHwRegister(pDis
, E_REG_P00_VERSION_MSB_RW
, ®Val
);
1238 RETIF(err
!= TM_OK
, err
)
1240 /* Build Device Version Info */
1242 pDis
->uDeviceVersion
= pDis
->uDeviceVersion
| (val16Bits
<< 8);
1243 val16Bits
= pDis
->uDeviceFeatures
;
1244 pDis
->uDeviceVersion
&= ~val16Bits
;
1246 if (pDis
->uDeviceVersion
!= E_DEV_VERSION_LIST_END
) {
1247 /* Search for the device version in the Supported Version
1248 * List in the Device Instance Structure.
1250 for (i
= 0, bFound
= False
; i
< E_DEV_VERSION_LIST_NUM
; i
++) {
1251 if (pDis
->uDeviceVersion
== pDis
->uSupportedVersions
[i
]) {
1255 if (bFound
== False
) {
1256 /* IF the device version is not found in the Supported Version List THEN
1257 * this driver component is not compatible with the device.*/
1258 err
= tmbslTDA9989Deinit(txUnit
);
1259 RETIF(err
!= TM_OK
, err
)
1260 return TMBSL_ERR_HDMI_COMPATIBILITY
;
1263 /* Quit if version reads zero */
1264 err
= tmbslTDA9989Deinit(txUnit
);
1265 RETIF(err
!= TM_OK
, err
)
1266 return TMBSL_ERR_HDMI_COMPATIBILITY
;
1269 /***************************************************************************************/
1270 /************Set the BIAS_tmds Value (general control for Analogu module)***************/
1271 regVal
= HDMI_TX_VSWING_VALUE
;
1273 err
= setHwRegister(pDis
, E_REG_P02_ANA_GENERAL_RW
, regVal
);
1274 RETIF(err
!= TM_OK
, err
)
1276 /*****************************************************************************************/
1277 /*****************************************************************************************/
1278 /* Set the PLL before resetting the device */
1279 /* PLL registers common configuration */
1280 err
= setHwRegisterFieldTable(pDis
, &kCommonPllCfg
[0]);
1283 /*Reset 656_Alt bit in VIP_CONTROL_4 Register */
1285 setHwRegisterField(pDis
, E_REG_P00_VIP_CNTRL_4_W
, E_MASKREG_P00_VIP_CNTRL_4_656_alt
, 0);
1288 /* 480i or 576i video input format */
1289 case HDMITX_VFMT_06_720x480i_60Hz
:
1290 case HDMITX_VFMT_07_720x480i_60Hz
:
1291 case HDMITX_VFMT_21_720x576i_50Hz
:
1292 case HDMITX_VFMT_22_720x576i_50Hz
:
1293 err
= setHwRegisterFieldTable(pDis
, &kVfmt480i576iPllCfg
[0]);
1297 case HDMITX_PIXRATE_SINGLE
:
1298 /* Single edge mode, vinFmt 480i or 576i */
1299 err
= setHwRegisterFieldTable(pDis
, &kSinglePrateVfmt480i576iPllCfg
[0]);
1303 case HDMITX_PIXRATE_SINGLE_REPEATED
:
1304 /* Single repeated edge mode, vinFmt 480i or 576i */
1305 err
= setHwRegisterFieldTable(pDis
, &kSrepeatedPrateVfmt480i576iPllCfg
[0]);
1310 /* Double edge mode doesn't exist for vinFmt 480i or 576i */
1311 return (TMBSL_ERR_HDMI_INCONSISTENT_PARAMS
);
1317 /* Others video input format */
1319 err
= setHwRegisterFieldTable(pDis
, &kVfmtOtherPllCfg
[0]);
1323 case HDMITX_PIXRATE_SINGLE
:
1324 /* Single edge mode, vinFmt other than 480i or 576i */
1325 err
= setHwRegisterFieldTable(pDis
, &kSinglePrateVfmtOtherPllCfg
[0]);
1328 case HDMITX_PIXRATE_DOUBLE
:
1329 /* Double edge mode, vinFmt other than 480i or 576i */
1330 err
= setHwRegisterFieldTable(pDis
, &kDoublePrateVfmtOtherPllCfg
[0]);
1334 /* Single repeated edge mode doesn't exist for other vinFmt */
1335 return (TMBSL_ERR_HDMI_INCONSISTENT_PARAMS
);
1341 /* DDC interface is disable for TDA9989 after reset, enable it */
1342 err
= setHwRegister(pDis
, E_REG_P00_DDC_DISABLE_RW
, 0x00);
1343 RETIF(err
!= TM_OK
, err
)
1345 /* Set clock speed of the DDC channel */
1346 err
= setHwRegister(pDis
, E_REG_P12_TX3_RW
, TDA19989_DDC_SPEED_FACTOR
);
1347 RETIF(err
!= TM_OK
, err
)
1349 /* TDA19989 N1 only */
1350 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
1352 err
= setHwRegisterField(pDis
, E_REG_P00_I2C_MASTER_RW
, E_MASKREG_P00_I2C_MASTER_dis_mm
, 0); /* 0: enable multi master mode */
1357 /* TDA19989 N1 only */
1359 setCECHwRegister(pDis
, E_REG_CEC_FRO_IM_CLK_CTRL_RW
,
1360 E_MASKREG_CEC_FRO_IM_CLK_CTRL_ghost_dis
|
1361 E_MASKREG_CEC_FRO_IM_CLK_CTRL_imclk_sel
);
1364 /* The DIS hotplug status is HDMITX_HOTPLUG_INVALID, so call the main
1365 * interrupt handler to read the current Hot Plug status and run any
1366 * registered HPD callback before interrupts are enabled below */
1367 /* err = tmbslTDA9989HwHandleInterrupt(txUnit); */
1368 RETIF(err
!= TM_OK
, err
)
1370 /* enable sw _interrupt and VS_interrupt for debug */
1371 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_1_RW
, E_MASKREG_P00_INT_FLAGS_1_sw_int
);
1373 /* enable edid read */
1374 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_2_RW
, E_MASKREG_P00_INT_FLAGS_2_edid_blk_rd
);
1377 /* Read HPD RXS level */
1378 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, ®Val
);
1379 RETIF(err
!= TM_OK
, err
)
1381 /* Read Hot Plug input status to know the actual level that caused the interrupt */
1382 pDis
->hotPlugStatus
= (regVal
& E_MASKREG_CEC_RXSHPDLEV_hpd_level
) ?
1383 HDMITX_HOTPLUG_ACTIVE
: HDMITX_HOTPLUG_INACTIVE
;
1385 /*Read RXS_FIL status to know the actual level that caused the interrupt */
1386 pDis
->rxSenseStatus
= (regVal
& E_MASKREG_CEC_RXSHPDLEV_rxs_level
) ?
1387 HDMITX_RX_SENSE_ACTIVE
: HDMITX_RX_SENSE_INACTIVE
;
1389 /*Disable required Interrupts */
1390 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &EnableIntMask
);
1391 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
; /* Enable RxSense Interrupt */
1392 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
; /* Enable HPD Interrupt */
1394 /* Switch BSL State machine into UNINITIALIZED State */
1395 setState(pDis
, EV_INIT
);
1397 /*Write data in RXSHPD Register */
1398 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, EnableIntMask
);
1399 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
1401 /* Enable HPD and RX sense IT after first call done by init function */
1402 gMiscInterruptHpdRxEnable
= True
;
1407 /*============================================================================*/
1408 /* tmbslTDA9989PowerGetState */
1409 /*============================================================================*/
1411 tmErrorCode_t
tmbslTDA9989PowerGetState(tmUnitSelect_t txUnit
, tmPowerState_t
*pePowerState
) {
1412 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1413 tmErrorCode_t err
; /* Error code */
1415 /* Check unit parameter and point to its object */
1416 err
= checkUnitSetDis(txUnit
, &pDis
);
1417 RETIF(err
!= TM_OK
, err
)
1419 /* Check remaining parameters */
1420 RETIF_BADPARAM(pePowerState
== (tmPowerState_t
) 0)
1422 /*return parameter */
1423 * pePowerState
= (tmPowerState_t
) pDis
->ePowerState
;
1429 /*============================================================================*/
1430 /* tmbslTDA9989PowerSetState */
1431 /*============================================================================*/
1432 tmErrorCode_t
tmbslTDA9989PowerSetState(tmUnitSelect_t txUnit
, tmPowerState_t ePowerState
) {
1433 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1434 tmErrorCode_t err
; /* Error code */
1435 UInt8 RegVal
= 0; /* Local Variable */
1437 /* Check unit parameter and point to its object */
1438 err
= checkUnitSetDis(txUnit
, &pDis
);
1439 RETIF(err
!= TM_OK
, err
)
1441 if (ePowerState
== tmPowerOff
) {
1442 ePowerState
= tmPowerStandby
;
1446 /* Check remaining parameters */
1447 RETIF_BADPARAM((ePowerState
!= tmPowerStandby
)
1448 && (ePowerState
!= tmPowerSuspend
)
1449 && (ePowerState
!= tmPowerOn
)
1452 if ((ePowerState
== tmPowerStandby
) && (pDis
->ePowerState
!= tmPowerStandby
)) {
1453 /*Disable HPD and RxSense Interrupts */
1454 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &RegVal
);
1455 RegVal
&= ~E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
;
1456 RegVal
&= ~E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
;
1457 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, RegVal
);
1458 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
1461 /* Disable if coming from ACTIVE */
1462 if (pDis
->ePowerState
== tmPowerOn
) {
1464 /* Disable audio and video ports */
1465 err
= setHwRegister(pDis
, E_REG_P00_ENA_AP_RW
, 0x00); /* 0: disable */
1469 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_0_RW
, 0x00); /* 0: disable */
1472 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_1_RW
, 0x00); /* 0: disable */
1475 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_2_RW
, 0x00); /* 0: disable */
1479 err
= setHwRegisterField(pDis
, E_REG_P00_DDC_DISABLE_RW
, E_MASKREG_P00_DDC_DISABLE_ddc_dis
, 1); /* 1: disable */
1480 RETIF_REG_FAIL(err
);
1482 #ifdef TMFL_HDCP_OPTIMIZED_POWER
1483 /* power down clocks */
1484 tmbslTDA9989HdcpPowerDown(txUnit
, True
);
1485 err
= setHwRegisterField(pDis
, E_REG_FEAT_POWER_DOWN
,
1486 E_MASKREG_FEAT_POWER_DOWN_all
, 0x0F);
1490 /*Disable HDMI and RxSense Modes AND FRO if required */
1491 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1492 RegVal
&= ~E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Reset HDMI Mode */
1494 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1497 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1499 RegVal
|= E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Set HDMI Mode */
1500 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1503 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1504 RegVal
&= ~E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Reset HDMI Mode */
1506 RegVal
&= ~E_MASKREG_CEC_ENAMODS_ena_rxs
; /* Reset RxSense Mode */
1510 RegVal
|= E_MASKREG_CEC_ENAMODS_dis_fro
;
1511 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1515 /*Send STANDBY event to the BSL State Machine */
1516 setState(pDis
, EV_STANDBY
);
1517 } else if ((ePowerState
== tmPowerSuspend
) && (pDis
->ePowerState
!= tmPowerSuspend
)) {
1519 /* Disable if coming from ACTIVE */
1520 if (pDis
->ePowerState
== tmPowerOn
) {
1521 /* Disable audio and video ports */
1522 err
= setHwRegister(pDis
, E_REG_P00_ENA_AP_RW
, 0x00); /* 0: disable */
1526 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_0_RW
, 0x00); /* 0: disable */
1529 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_1_RW
, 0x00); /* 0: disable */
1532 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_2_RW
, 0x00); /* 0: disable */
1533 RETIF_REG_FAIL(err
);
1536 err
= setHwRegisterField(pDis
, E_REG_P00_DDC_DISABLE_RW
, E_MASKREG_P00_DDC_DISABLE_ddc_dis
, 1); /* 1: disable */
1537 RETIF_REG_FAIL(err
);
1539 #ifdef TMFL_HDCP_OPTIMIZED_POWER
1540 /* power down clocks */
1541 tmbslTDA9989HdcpPowerDown(txUnit
, True
);
1542 err
= setHwRegisterField(pDis
, E_REG_FEAT_POWER_DOWN
,
1543 E_MASKREG_FEAT_POWER_DOWN_all
, 0x0F);
1547 /*Enable RxSense Mode and Disable HDMI Mode */
1548 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1549 RegVal
&= ~E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Reset HDMI Mode */
1550 RegVal
|= E_MASKREG_CEC_ENAMODS_ena_rxs
; /* Set RxSense Mode */
1551 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1554 /*Enable HPD and RxS Interupt in case of the current Device Power States is STANDBY */
1555 /*In other cases, those interrupts have already been enabled */
1556 if (pDis
->ePowerState
== tmPowerStandby
) {
1557 /* Enable FRO if coming from STANDBY */
1558 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1559 RegVal
&= ~E_MASKREG_CEC_ENAMODS_dis_fro
; /* Enable FRO */
1560 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1563 /*Enable HPD and RxS Interupt */
1564 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &RegVal
);
1565 RegVal
|= E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
; /* Enable HPD Interrupt */
1566 RegVal
|= E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
; /* Enable RxSense Interrupt */
1567 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, RegVal
);
1568 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
1571 /* force interrupt HPD and RXS level reading */
1572 err
= tmbslTDA9989HwHandleInterrupt(txUnit
);
1573 RETIF(err
!= TM_OK
, err
)
1578 /*Send the SLEEP event to the BSL State Machine */
1579 setState(pDis
, EV_SLEEP
);
1583 else if ((ePowerState
== tmPowerOn
) && (pDis
->ePowerState
!= tmPowerOn
)) {
1585 /* Enable RxSense HDMI Modes */
1586 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1587 RegVal
|= E_MASKREG_CEC_ENAMODS_ena_hdmi
; /* Set HDMI Mode */
1588 RegVal
|= E_MASKREG_CEC_ENAMODS_ena_rxs
; /* Set RxSense Mode */
1589 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1592 /*Enable HPD and RxS Interupt in case of the current Device Power States is STANDBY */
1593 /*In other cases, those interrupts have already been enabled */
1594 if (pDis
->ePowerState
== tmPowerStandby
) {
1595 /* Enable FRO if coming from STANDBY */
1596 err
= getCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, &RegVal
);
1597 RegVal
&= ~E_MASKREG_CEC_ENAMODS_dis_fro
; /* Enable FRO */
1598 err
= setCECHwRegister(pDis
, E_REG_CEC_ENAMODS_RW
, RegVal
);
1602 /*Apply the required mode, Reset RxS and HDMI bits */
1603 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &RegVal
);
1604 RegVal
|= E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
; /* Enable HPD Interrupt */
1605 RegVal
|= E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
; /* Enable RxSense Interrupt */
1606 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, RegVal
);
1607 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
1612 /* Restore BIAS TMDS */
1613 RegVal
= HDMI_TX_VSWING_VALUE
;
1614 err
= setHwRegister(pDis
, E_REG_P02_ANA_GENERAL_RW
, RegVal
);
1615 RETIF(err
!= TM_OK
, err
)
1618 err
= tmbslTDA9989Reset(txUnit
);
1619 RETIF(err
!= TM_OK
, err
)
1623 setHwRegisterField(pDis
, E_REG_P00_VIP_CNTRL_4_W
,
1624 E_MASKREG_P00_VIP_CNTRL_4_656_alt
, 0);
1626 err
= setHwRegister(pDis
, E_REG_P12_TX3_RW
, TDA19989_DDC_SPEED_FACTOR
);
1627 RETIF(err
!= TM_OK
, err
)
1629 /* TDA19989 N1 only */
1630 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
1632 err
= setHwRegisterField(pDis
,
1633 E_REG_P00_I2C_MASTER_RW
,
1634 E_MASKREG_P00_I2C_MASTER_dis_mm
, 0);
1638 /* TDA19989 N1 only */
1640 setCECHwRegister(pDis
, E_REG_CEC_FRO_IM_CLK_CTRL_RW
,
1641 E_MASKREG_CEC_FRO_IM_CLK_CTRL_ghost_dis
|
1642 E_MASKREG_CEC_FRO_IM_CLK_CTRL_imclk_sel
);
1644 #ifdef TMFL_HDCP_SUPPORT
1645 if (pDis
->HdcpSeed
) {
1647 tmbslTDA9989HdcpDownloadKeys(txUnit
, pDis
->HdcpSeed
,
1648 HDMITX_HDCP_DECRYPT_ENABLE
);
1650 #endif /* TMFL_HDCP_SUPPORT */
1654 err
= setHwRegisterField(pDis
, E_REG_P00_DDC_DISABLE_RW
, E_MASKREG_P00_DDC_DISABLE_ddc_dis
, 0); /* 0: enable */
1657 /* Enable audio and video ports */
1658 err
= setHwRegister(pDis
, E_REG_P00_ENA_AP_RW
, 0xFF); /* 1: enable */
1662 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_0_RW
, 0xFF); /* 1: enable */
1665 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_1_RW
, 0xFF); /* 1: enable */
1668 err
= setHwRegister(pDis
, E_REG_P00_ENA_VP_2_RW
, 0xFF); /* 1: enable */
1672 /*Send the Hot Plug detection status event to the BSL State Machine */
1673 if (pDis
->hotPlugStatus
== HDMITX_HOTPLUG_ACTIVE
) {
1674 setState(pDis
, EV_PLUGGEDIN
);
1676 setState(pDis
, EV_UNPLUGGED
);
1681 /* Set the current Device Power status to the required Power Status */
1682 pDis
->ePowerState
= (tmbslHdmiTxPowerState_t
) ePowerState
;
1688 /*============================================================================*/
1689 /* tmbslTDA9989Reset */
1690 /*============================================================================*/
1691 tmErrorCode_t
tmbslTDA9989Reset(tmUnitSelect_t txUnit
) {
1692 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1693 tmErrorCode_t err
; /* Error code */
1695 /* Check unit parameter and point to its object */
1696 err
= checkUnitSetDis(txUnit
, &pDis
);
1697 RETIF(err
!= TM_OK
, err
)
1699 /* Reset I2C master and Audio */
1700 (void)setHwRegisterField(pDis
, E_REG_P00_SR_REG_W
,
1701 E_MASKREG_P00_SR_REG_sr_i2c_ms
|
1702 E_MASKREG_P00_SR_REG_sr_audio
, 1);
1704 pDis
->sysFuncTimer(50); /* ms */
1706 (void)setHwRegisterField(pDis
, E_REG_P00_SR_REG_W
,
1707 E_MASKREG_P00_SR_REG_sr_i2c_ms
| E_MASKREG_P00_SR_REG_sr_audio
, 0);
1709 pDis
->sysFuncTimer(50); /* ms */
1711 /* Write to the transmitter to do a soft reset. Don't abort after any
1712 * error here, to ensure full reset.
1714 (void)setHwRegisterField(pDis
, E_REG_P00_MAIN_CNTRL0_RW
, E_MASKREG_P00_MAIN_CNTRL0_sr
, 1);
1715 /* pDis->sysFuncTimer(50); *//* ms */
1716 (void)setHwRegisterField(pDis
, E_REG_P00_MAIN_CNTRL0_RW
, E_MASKREG_P00_MAIN_CNTRL0_sr
, 0);
1717 /* pDis->sysFuncTimer(50); *//* ms */
1718 /* Clear any colourbars */
1719 (void)setHwRegisterField(pDis
, E_REG_P00_HVF_CNTRL_0_W
, E_MASKREG_P00_HVF_CNTRL_0_sm
, 0);
1721 #ifdef TMFL_HDCP_SUPPORT
1722 /* Disable any scheduled function and HDCP check timer */
1723 pDis
->HdcpFuncRemainingMs
= 0;
1724 pDis
->HdcpCheckNum
= 0;
1725 #endif /* TMFL_HDCP_SUPPORT */
1727 /* Switch BSL State machine into UNINITIALIZED State */
1728 setState(pDis
, EV_DEINIT
);
1729 /* Switch Power State into STAND_BY State */
1730 /* pDis->ePowerState = tmPowerStandby; */
1734 /*============================================================================*/
1735 /* tmbslTDA9989SwGetVersion */
1736 /*============================================================================*/
1737 tmErrorCode_t
tmbslTDA9989SwGetVersion(ptmSWVersion_t pSWVersion
) {
1738 /* Check parameters */
1739 RETIF_BADPARAM(pSWVersion
== (ptmSWVersion_t
) 0)
1741 /* Get the version details of the component. */
1742 pSWVersion
->compatibilityNr
= HDMITX_BSL_COMP_NUM
;
1743 pSWVersion
->majorVersionNr
= HDMITX_BSL_MAJOR_VER
;
1744 pSWVersion
->minorVersionNr
= HDMITX_BSL_MINOR_VER
;
1749 /*============================================================================*/
1750 /* tmbslTDA9989SysTimerWait */
1751 /*============================================================================*/
1752 tmErrorCode_t
tmbslTDA9989SysTimerWait(tmUnitSelect_t txUnit
, UInt16 waitMs
) {
1753 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1754 tmErrorCode_t err
; /* Error code */
1756 /* Check unit parameter and point to TX unit object */
1757 err
= checkUnitSetDis(txUnit
, &pDis
);
1758 RETIF(err
!= TM_OK
, err
)
1760 /* Return if this device timer is not set up */
1761 RETIF(!pDis
->sysFuncTimer
, TMBSL_ERR_HDMI_NOT_INITIALIZED
)
1763 /* Wait for the requested time */
1764 pDis
->sysFuncTimer(waitMs
);
1769 /*============================================================================*/
1770 /* tmbslTDA9989TestSetMode */
1771 /*============================================================================*/
1774 tmbslTDA9989TestSetMode
1775 (tmUnitSelect_t txUnit
, tmbslHdmiTxTestMode_t testMode
, tmbslHdmiTxTestState_t testState
) {
1776 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1777 tmErrorCode_t err
; /* Error code */
1778 /* Register used to activate a test */
1779 UInt16 testReg
= E_REG_P00_VIP_CNTRL_4_W
;
1780 /* Register bitfield mask used */
1781 UInt8 testMask
= E_MASKREG_P00_VIP_CNTRL_4_tst_pat
;
1783 /* Check unit parameter and point to TX unit object */
1784 err
= checkUnitSetDis(txUnit
, &pDis
);
1785 RETIF(err
!= TM_OK
, err
)
1787 /* Check parameters */
1788 RETIF_BADPARAM(testMode
>= HDMITX_TESTMODE_INVALID
)
1789 RETIF_BADPARAM(testState
>= HDMITX_TESTSTATE_INVALID
)
1791 /* Set the mode selected by testMode to the state indicated by testState */
1793 case HDMITX_TESTMODE_PAT
:
1794 testReg
= E_REG_P00_VIP_CNTRL_4_W
;
1795 testMask
= E_MASKREG_P00_VIP_CNTRL_4_tst_pat
;
1797 case HDMITX_TESTMODE_656
:
1798 testReg
= E_REG_P00_VIP_CNTRL_4_W
;
1799 testMask
= E_MASKREG_P00_VIP_CNTRL_4_tst_656
;
1801 case HDMITX_TESTMODE_SERPHOE
:
1802 /*testReg = E_REG_P02_TEST1_RW;
1803 testMask = E_MASKREG_P02_TEST1_tstserphoe; */
1805 case HDMITX_TESTMODE_NOSC
:
1806 testReg
= E_REG_P02_TEST1_RW
;
1807 testMask
= E_MASKREG_P02_TEST1_tst_nosc
;
1809 case HDMITX_TESTMODE_HVP
:
1810 /*testReg = E_REG_P02_TEST1_RW;
1811 testMask = E_MASKREG_P02_TEST1_tst_hvp; */
1813 case HDMITX_TESTMODE_PWD
:
1814 /*testReg = E_REG_P02_TEST2_RW;
1815 testMask = E_MASKREG_P02_TEST2_pwd1v8; */
1817 case HDMITX_TESTMODE_DIVOE
:
1818 /*testReg = E_REG_P02_TEST2_RW;
1819 testMask = E_MASKREG_P02_TEST2_divtestoe; */
1821 case HDMITX_TESTMODE_INVALID
:
1824 err
= setHwRegisterField(pDis
, testReg
, testMask
, (UInt8
) testState
);
1828 /*============================================================================*/
1830 \brief Fill Gamut metadata packet into one of the gamut HW buffer. this
1831 function is not sending any gamut metadata into the HDMI stream,
1832 it is only loading data into the HW.
1834 \param txUnit Transmitter unit number
1835 \param pPkt pointer to the gamut packet structure
1836 \param bufSel number of the gamut buffer to fill
1838 \return The call result:
1839 - TM_OK: the call was successful
1840 - TMBSL_ERR_BSLHDMIRX_BAD_UNIT_NUMBER: the unit number is wrong or
1841 the receiver instance is not initialised
1842 - TMBSL_ERR_BSLHDMIRX_BAD_PARAMETER: a parameter is invalid or out
1844 - TMBSL_ERR_BSLHDMIRX_I2C_WRITE: failed when writing to the I2C
1847 ******************************************************************************/
1848 tmErrorCode_t tmbslTDA9989PktFillGamut
1849 (tmUnitSelect_t txUnit
, tmbslHdmiTxPktGamut_t
*pPkt
, UInt8 bufSel
) {
1850 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1851 tmErrorCode_t err
; /* Error code */
1853 /* Check unit parameter and point to TX unit object */
1855 err
= checkUnitSetDis(txUnit
, &pDis
);
1856 RETIF(err
!= TM_OK
, err
)
1858 /* Check parameters */
1859 RETIF_BADPARAM((bufSel
!= 0) && (bufSel
!= 1))
1861 /* Fill Gamut registers */
1865 err
= setHwRegisters(pDis
, E_REG_P13_GMD_0_HB0_RW
, &pPkt
->HB
[0], 3);
1866 RETIF(err
!= TM_OK
, err
)
1868 err
= setHwRegisters(pDis
, E_REG_P13_GMD_0_PB0_RW
, &pPkt
->PB
[0], 28);
1869 RETIF(err
!= TM_OK
, err
)
1875 err
= setHwRegisters(pDis
, E_REG_P13_GMD_1_HB0_RW
, &pPkt
->HB
[0], 3);
1876 RETIF(err
!= TM_OK
, err
)
1878 err
= setHwRegisters(pDis
, E_REG_P13_GMD_1_PB0_RW
, &pPkt
->PB
[0], 28);
1879 RETIF(err
!= TM_OK
, err
)
1885 /*============================================================================*/
1887 \brief Enable transmission of gamut metadata packet. Calling this function
1888 tells HW which gamut buffer to send into the HDMI stream. HW will
1889 only take into account this command at the next VS, not during the
1892 \param txUnit Transmitter unit number
1893 \param bufSel Number of the gamut buffer to be sent
1894 \param enable Enable/disable gamut packet transmission
1896 \return The call result:
1897 - TM_OK: the call was successful
1898 - TMBSL_ERR_BSLHDMIRX_BAD_UNIT_NUMBER: the unit number is wrong or
1899 the receiver instance is not initialised
1900 - TMBSL_ERR_BSLHDMIRX_BAD_PARAMETER: a parameter is invalid or out
1902 - TMBSL_ERR_BSLHDMIRX_I2C_WRITE: failed when writing to the I2C
1905 ******************************************************************************/
1906 tmErrorCode_t
tmbslTDA9989PktSendGamut(tmUnitSelect_t txUnit
, UInt8 bufSel
, Bool bEnable
) {
1907 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1908 tmErrorCode_t err
; /* Error code */
1909 UInt8 GMD_Ctrl_Val
; /*GMD control Value */
1911 /* Check unit parameter and point to TX unit object */
1912 err
= checkUnitSetDis(txUnit
, &pDis
);
1913 RETIF(err
!= TM_OK
, err
)
1915 /* Check parameters */
1916 RETIF_BADPARAM((bufSel
!= 0) && (bufSel
!= 1))
1919 GMD_Ctrl_Val
= 0x00;
1921 /*Enable Send of Gamut MetaData */
1925 GMD_Ctrl_Val
|= E_MASKREG_P13_GMD_CONTROL_enable
;
1926 GMD_Ctrl_Val
&= ~E_MASKREG_P13_GMD_CONTROL_buf_sel
;
1927 err
= setHwRegister(pDis
, E_REG_P13_GMD_CONTROL_RW
, GMD_Ctrl_Val
);
1928 RETIF(err
!= TM_OK
, err
)
1932 GMD_Ctrl_Val
|= E_MASKREG_P13_GMD_CONTROL_enable
;
1933 GMD_Ctrl_Val
|= E_MASKREG_P13_GMD_CONTROL_buf_sel
;
1934 err
= setHwRegister(pDis
, E_REG_P13_GMD_CONTROL_RW
, GMD_Ctrl_Val
);
1935 RETIF(err
!= TM_OK
, err
)
1938 /*Disable Send of Gamut MetaData */
1940 GMD_Ctrl_Val
&= ~E_MASKREG_P13_GMD_CONTROL_enable
;
1941 GMD_Ctrl_Val
&= ~E_MASKREG_P13_GMD_CONTROL_buf_sel
;
1942 err
= setHwRegister(pDis
, E_REG_P13_GMD_CONTROL_RW
, GMD_Ctrl_Val
);
1943 RETIF(err
!= TM_OK
, err
)
1952 /*============================================================================*/
1953 /* tmbslTDA9989EnableCallback */
1954 /*============================================================================*/
1956 tmbslTDA9989EnableCallback
1957 (tmUnitSelect_t txUnit
, tmbslHdmiTxCallbackInt_t callbackSource
, Bool enable
) {
1958 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1959 tmErrorCode_t err
= TM_OK
; /* Error code */
1961 /* Check unit parameter and point to TX unit object */
1962 err
= checkUnitSetDis(txUnit
, &pDis
);
1963 RETIF(err
!= TM_OK
, err
)
1965 /* Check parameters */
1966 RETIF_BADPARAM(callbackSource
>= HDMITX_CALLBACK_INT_NUM
)
1968 switch (callbackSource
) {
1969 case HDMITX_CALLBACK_INT_VS_RPT
:
1970 /* Enable or disable VS Interrupt */
1971 err
= setHwRegisterField(pDis
,
1972 E_REG_P00_INT_FLAGS_1_RW
,
1973 E_MASKREG_P00_INT_FLAGS_1_vs_rpt
, (UInt8
) enable
);
1975 pDis
->InterruptsEnable
|= (1 << callbackSource
);
1977 pDis
->InterruptsEnable
&= ~(1 << callbackSource
);
1981 err
= TMBSL_ERR_HDMI_NOT_SUPPORTED
;
1988 /*============================================================================*/
1989 /* tmbslTDA9989SetColorDepth */
1990 /*============================================================================*/
1992 tmbslTDA9989SetColorDepth
1993 (tmUnitSelect_t txUnit
, tmbslHdmiTxColorDepth colorDepth
, Bool termEnable
) {
1994 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
1995 tmErrorCode_t err
= TM_OK
; /* Error code */
1997 DUMMY_ACCESS(termEnable
);
1999 /* Check unit parameter and point to TX unit object */
2000 err
= checkUnitSetDis(txUnit
, &pDis
);
2001 RETIF(err
!= TM_OK
, err
)
2003 /* Check parameters */
2004 RETIF_BADPARAM(colorDepth
>= HDMITX_COLORDEPTH_INVALID
)
2006 switch (colorDepth
) {
2007 case HDMITX_COLORDEPTH_NO_CHANGE
:
2010 case HDMITX_COLORDEPTH_24
:
2015 err
= TMBSL_ERR_HDMI_NOT_SUPPORTED
;
2024 /*============================================================================*/
2025 /* tmbslTDA9989Set5vpower */
2026 /*============================================================================*/
2027 tmErrorCode_t
tmbslTDA9989Set5vpower(tmUnitSelect_t txUnit
, Bool pwrEnable
) {
2028 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2029 tmErrorCode_t err
; /* Error code */
2031 DUMMY_ACCESS(pwrEnable
);
2033 /* Check unit parameter and point to TX unit object */
2034 err
= checkUnitSetDis(txUnit
, &pDis
);
2035 RETIF(err
!= TM_OK
, err
)
2038 return TMBSL_ERR_HDMI_NOT_SUPPORTED
;
2041 /*============================================================================*/
2042 /* tmbslTDA9989SetDefaultPhase */
2043 /*============================================================================*/
2045 tmbslTDA9989SetDefaultPhase
2046 (tmUnitSelect_t txUnit
, Bool bEnable
, tmbslHdmiTxColorDepth colorDepth
, UInt8 videoFormat
) {
2047 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2048 tmErrorCode_t err
; /* Error code */
2050 DUMMY_ACCESS(bEnable
);
2051 DUMMY_ACCESS(colorDepth
);
2052 DUMMY_ACCESS(videoFormat
);
2054 /* Check unit parameter and point to TX unit object */
2055 err
= checkUnitSetDis(txUnit
, &pDis
);
2056 RETIF(err
!= TM_OK
, err
)
2058 return TMBSL_ERR_HDMI_NOT_SUPPORTED
;
2063 /*============================================================================*/
2064 /* tmbslDebugWriteFakeRegPage */
2065 /*============================================================================*/
2066 tmErrorCode_t
tmbslDebugWriteFakeRegPage(tmUnitSelect_t txUnit
)
2068 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2069 tmErrorCode_t err
; /* Error code */
2071 err
= checkUnitSetDis(txUnit
, &pDis
);
2073 pDis
->curRegPage
= 0x20;
2079 /*============================================================================*/
2080 /* hotPlugRestore */
2081 /*============================================================================*/
2082 tmErrorCode_t
hotPlugRestore(tmUnitSelect_t txUnit
)
2084 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2085 tmErrorCode_t err
; /* Error code */
2087 UInt8 EnableIntMask
= 0; /* Mask used to enable HPD and RX Sense interrupt */
2089 /* Check unit parameter and point to TX unit object */
2090 err
= checkUnitSetDis(txUnit
, &pDis
);
2091 RETIF(err
!= TM_OK
, err
)
2093 /* Set the BIAS_tmds Value */
2094 regVal
= HDMI_TX_VSWING_VALUE
;
2095 err
= setHwRegister(pDis
, E_REG_P02_ANA_GENERAL_RW
, regVal
);
2096 RETIF(err
!= TM_OK
, err
)
2098 /* PLL registers common configuration */
2099 err
= setHwRegisterFieldTable(pDis
, &kCommonPllCfg
[0]);
2102 /*Reset 656_Alt bit in VIP_CONTROL_4 Register */
2104 setHwRegisterField(pDis
, E_REG_P00_VIP_CNTRL_4_W
, E_MASKREG_P00_VIP_CNTRL_4_656_alt
, 0);
2106 /* DDC interface is disable for TDA9989 after reset, enable it */
2107 err
= setHwRegister(pDis
, E_REG_P00_DDC_DISABLE_RW
, 0x00);
2108 RETIF(err
!= TM_OK
, err
)
2110 err
= setHwRegister(pDis
, E_REG_P12_TX3_RW
, TDA19989_DDC_SPEED_FACTOR
);
2111 RETIF(err
!= TM_OK
, err
)
2113 /* TDA19989 N1 only */
2114 if (pDis
->uDeviceVersion
== E_DEV_VERSION_TDA19989
) {
2116 err
= setHwRegisterField(pDis
, E_REG_P00_I2C_MASTER_RW
, E_MASKREG_P00_I2C_MASTER_dis_mm
, 0); /* 0: enable multi master mode */
2121 /* TDA19989 N1 only */
2123 setCECHwRegister(pDis
, E_REG_CEC_FRO_IM_CLK_CTRL_RW
,
2124 E_MASKREG_CEC_FRO_IM_CLK_CTRL_ghost_dis
|
2125 E_MASKREG_CEC_FRO_IM_CLK_CTRL_imclk_sel
);
2131 /* enable sw_interrupt for debug */
2132 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_1_RW
, E_MASKREG_P00_INT_FLAGS_1_sw_int
);
2134 /* enable edid read */
2135 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_2_RW
, E_MASKREG_P00_INT_FLAGS_2_edid_blk_rd
);
2137 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &EnableIntMask
);
2138 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
; /* Enable RxSense Interrupt */
2139 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
; /* Enable HPD Interrupt */
2140 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, EnableIntMask
);
2141 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
2143 #ifdef TMFL_HDCP_SUPPORT
2145 if (pDis
->HdcpSeed
) {
2147 tmbslTDA9989HdcpDownloadKeys(txUnit
, pDis
->HdcpSeed
,
2148 HDMITX_HDCP_DECRYPT_ENABLE
);
2150 #endif /* TMFL_HDCP_SUPPORT */
2152 setState(pDis
, EV_INIT
);
2157 #ifdef TMFL_TDA9989_PIXEL_CLOCK_ON_DDC
2159 tmErrorCode_t
hotPlugRestore(tmUnitSelect_t txUnit
)
2161 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2162 tmErrorCode_t err
; /* Error code */
2164 UInt8 EnableIntMask
= 0; /* Mask used to enable HPD and RX Sense interrupt */
2166 /* Check unit parameter and point to TX unit object */
2167 err
= checkUnitSetDis(txUnit
, &pDis
);
2168 RETIF(err
!= TM_OK
, err
)
2170 /* Set the BIAS_tmds Value */
2171 regVal
= HDMI_TX_VSWING_VALUE
;
2172 err
= setHwRegister(pDis
, E_REG_P02_ANA_GENERAL_RW
, regVal
);
2173 RETIF(err
!= TM_OK
, err
)
2175 /* PLL registers common configuration */
2176 err
= setHwRegisterFieldTable(pDis
, &kCommonPllCfg
[0]);
2179 /*Reset 656_Alt bit in VIP_CONTROL_4 Register */
2181 setHwRegisterField(pDis
, E_REG_P00_VIP_CNTRL_4_W
, E_MASKREG_P00_VIP_CNTRL_4_656_alt
, 0);
2183 /* DDC interface is disable for TDA9989 after reset, enable it */
2184 err
= setHwRegister(pDis
, E_REG_P00_DDC_DISABLE_RW
, 0x00);
2185 RETIF(err
!= TM_OK
, err
)
2189 if ((pDis
->vinFmt
!= HDMITX_VFMT_NO_CHANGE
) && (pDis
->vinFmt
<= HDMITX_VFMT_TV_MAX
)) {
2191 err
= setHwRegister(pDis
, E_REG_P00_TIMER_H_W
, 0);
2192 RETIF(err
!= TM_OK
, err
)
2194 err
= setHwRegister(pDis
, E_REG_P00_NDIV_IM_W
, kndiv_im
[pDis
->vinFmt
]);
2195 RETIF(err
!= TM_OK
, err
)
2197 err
= setHwRegister(pDis
, E_REG_P12_TX3_RW
, kclk_div
[pDis
->vinFmt
]);
2198 RETIF(err
!= TM_OK
, err
)
2200 } else if (pDis
->vinFmt
> HDMITX_VFMT_TV_MAX
) {
2202 err
= setHwRegister(pDis
, E_REG_P00_TIMER_H_W
, E_MASKREG_P00_TIMER_H_im_clksel
);
2203 RETIF(err
!= TM_OK
, err
)
2204 err
= setHwRegister(pDis
, E_REG_P12_TX3_RW
, 17);
2205 RETIF(err
!= TM_OK
, err
)
2212 /* enable sw_interrupt for debug */
2213 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_1_RW
, E_MASKREG_P00_INT_FLAGS_1_sw_int
);
2215 /* enable edid read */
2216 err
= setHwRegister(pDis
, E_REG_P00_INT_FLAGS_2_RW
, E_MASKREG_P00_INT_FLAGS_2_edid_blk_rd
);
2218 err
= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, &EnableIntMask
);
2219 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_rxs_int
; /* Enable RxSense Interrupt */
2220 EnableIntMask
|= E_MASKREG_CEC_RXSHPDINTENA_ena_hpd_int
; /* Enable HPD Interrupt */
2221 err
+= setCECHwRegister(pDis
, E_REG_CEC_RXSHPDINTENA_RW
, EnableIntMask
);
2222 err
+= getCECHwRegister(pDis
, E_REG_CEC_RXSHPDLEV_R
, &int_level
);
2227 #endif /* TMFL_TDA9989_PIXEL_CLOCK_ON_DDC */
2229 #ifdef TMFL_HDCP_OPTIMIZED_POWER
2230 /*============================================================================*/
2231 /* tmbslTDA9989HdcpPowerDown */
2232 /* RETIF_REG_FAIL NOT USED HERE AS ALL ERRORS SHOULD BE TRAPPED IN ALL BUILDS */
2233 /*============================================================================*/
2234 tmErrorCode_t
tmbslTDA9989HdcpPowerDown(tmUnitSelect_t txUnit
, Bool requested
) {
2235 tmHdmiTxobject_t
*pDis
; /* Pointer to Device Instance Structure */
2236 tmErrorCode_t err
; /* Error code */
2238 /* Check unit parameter and point to TX unit object */
2239 err
= checkUnitSetDis(txUnit
, &pDis
);
2240 RETIF(err
!= TM_OK
, err
);
2242 err
= setHwRegisterField(pDis
, E_REG_P12_TX4_RW
,
2243 E_MASKREG_P12_TX4_pd_all
, (requested
? 0x07 : 0x00));
2249 /*============================================================================*/
2251 /*============================================================================*/