/*
 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Jason Hu <jason.hu@intel.com>
 */

#include "psb_HDMIExtMode.h"
#include "psb_output_android.h"
#include "pvr2d.h"
#include "psb_drv_video.h"
#include "psb_drv_debug.h"

#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData

VAStatus psb_HDMIExt_get_prop(psb_android_output_p output,
                              unsigned short *xres, unsigned short *yres)
{
    psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;

    if (!psb_HDMIExt_info || !psb_HDMIExt_info->hdmi_extvideo_prop ||
        (psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode == OFF)) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get HDMI prop\n", __FUNCTION__);
        return VA_STATUS_ERROR_UNKNOWN;
    }
    *xres = psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode_XRes;
    *yres = psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode_YRes;

    return VA_STATUS_SUCCESS;
}

psb_hdmi_mode psb_HDMIExt_get_mode(psb_android_output_p output)
{
    psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;

    if (!psb_HDMIExt_info) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get HDMI mode\n", __FUNCTION__);
        return VA_STATUS_ERROR_UNKNOWN;
    }
    return psb_HDMIExt_info->hdmi_mode;
}

VAStatus psb_HDMIExt_update(VADriverContextP ctx, psb_HDMIExt_info_p psb_HDMIExt_info)
{
    INIT_DRIVER_DATA;
    drmModeCrtc *hdmi_crtc = NULL;
    drmModeConnector *hdmi_connector = NULL;
    drmModeEncoder *hdmi_encoder = NULL;
    char *strHeight = NULL;
    struct drm_lnc_video_getparam_arg arg;
    int hdmi_state = 0;
    static int hdmi_connected_frame = 0;

    arg.key = IMG_VIDEO_GET_HDMI_STATE;
    arg.value = (uint64_t)((unsigned int)&hdmi_state);
    drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
                        &arg, sizeof(arg));

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : hdmi_state = %d\n", __FUNCTION__, hdmi_state);
    if (psb_HDMIExt_info->hdmi_state != hdmi_state) {
        psb_HDMIExt_info->hdmi_state = hdmi_state;
        switch (hdmi_state) {
            case HDMI_MODE_EXT_VIDEO:
                psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = EXTENDED_VIDEO;
                psb_HDMIExt_info->hdmi_mode = EXTENDED_VIDEO;

                psb_extvideo_prop_p hdmi_extvideo_prop = psb_HDMIExt_info->hdmi_extvideo_prop;

                hdmi_connector = drmModeGetConnector(driver_data->drm_fd, psb_HDMIExt_info->hdmi_connector_id);
                if (!hdmi_connector) {
                    drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi connector\n", __FUNCTION__);
                    return VA_STATUS_ERROR_UNKNOWN;
                }

                hdmi_encoder = drmModeGetEncoder(driver_data->drm_fd, hdmi_connector->encoder_id);
                if (!hdmi_encoder) {
                    drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi encoder\n", __FUNCTION__);
                    return VA_STATUS_ERROR_UNKNOWN;
                }

                hdmi_crtc = drmModeGetCrtc(driver_data->drm_fd, hdmi_encoder->crtc_id);
                if (!hdmi_crtc) {
                    /* No CRTC attached to HDMI. */
                    drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi crtc\n", __FUNCTION__);
                    return VA_STATUS_ERROR_UNKNOWN;
                }

                strHeight = strstr(hdmi_crtc->mode.name, "x");
                hdmi_extvideo_prop->ExtVideoMode_XRes = (unsigned short)atoi(hdmi_crtc->mode.name);
                hdmi_extvideo_prop->ExtVideoMode_YRes = (unsigned short)atoi(strHeight + 1);
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : size = %d x %d\n", __FUNCTION__,
                        hdmi_extvideo_prop->ExtVideoMode_XRes, hdmi_extvideo_prop->ExtVideoMode_YRes);
                drmModeFreeCrtc(hdmi_crtc);
                drmModeFreeEncoder(hdmi_encoder);
                drmModeFreeConnector(hdmi_connector);
                break;
            case HDMI_MODE_OFF:
                psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = OFF;
                psb_HDMIExt_info->hdmi_mode = OFF;
                hdmi_connected_frame = 0;
                break;
            default:
                psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = UNDEFINED;
                psb_HDMIExt_info->hdmi_mode = UNDEFINED;
        }
    }

    return VA_STATUS_SUCCESS;
}

psb_HDMIExt_info_p psb_HDMIExt_init(VADriverContextP ctx, psb_android_output_p output)
{
    INIT_DRIVER_DATA;
    drmModeRes *resources;
    drmModeConnector *connector = NULL;
    drmModeEncoder *mipi_encoder = NULL;
    int mipi_connector_id = 0, mipi_encoder_id = 0, mipi_crtc_id = 0, i;
    psb_HDMIExt_info_p psb_HDMIExt_info = NULL;

    psb_HDMIExt_info = (psb_HDMIExt_info_p)calloc(1, sizeof(psb_HDMIExt_info_s));
    if (!psb_HDMIExt_info) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to create psb_HDMIExt_info.\n", __FUNCTION__);
        return NULL;
    }
    memset(psb_HDMIExt_info, 0, sizeof(psb_HDMIExt_info_s));

    psb_HDMIExt_info->hdmi_extvideo_prop = (psb_extvideo_prop_p)calloc(1, sizeof(psb_extvideo_prop_s));
    if (!psb_HDMIExt_info->hdmi_extvideo_prop) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to create hdmi_extvideo_prop.\n", __FUNCTION__);
        free(psb_HDMIExt_info);
        return NULL;
    }
    memset(psb_HDMIExt_info->hdmi_extvideo_prop, 0, sizeof(psb_extvideo_prop_s));

    /*Get Resources.*/
    resources = drmModeGetResources(driver_data->drm_fd);
    if (!resources) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : drmModeGetResources failed.\n", __FUNCTION__);
        goto exit;
    }

    /*Get MIPI and HDMI connector id.*/
    for (i = 0; i < resources->count_connectors; i++) {
        connector = drmModeGetConnector(driver_data->drm_fd, resources->connectors[i]);

        if (!connector) {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get connector %i\n", __FUNCTION__,
                               resources->connectors[i]);
            continue;
        }

        if (connector->connector_type == DRM_MODE_CONNECTOR_DVID)
            psb_HDMIExt_info->hdmi_connector_id = connector->connector_id;

        if ((connector->connector_type == DRM_MODE_CONNECTOR_DSI) &&
            (!mipi_connector_id)) {
            mipi_connector_id = connector->connector_id;
            mipi_encoder_id = connector->encoder_id;
        }

        drmModeFreeConnector(connector);
        connector = NULL;
    }

    if (!mipi_connector_id ||
        !psb_HDMIExt_info->hdmi_connector_id ||
        !mipi_encoder_id) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get connector id or mipi encoder id. mipi_connector_id=%d, hdmi_connector_id=%d, mipi_encoder_id=%d\n", __FUNCTION__,
                           mipi_connector_id, psb_HDMIExt_info->hdmi_connector_id, mipi_encoder_id);
        goto exit;
    }

    mipi_encoder = drmModeGetEncoder(driver_data->drm_fd, mipi_encoder_id);
    if (!mipi_encoder) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get mipi encoder %i\n", __FUNCTION__);
        goto exit;
    }

    psb_HDMIExt_info->mipi_crtc_id = mipi_encoder->crtc_id;
    drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : mipi_crtc_id = %d\n", __FUNCTION__,
                             mipi_crtc_id);

    drmModeFreeEncoder(mipi_encoder);

    if (psb_HDMIExt_update(ctx, psb_HDMIExt_info))
        goto exit;

    if (resources)
        drmModeFreeResources(resources);

    return psb_HDMIExt_info;

exit:
    if (resources)
        drmModeFreeResources(resources);

    if (connector)
        drmModeFreeConnector(connector);

    return psb_HDMIExt_info;
}

VAStatus psb_HDMIExt_deinit(psb_android_output_p output)
{
    psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info;

    if (psb_HDMIExt_info->hdmi_extvideo_prop)
        free(psb_HDMIExt_info->hdmi_extvideo_prop);

    if (psb_HDMIExt_info)
        free(psb_HDMIExt_info);

    return VA_STATUS_SUCCESS;
}

