/*****************************************************************************/
/* Copyright (c) 2008 NXP B.V.                                               */
/*                                                                           */
/* This library is free software; you can redistribute it and/or             */
/* modify it under the terms of the GNU Lesser General Public                */
/* License as published by the Free Software Foundation, using               */
/* version 2.1 of the License.                                               */
/*                                                                           */
/* This library is distributed in the hope that it will be useful,           */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU          */
/* Lesser General Public License for more details.                           */
/*                                                                           */
/* You should have received a copy of the GNU Lesser General Public          */
/* License along with this library; if not, write to the Free Software       */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   */
/*                                                                           */
/*****************************************************************************/
/*
   NXP STB22X Driver

   Code is derived from TI Davinci driver.

   TI Davinci driver

   (c) Copyright 2007  Telio AG

   Written by Denis Oliver Kropp <dok@directfb.org>

   Code is derived from VMWare driver.

   (c) Copyright 2001-2007  The DirectFB Organization (directfb.org)
   (c) Copyright 2000-2004  Convergence (integrated media) GmbH

   All rights reserved.

   Written by Denis Oliver Kropp <dok@directfb.org>,
              Andreas Hundt <andi@fischlustig.de>,
              Sven Neumann <neo@directfb.org>,
              Ville Syrjälä <syrjala@sci.fi> and
              Claudio Ciccani <klan@users.sf.net>.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*//**
    @file   phStbDFB_mixer.c
    @brief  Implementation of Mixer API for DirectFB.

@b  Component:  phStbDFB.

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
  1 20080103    laird       New version for DirectFB 1.1.1
  2 20080902    laird       Update Copyright headers.
  4 20080918    laird       Updates to debug and startup behaviour.
  5 20081001    neill       Correct config flags
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

/***********************************************
* INCLUDE FILES                                *
************************************************/
#include "phStbDFB_mixer.h"

/***********************************************
* LOCAL MACROS                                 *
* recommendation only: <MODULE><_WORD>+        *
************************************************/
#define GRAPHICS_1_MASK  0x01
#define GRAPHICS_2_MASK  0x02
#define DISPLAY_1_MASK   0x04
#define DISPLAY_2_MASK   0x08

/******************************************************************
* LOCAL TYPEDEFS                                                  *
* recommendation only:                [p]phStbTemplate_<Word>+_t  *
*******************************************************************/
D_DEBUG_DOMAIN( phStbDFB_Mixers, "NXP/STB22X/Mixer", "NXP 22X Mixers" );

/******************************************************************
* STATIC FUNCTION PROTOTYPES                  <Module>_<Word>+    *
*******************************************************************/

/******************************************************************
* STATIC DATA                  g[k|p|kp|pk|kpk]<Module>_<Word>+   *
*******************************************************************/

/**
 * @brief Give each mixer a name.
 */
static Char *gphStbDFB_ScreenMixerName[PH_STBVIDEORENDERER_MAX_INSTANCES] =
{
    "Mixer (Analog)",
    "Mixer (HDMI)"
};

/**************************************************************************
* EXPORTED DATA                     g[k|p|kp|pk|kpk]phStbTemplate_<Word>+ *
***************************************************************************/

/*******************************************************************************
* FUNCTION IMPLEMENTATION  <Module>[_<Word>+] for static functions             *
*                          tm[<screen>]<Module>[_<Word>+] for exported functions*
********************************************************************************/

/******************************************************************************/
/*
 * Called once by the master for each mixer.
 * Driver fills description and default config.
 */
extern DFBResult phStbDFB_InitMixer(
    CoreScreen                   *screen,
    void                         *driver_data,
    void                         *screen_data,
    int                           mixer,
    DFBScreenMixerDescription    *description,
    DFBScreenMixerConfig         *config )
{
    DFBResult result = DFB_FAILURE;
    tmErrorCode_t err = TM_OK;
    phStbVideoRenderer_t *pVideoRenderer;
    phStbVideoRenderer_Plane_t layers[phStbVideoRenderer_Planes_Count];

    UInt32 i;
    UInt32 red;
    UInt32 green;
    UInt32 blue;

    D_DEBUG_ENTER( phStbDFB_Mixers, "");

    err = phStbVideoRenderer_GetInstance(mixer, &pVideoRenderer);
    if (err != TM_OK)
    {
        D_DEBUG_AT(phStbDFB_Mixers, " -> phStbVideoRenderer_GetInstance failed err=0x%08x\n", err);
        goto RETURN;
    }

    description->caps = PH_STBDFB_SCREEN_MIXERS_CAPABILITIES;

    /* Bit flag of all visible layers possible: */
    description->layers = 0;
    /* Add a bit for each layer: */
    for (i = 0; i < PH_STBDFB_NUM_LAYERS_USED; i++)
    {
        description->layers <<= 1;
        description->layers ++;
    }
    /* Not sure if just setting description->sub_layers is sufficient. */
    description->sub_layers = description->layers;
    snprintf(description->name,
             DFB_SCREEN_MIXER_DESC_NAME_LENGTH, gphStbDFB_ScreenMixerName[mixer]);

    config->flags = DSMCONF_LAYERS;

    /* Get the layers currently enabled for this mixer */
    config->layers = 0;

    err = phStbVideoRenderer_GetPlaneStack(pVideoRenderer, layers);
    if (err != TM_OK)
    {
        D_DEBUG_AT(phStbDFB_Mixers, " -> phStbVideoRenderer_GetPlaneStack failed err=0x%08x\n", err);
        goto RETURN;
    }

    for(i=0; i<phStbVideoRenderer_Planes_Count; i++)
    {
        if (layers[i].enabled)
        {
            switch (layers[i].layer)
            {
                case(phStbVideoRenderer_Layers_Graphics1) :
                    config->layers |= GRAPHICS_1_MASK;
                    break;
                case(phStbVideoRenderer_Layers_Graphics2) :
                    config->layers |= GRAPHICS_2_MASK;
                    break;
                case(phStbVideoRenderer_Layers_Display1) :
                    config->layers |= DISPLAY_1_MASK;
                    break;
                case(phStbVideoRenderer_Layers_Display2) :
                    config->layers |= DISPLAY_2_MASK;
                    break;
                default:
                    break;
            }
        }
    }

    err = phStbVideoRenderer_GetBackgroundColour( pVideoRenderer, &red, &green, &blue);
    if (err != 0)
    {
        D_DEBUG_AT(phStbDFB_Mixers, " -> phStbVideoRenderer_GetBackgroundColour failed err=0x%08x\n", err);
        goto RETURN;
    }

    config->flags |= DSMCONF_BACKGROUND;
    config->background.a = OPAQUE;
    config->background.r = (UInt8)red;
    config->background.g = (UInt8)green;
    config->background.b = (UInt8)blue;

    result = DFB_OK;

RETURN:
    D_DEBUG_EXIT( phStbDFB_Mixers, " result => 0x%08x", result);
    return result;

}

/******************************************************************************/
/*
 * Test if configuration is supported. Store failing fields in 'failed'.
 */
extern DFBResult phStbDFB_TestMixerConfig(
    CoreScreen                  *screen,
    void                        *driver_data,
    void                        *screen_data,
    int                          mixer,
    const DFBScreenMixerConfig  *config,
    DFBScreenMixerConfigFlags   *failed )
{
    DFBResult result = DFB_OK;
    D_DEBUG_ENTER( phStbDFB_Mixers, "");
    D_DEBUG_EXIT( phStbDFB_Mixers, " result => 0x%08x", result);
    return result;
}

/******************************************************************************/

extern DFBResult phStbDFB_SetMixerConfig(
    CoreScreen                  *screen,
    void                        *driver_data,
    void                        *screen_data,
    int                          mixer,
    const DFBScreenMixerConfig  *config )
{
    DFBResult result = DFB_FAILURE;
    tmErrorCode_t err = TM_OK;
    phStbVideoRenderer_t *pVideoRenderer;

    D_DEBUG_ENTER( phStbDFB_Mixers, " config->flags=0x%08x", config->flags);

    err = phStbVideoRenderer_GetInstance(mixer, &pVideoRenderer);

    if (err == TM_OK)
    {
        if (config->flags & DSMCONF_LAYERS)
        {
            phStbVideoRenderer_Plane_t layers[phStbVideoRenderer_Planes_Count];

            err = phStbVideoRenderer_GetPlaneStack(pVideoRenderer, layers);
            if (err == TM_OK)
            {
                int i;
                for(i=0; i<phStbVideoRenderer_Planes_Count; i++)
                {
                    switch (layers[i].layer)
                    {
                        case(phStbVideoRenderer_Layers_Graphics1) :
                            layers[i].enabled = (config->layers & GRAPHICS_1_MASK) ? true : false;
                            break;
                        case(phStbVideoRenderer_Layers_Graphics2) :
                            layers[i].enabled = (config->layers & GRAPHICS_2_MASK) ? true : false;
                            break;
                        case(phStbVideoRenderer_Layers_Display1) :
                            layers[i].enabled = (config->layers & DISPLAY_1_MASK) ? true : false;
                            break;
                        case(phStbVideoRenderer_Layers_Display2) :
                            layers[i].enabled = (config->layers & DISPLAY_2_MASK) ? true : false;
                            break;
                        default:
                            layers[i].enabled = false;
                            break;
                    }
                }

                err = phStbVideoRenderer_SetPlaneStack(pVideoRenderer, layers);
                if (err == TM_OK)
                {
                    result = DFB_OK;
                }
            }
        }

        if (config->flags & DSMCONF_BACKGROUND)
        {
            err = phStbVideoRenderer_SetBackgroundColour( pVideoRenderer,
                                                          (unsigned int)config->background.r,
                                                          (unsigned int)config->background.g,
                                                          (unsigned int)config->background.b);
            if (err == TM_OK)
            {
                result = DFB_OK;
            }
        }
    }

    D_DEBUG_EXIT( phStbDFB_Mixers, " result => 0x%08x", result);
    return result;
}

