//*****************************************************************************
//
// Function Name: dsic_close
// 
// Description:   Close The Driver
//
//*****************************************************************************
Int32 dsic_close ( DISPDRV_HANDLE_T drvH ) 
{
    Int32                   res = 0;
    dsic_panel_t   *pPanel = (dsic_panel_t *)drvH;
    
    pPanel->pFb  = NULL;
    pPanel->pFbA = NULL;

    if ( CSL_DSI_CloseCmVc ( pPanel->dsiCmVcHandle ) ) 
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERROR, "
            "Closing Command Mode Handle\n\r", __FUNCTION__);
        return ( -1 );
    }
    
    if ( CSL_DSI_CloseClient ( pPanel->clientH ) != CSL_LCD_OK )
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERROR, Closing DSI Client\n\r",
            __FUNCTION__);
        return ( -1 );
    }
    
    if ( CSL_DSI_Close( pPanel->busId ) != CSL_LCD_OK )
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERR Closing DSI Controller\n\r",
            __FUNCTION__ );
        return ( -1 );
    }

    pPanel->pwrState = DISP_PWR_OFF;
    pPanel->drvState = DRV_STATE_INIT;
    LCD_DBG ( LCD_DBG_INIT_ID, "[DISPDRV] %s: OK\n\r", __FUNCTION__ );

    return ( res );
}
//*****************************************************************************
//
// Function Name: DISPDRV__Close
// 
// Description:   Close The Driver
//
//*****************************************************************************
Int32 DISPDRV_Close(DISPDRV_HANDLE_T drvH)
{
	Int32 res = 0;
	DISPDRV_PANEL_T *pPanel = (DISPDRV_PANEL_T *)drvH;

	if (CSL_DSI_CloseCmVc(pPanel->dsiCmVcHandle)) {
		LCD_DBG(LCD_DBG_ERR_ID, "[DISPDRV] %s: ERROR, "
			"Closing Command Mode Handle\n\r", __FUNCTION__);
		return (-1);
	}

	if (CSL_DSI_CloseClient(pPanel->clientH) != CSL_LCD_OK) {
		LCD_DBG(LCD_DBG_ERR_ID,
			"[DISPDRV] %s: ERROR, Closing DSI Client\n",
			__FUNCTION__);
		return (-1);
	}

	if (CSL_DSI_Close(pPanel->busNo) != CSL_LCD_OK) {
		LCD_DBG(LCD_DBG_ERR_ID,
			"[DISPDRV] %s: ERR Closing DSI Controller\n",
			__FUNCTION__);
		return (-1);
	}

	if (pPanel->isTE)
		DISPDRV_TeOff(pPanel);

	if (brcm_disable_dsi_pll_clocks(pPanel->busNo)) {
		LCD_DBG(LCD_DBG_ERR_ID,
			"[DISPDRV] %s: ERROR to disable the pll clock\n",
			__FUNCTION__);
		return (-1);
	}

	pPanel->pwrState = STATE_PWR_OFF;
	pPanel->drvState = DRV_STATE_INIT;
	LCD_DBG(LCD_DBG_INIT_ID, "[DISPDRV] %s: OK\n", __FUNCTION__);

	return (res);
}
//*****************************************************************************
//
// Function Name: DISPDRV__Close
// 
// Description:   Close The Driver
//
//*****************************************************************************
Int32 DISPDRV_Close ( DISPDRV_HANDLE_T drvH ) 
{
    Int32                   res = 0;
    DISPDRV_PANEL_T   *pPanel = (DISPDRV_PANEL_T *)drvH;
    
    DISPDRV_CHECK_PTR_2_RET( drvH, &panel[0], &panel[1], __FUNCTION__ );
    
    pPanel->pFb  = NULL;
    pPanel->pFbA = NULL;
    
    if ( CSL_DSI_CloseCmVc ( pPanel->dsiCmVcHandle ) ) 
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERROR, "
            "Closing Command Mode Handle\n\r", __FUNCTION__);
        return ( -1 );
    }
    
    if ( CSL_DSI_CloseClient ( pPanel->clientH ) != CSL_LCD_OK )
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERROR, Closing DSI Client\n\r",
            __FUNCTION__);
        return ( -1 );
    }
    
    if ( CSL_DSI_Close( pPanel->busId ) != CSL_LCD_OK )
    {
        LCD_DBG ( LCD_DBG_ERR_ID, "[DISPDRV] %s: ERR Closing DSI Controller\n\r",
            __FUNCTION__ );
        return ( -1 );
    }
    
   	DISPDRV_TeOff ( pPanel );


    pPanel->pwrState = DISP_PWR_OFF;
    pPanel->drvState = DRV_STATE_INIT;
    LCD_DBG ( LCD_DBG_INIT_ID, "[DISPDRV] %s: OK\n\r", __FUNCTION__ );
    
    return ( res );
}
/*
 *
 *  Function Name: DSI_Close
 *
 *  Description:   disp bus OFF
 *
 */
Int32 DSI_Close(DISPDRV_HANDLE_T drvH)
{
	Int32 res = 0;
	DispDrv_PANEL_t	*pPanel	= (DispDrv_PANEL_t *)drvH;

	if (pPanel->disp_info->vmode)
		CSL_DSI_Suspend(pPanel->dsiCmVcHandle);

	if (CSL_DSI_CloseCmVc(pPanel->dsiCmVcHandle)) {
		DSI_ERR("Closing Command Mode Handle\n");
		return -1;
	}

	if (CSL_DSI_CloseClient(pPanel->clientH) != CSL_LCD_OK)	{
		DSI_ERR("Closing DSI Client\n");
		return -1;
	}

	if (CSL_DSI_Close(pPanel->busNo) != CSL_LCD_OK)	{
		DSI_ERR("ERR Closing DSI Controller\n");
		return -1;
	}

	if (pPanel->isTE)
		DSI_TeOff(pPanel);

	if (brcm_disable_dsi_pll_clocks(pPanel->busNo))	{
		DSI_ERR("ERROR disabling the pll clock\n");
		return -1;
	}

	gpio_free(pPanel->disp_info->rst->gpio);

	pPanel->pwrState = STATE_PWR_OFF;
	pPanel->drvState = DRV_STATE_INIT;
	g_display_enabled = 0;
	DSI_INFO("OK\n");

	return res;
}
/*
 *
 *  Function Name: DSI_Open
 *
 *  Description:   disp bus ON
 *
 */
Int32 DSI_Open(DISPDRV_HANDLE_T drvH)
{
	Int32 res = 0;
	DispDrv_PANEL_t	*pPanel;

	pPanel = (DispDrv_PANEL_t *) drvH;

	DSI_INFO("enter\n");

	if (pPanel->drvState !=	DRV_STATE_INIT)	{
		DSI_ERR("ERROR State != Init\n");
		return -1;
	}

	if (brcm_enable_dsi_pll_clocks(pPanel->busNo,
		pPanel->dsi_cfg->hsBitClk.clkIn_MHz * 1000000,
		pPanel->dsi_cfg->hsBitClk.clkInDiv,
		pPanel->disp_info->desense_offset,
		pPanel->dsi_cfg->escClk.clkIn_MHz   * 1000000
		/ pPanel->dsi_cfg->escClk.clkInDiv)) {

		DSI_ERR("ERROR enabling clock\n");
	}

	if (pPanel->isTE && DSI_TeOn(pPanel) == -1) {
		DSI_ERR("Failed to Configure TE Input\n");
		goto err_te_on;
	}

	if (CSL_DSI_Init(pPanel->dsi_cfg) != CSL_LCD_OK) {
		DSI_ERR("DSI CSL Init Failed\n");
		goto err_dsi_init;
	}

	if (CSL_DSI_OpenClient(pPanel->busNo, &pPanel->clientH)	!= CSL_LCD_OK) {
		DSI_ERR("CSL_DSI_OpenClient Failed\n");
		goto err_dsi_open_cl;
	}

	if (CSL_DSI_OpenCmVc(pPanel->clientH,
		pPanel->cmnd_mode, &pPanel->dsiCmVcHandle) != CSL_LCD_OK) {

		DSI_ERR("CSL_DSI_OpenCmVc Failed\n");
		goto err_dsi_open_cm;
	}

	if (!pPanel->dsi_cfg->dispEngine && pPanel->dsi_cfg->pixTxporter) {
		DSI_ERR("Cannot transfer pixels via MMDMA to DispEngine 0.");
		DSI_ERR("Default to Display Engine 1\n");
		pPanel->dsi_cfg->dispEngine = 1;
	}

	if (pPanel->dsi_cfg->dispEngine && pPanel->dsi_cfg->pixTxporter) {
		if (csl_dma_vc4lite_init() != DMA_VC4LITE_STATUS_SUCCESS) {
			DSI_ERR("csl_dma_vc4lite_init Failed\n");
			goto err_dma_init;
		}
	}
	if (!disp_reg) {
		/*CAM2 LDO */
		disp_reg = regulator_get(NULL, pPanel->disp_info->reg_name);
		if (IS_ERR_OR_NULL(disp_reg)) {
			DSI_ERR("Failed to get disp_reg\n");
			goto err_reg_init;
		}
		if (g_display_enabled)
			regulator_enable(disp_reg); /* Turn ON disp_reg to increase use count */
	}
	res = gpio_request(pPanel->disp_info->rst->gpio, "LCD_RST");
	if (res < 0) {
		DSI_ERR("gpio_request failed %ld\n", res);
		goto err_gpio_request;
	}

	if (!g_display_enabled)
		hw_reset(drvH, FALSE);
#if 0	// SS & DS not used
	if (DSI_ReadPanelID(pPanel) < 0) {
		DSI_ERR("ID read failed\n");
		goto err_id_read;
	}
#endif
	pPanel->win_dim.l = 0;
	pPanel->win_dim.r = pPanel->disp_info->width-1;
	pPanel->win_dim.t = 0;
	pPanel->win_dim.b = pPanel->disp_info->height-1;
	pPanel->win_dim.w = pPanel->disp_info->width;
	pPanel->win_dim.h = pPanel->disp_info->height;

	pPanel->drvState = DRV_STATE_OPEN;

	DSI_INFO("OK\n");

	return res;
#if 0
err_id_read:
	gpio_free(pPanel->disp_info->rst->gpio);
#endif
err_gpio_request:
err_reg_init:
err_dma_init:
	CSL_DSI_CloseCmVc(pPanel->dsiCmVcHandle);
err_dsi_open_cm:
	CSL_DSI_CloseClient(pPanel->clientH);
err_dsi_open_cl:
	CSL_DSI_Close(pPanel->busNo);
err_dsi_init:
	if (pPanel->isTE)
		DSI_TeOff(pPanel);
err_te_on:
	return -1;
}