/*****************************************************************************/
/* Copyright (c) 2009 NXP B.V.                                               */
/*                                                                           */
/* This program is free software; you can redistribute it and/or modify      */
/* it under the terms of the GNU General Public License as published by      */
/* the Free Software Foundation, using version 2 of the License.             */
/*                                                                           */
/* This program 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 General Public License for more details.                              */
/*                                                                           */
/* You should have received a copy of the GNU General Public License         */
/* along with this program; if not, write to the Free Software               */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307       */
/* USA.                                                                      */
/*                                                                           */
/*****************************************************************************/
/**
    @file   phStbScartSwitch.c
    @brief  Linux implementation of the AV Scart switch driver.

    @b  Module:  UDA3000 (AV Scart switch) driver.

*//*

Rev Date        Author      Comments
--------------------------------------------------------------------------------
    20061009    frq06781    Creation.
    20061219    frq06781    Added GetVolume ioctl.
    20070126    frq06781    Correct IOCTL GET_xxx (incorrect values returned)
    20070129    frq06781    Merged with PR10042.
    20070130    frq06781    - Modify to externalize API (for ALSA).
                            - Add mutex protection to allow reentrance of API
    20070208    frq06781    Added "EXPORT_SYMBOL" for API.
    20070221    frq06781    Remove busy flag in open.
                            Scart switch driver is now multi instance.
    20081015    frq06751    Import component into stb225 database
  3 20090121    batelaan    Update license header
  4 20090226    boudy       Add Get/Set IOCTL to control slow blanking and video format
                            with one IOCTL and one associated data structure
--------------------------------------------------------------------------------
    For consistency and standardisation retain the Section Separators.
*/

/* Number of devices */
#define phStbScartSwitch_DEVICE_NUMBER 1

/*============================================================================*/
/*                   STANDARD INCLUDE FILES                                   */
/*============================================================================*/
#include <tmtypes.h>                    // DVP standard types/defines/enums
#include <tmosal.h>                     // DVP Operating System Adaptaion Layer

#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/types.h>

/*============================================================================*/
/*                   PROJECT INCLUDE FILES                                    */
/*============================================================================*/
#include "phStbScartSwitch.h"
#include "phStbScartSwitchApi.h"


/*============================================================================*/
/*                   MACRO DEFINITION                                         */
/*============================================================================*/


/*============================================================================*/
/*                   TYPE DEFINITION                                          */
/*============================================================================*/


/*============================================================================*/
/*                   PUBLIC VARIABLES DEFINITION                              */
/*============================================================================*/

/*============================================================================*/
/*                   EXTERNAL FUNCTIONS DECLARATIONS                         */
/*============================================================================*/
int32_t phStbScartSwitchUDASetInterface(
        phStbScartSwitchFunctionList_t *pFunctionList,
        uint8_t Id);

/*============================================================================*/
/*                   STATIC FUNCTIONS DECLARATIONS                            */
/*============================================================================*/

static int __init    phStbScartSwitch_init(         void                                                                               );
static void __exit   phStbScartSwitch_exit(         void                                                                               );
static int           sfphStbScartSwitch_open(       struct inode *inode, struct file *file                                             );
static int           sfphStbScartSwitch_release(    struct inode *inode, struct file *file                                             );
static int           sfphStbScartSwitch_ioctl(      struct inode *inode,
                                                    struct file *file,
                                                    unsigned int command,
                                                    unsigned long parameters                                                           );

/*============================================================================*/
/*                   STATIC VARIABLES DECLARATIONS                            */
/*============================================================================*/
static uint8_t gInitialized = False;
static uint8_t gDeviceId;
static phStbScartSwitchFunctionList_t gFunctionList;

/* File operations */
static struct file_operations sphStbScartSwitch_fops =
{
	.open = sfphStbScartSwitch_open,
	.release = sfphStbScartSwitch_release,
    .ioctl = sfphStbScartSwitch_ioctl
};

static struct miscdevice udaMiscDev =
{
     .minor =   MISC_DYNAMIC_MINOR,
     .name  =   PH_STB_SCART_SWITCH_DEVNAME,
     .fops  =   &sphStbScartSwitch_fops
};

/* Mutex to allow reentrance of functions */
static struct semaphore gApiReentranceProtectionMutex;

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchInit                                          */
/*                                                                            */
/* DESCRIPTION: This function initialize the scart switch driver.             */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
static int __init phStbScartSwitch_init(void)
{
    int ret = 0;

    /* Set device id and configure interface functions */
    gDeviceId = PHSTB_SCART_SWITCH_UDA;
    ret = phStbScartSwitchUDASetInterface(&gFunctionList, gDeviceId);
    if (ret != 0)
    {
        dprintk("%s :phStbScartSwitchUDASetInterface() failed !\n", PH_STB_SCART_SWITCH_DESCRIPTION);
        ret = -EINVAL;
    }

    /* Register a misc device called "uda3000". */
    ret = misc_register(&udaMiscDev);
    if (ret < 0)
    {
        dprintk("%s :Can't register misc device (minor %d)!\n", PH_STB_SCART_SWITCH_DESCRIPTION, udaMiscDev.minor);
        return -EINVAL;
    }

    ret = gFunctionList.Init();
    if (ret != 0)
    {
        dprintk("%s :Device init() failed\n", PH_STB_SCART_SWITCH_DESCRIPTION);
        return -EINVAL;
    }

    gInitialized = True;

    /* Initialize a mutex because of reentrance of API (Linux driver access and API) */
    init_MUTEX(&gApiReentranceProtectionMutex);
    
    printk("%s (%s-%s)\n",
              PH_STB_SCART_SWITCH_DESCRIPTION,
              __DATE__,
              __TIME__);

    return 0;
}


/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbDriversAudio_exit                                        */
/*                                                                            */
/* DESCRIPTION: This function de-initialize the scart switch driver.          */
/* -------------------------------------------------------------------------- */
static void __exit phStbScartSwitch_exit(void)
{
    int ret;

    /* Call API function to deinit driver */
    ret = gFunctionList.Terminate();
    if (ret != 0)
        dprintk("%s : Terminate operation has failed\n", PH_STB_SCART_SWITCH_DESCRIPTION);

    /* deregister misc device */
    if (misc_deregister(&udaMiscDev) != 0)
    {
        dprintk("%s : could not misc_deregister the device\n", PH_STB_SCART_SWITCH_DESCRIPTION);
    }
}


/* -------------------------------------------------------------------------- */
/* FUNCTION:    sfphStbScartSwitch_open                                       */
/*                                                                            */
/* DESCRIPTION: This function open the scart switch.                          */
/* -------------------------------------------------------------------------- */
static int sfphStbScartSwitch_open(struct inode *inode, struct file *file)
{
    /* Multiple instance may be opened in scart switch */
    return 0;
}


/* -------------------------------------------------------------------------- */
/* FUNCTION:    sfphStbScartSwitch_release                                    */
/*                                                                            */
/* DESCRIPTION: This function release the scart switch.                       */
/* -------------------------------------------------------------------------- */
static int sfphStbScartSwitch_release(struct inode *inode, struct file *file)
{
    return 0;
}


/* -------------------------------------------------------------------------- */
/* FUNCTION:    sfphStbScartSwitch_ioctl                                      */
/*                                                                            */
/* DESCRIPTION: This function release the scart switch.                       */
/* -------------------------------------------------------------------------- */
static int sfphStbScartSwitch_ioctl(struct inode  *inode,
                                    struct file   *file,
                                    unsigned int  command,
                                    unsigned long parameters)
{
    int ret = 0;
    phStbScartSwitchSetVolumeData_t setVolumeData;
    phStbScartSwitchGetVolumeData_t getVolumeData;
    phStbScartSwitchSetOuputModeData_t setOutputModeData;
    phStbScartSwitchSetVideoFormatData_t setVideoFormatData;
    phStbScartSwitchSetSBModeData_t setSBModeData;
    phStbScartSwitchSetSBValueData_t setSBValueData;
    phStbScartSwitchGetSBValueData_t getSBValueData;
    phStbScartSwitchInstallSBCallbackData_t installSBCallbackData;
    phStbScartSwitchSetFBModeData_t setFBModeData;
    phStbScartSwitchAudioCommonMute_t audioCommonMute;
    phStbScartSwitchSetAudioSourceData_t setAudioSource;
    phStbScartSwitch_data_t scartSwitchData;
    uint8_t deviceId;

    switch(command)
    {
        case phStbScartSwitch_SET_VOLUME:
        {
            /* Retrieve data from user space */
            copy_from_user(&setVolumeData, (phStbScartSwitchSetVolumeData_t *)parameters, sizeof(phStbScartSwitchSetVolumeData_t));
            /* Set volume level */
            phStbScartSwitchSetVolume(setVolumeData.kScartNumber,
                                      setVolumeData.kVolume);
        }
        break;

        case phStbScartSwitch_GET_VOLUME:
        {
            /* Retrieve data from user space */
            copy_from_user(&getVolumeData, (phStbScartSwitchGetVolumeData_t *)parameters, sizeof(phStbScartSwitchGetVolumeData_t));
            /* Get volume level */
            phStbScartSwitchGetVolume(getVolumeData.kScartNumber,
                                      &(getVolumeData.kVolume));
            /* Transfer data to user space */
            copy_to_user((phStbScartSwitchGetVolumeData_t *)parameters, &getVolumeData, sizeof(phStbScartSwitchGetVolumeData_t));
        }
        break;

        case phStbScartSwitch_SET_OUTPUT_MODE:
        {
            /* Retrieve data from user space */
            copy_from_user(&setOutputModeData, (phStbScartSwitchSetOuputModeData_t *)parameters, sizeof(phStbScartSwitchSetOuputModeData_t));
            /* Set output mode */
            phStbScartSwitchSetOutputMode(setOutputModeData.kScartNumber,
                                          setOutputModeData.kMode);
        }
        break;

        case phStbScartSwitch_SET_VIDEO_FORMAT:
        {
            /* Retrieve data from user space */
            copy_from_user(&setVideoFormatData, (phStbScartSwitchSetVideoFormatData_t *)parameters, sizeof(phStbScartSwitchSetVideoFormatData_t));
            /* Set video format */
            phStbScartSwitchSetVideoFormat(setVideoFormatData.kScartNumber,
                                           setVideoFormatData.kFormat);
        }
        break;

        case phStbScartSwitch_SET_SB_MODE:
        {
            /* Retrieve data from user space */
            copy_from_user(&setSBModeData, (phStbScartSwitchSetSBModeData_t *)parameters, sizeof(phStbScartSwitchSetSBModeData_t));
            /* Set slow blanking mode */
            phStbScartSwitchSetSBMode(setSBModeData.kScartNumber,
                                      setSBModeData.kMode);
        }
        break;

        case phStbScartSwitch_SET_SB_VALUE:
        {
            /* Retrieve data from user space */
            copy_from_user(&setSBValueData, (phStbScartSwitchSetSBValueData_t *)parameters, sizeof(phStbScartSwitchSetSBValueData_t));
            /* Set slow blanking value */
            phStbScartSwitchSetSBValue(setSBValueData.kScartNumber,
                                       setSBValueData.kValue);
        }
        break;

        case phStbScartSwitch_GET_SB_VALUE:
        {
            /* Retrieve data from user space */
            copy_from_user(&getSBValueData, (phStbScartSwitchGetSBValueData_t *)parameters, sizeof(phStbScartSwitchGetSBValueData_t));
            /* Get slow blanking value */
            phStbScartSwitchGetSBValue(getSBValueData.kScartNumber,
                                       &(getSBValueData.kValue));
            /* Transfer data to user space */
            copy_to_user((phStbScartSwitchGetSBValueData_t *)parameters, &getSBValueData, sizeof(phStbScartSwitchGetSBValueData_t));
        }
        break;

        case phStbScartSwitch_INSTALL_SB_CALLBACK:
        {
            /* Retrieve data from user space */
            copy_from_user(&installSBCallbackData, (phStbScartSwitchInstallSBCallbackData_t *)parameters, sizeof(phStbScartSwitchInstallSBCallbackData_t));
            /* Install slow blanking callback */
            phStbScartSwitchInstallSBCallback(installSBCallbackData.kScartNumber,
                                              installSBCallbackData.pFunc);
        }
        break;

        case phStbScartSwitch_SET_FB_MODE:
        {
            /* Retrieve data from user space */
            copy_from_user(&setFBModeData, (phStbScartSwitchSetFBModeData_t *)parameters, sizeof(phStbScartSwitchSetFBModeData_t));
            /* Set fast blanking mode */
            phStbScartSwitchSetFBMode(setFBModeData.kScartNumber,
                                      setFBModeData.kFBMode);
        }
        break;

        case phStbScartSwitch_SET_AUDIO_COMMON_MUTE:
        {
            /* Retrieve data from user space */
            copy_from_user(&audioCommonMute, (phStbScartSwitchAudioCommonMute_t *)parameters, sizeof(phStbScartSwitchAudioCommonMute_t));
            /* Set fast blanking mode */
            phStbScartSwitchSetAudioCommonMute(audioCommonMute);
        }
        break;

        case phStbScartSwitch_SET_AUDIO_SOURCE:
        {
            /* Retrieve data from user space */
            copy_from_user(&setAudioSource, (phStbScartSwitchSetAudioSourceData_t *)parameters, sizeof(phStbScartSwitchSetAudioSourceData_t));
            /* Set audio source to use */
            phStbScartSwitchSetAudioSource(setAudioSource.kScartNumber,
                                           setAudioSource.kAudioSource);
        }
        break;

        case phStbScartSwitch_GET_SWITCH_SETTINGS:
        {
            /* Get current scart switch settings: slow blanking and video format */
            phStbScartSwitchGetSwitchSettings(&scartSwitchData);
            /* Transfer data to user space */
            copy_to_user((phStbScartSwitch_data_t *)parameters, &scartSwitchData, sizeof(phStbScartSwitch_data_t));
        }
        break;

        case phStbScartSwitch_SET_SWITCH_SETTINGS:
        {
            /* Retrieve data from user space */
            copy_from_user(&scartSwitchData, (phStbScartSwitch_data_t *)parameters, sizeof(phStbScartSwitch_data_t));
            /* Set scart switch with current slow blanking and video format */
            phStbScartSwitchSetSwitchSettings(&scartSwitchData);
        }
        break;

        case phStbScartSwitch_GET_DEVICE_ID:
        {
            /* Retrieve device ID */
            phStbScartSwitchGetDeviceId(&deviceId);
            /* Transfer data to user space */
            copy_to_user((uint8_t*)parameters, &deviceId, sizeof(uint8_t));
        }
        break;

        /* For unimplemented IOCTL */
        default:
        {
            dprintk("%s :Unknown IOCTL command (%d)\n", PH_STB_SCART_SWITCH_DESCRIPTION, command);
            ret = -EINVAL;
        }
    }
    return ret;
}


/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetVolume                                     */
/*                                                                            */
/* DESCRIPTION: Set volume level.                                             */
/*                                                                            */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetVolume(phStbScartSwitchScartId_t kScartNumber,
                                  uint8_t kVolume)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting output mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetVolume(kScartNumber, kVolume);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetVolume);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchGetVolume                                     */
/*                                                                            */
/* DESCRIPTION: Get volume level.                                             */
/*                                                                            */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchGetVolume(phStbScartSwitchScartId_t kScartNumber,
                                  uint8_t *pVolume)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting output mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.GetVolume(kScartNumber, pVolume);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchGetVolume);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetOutputMode                                 */
/*                                                                            */
/* DESCRIPTION: Set output mode.                                              */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetOutputMode(phStbScartSwitchScartId_t kScartNumber,
                                      phStbScartSwitchOutputMode_t kMode)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting output mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetOutputMode(kScartNumber, kMode);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetOutputMode);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetVideoFormat                                */
/*                                                                            */
/* DESCRIPTION: Set video format (4:3, 16/9).                                 */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetVideoFormat(phStbScartSwitchScartId_t kScartNumber,
                                       phStbScartSwitchVideoFormat_t kFormat)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting video format */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetVideoFormat(kScartNumber, kFormat);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret = 0;
}
EXPORT_SYMBOL(phStbScartSwitchSetVideoFormat);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetSBMode                                     */
/*                                                                            */
/* DESCRIPTION: Set Slow Blanking mode.                                       */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetSBMode(phStbScartSwitchScartId_t kScartNumber,
                                  phStbScartSwitchSBMode_t kMode)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting slow blanking mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetSBMode(kScartNumber, kMode);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetSBMode);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetSBValue                                    */
/*                                                                            */
/* DESCRIPTION: Set Slow Blanking value.                                      */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetSBValue(phStbScartSwitchScartId_t kScartNumber,
                                   phStbScartSwitchSBValue_t kValue)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting slow blanking value */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call matching API function */
        ret = gFunctionList.SetSBValue(kScartNumber, kValue);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetSBValue);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchGetSBValue                                    */
/*                                                                            */
/* DESCRIPTION: Get Slow Blanking mode.                                       */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchGetSBValue(phStbScartSwitchScartId_t kScartNumber,
                                   phStbScartSwitchSBValue_t *pValue)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before retreiving slow blanking mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.GetSBValue(kScartNumber, pValue);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchGetSBValue);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchInstallSBCallback                             */
/*                                                                            */
/* DESCRIPTION: Install callback to manage Slow Blanking interrupt.           */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchInstallSBCallback(phStbScartSwitchScartId_t kScartNumber,
                                          ptmCallback_t pFunc)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before installing slow blanking callback */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.InstallSBCallback(kScartNumber, pFunc);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchInstallSBCallback);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetFBMode                                     */
/*                                                                            */
/* DESCRIPTION: Install callback to manage Slow Blanking interrupt.           */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetFBMode(phStbScartSwitchScartId_t kScartNumber,
                                  phStbScartSwitchFBMode_t kFBMode)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting Fast Blanking mode */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetFBMode(kScartNumber, kFBMode);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetFBMode);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetAudioCommonMute                            */
/*                                                                            */
/* DESCRIPTION: Mute on/off all audio output.                                 */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetAudioCommonMute(phStbScartSwitchAudioCommonMute_t kMute)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before retreiving device ID */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetAudioCommonMute(kMute);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetAudioCommonMute);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetAudioSource                                */
/*                                                                            */
/* DESCRIPTION: Set audio source for TV/VCR.                                  */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetAudioSource(phStbScartSwitchScartId_t kScartNumber,
                                       phStbScartSwitchAudioSource_t kAudioSource)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting audio source */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetAudioSource(kScartNumber, kAudioSource);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetAudioSource);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchGetSwitchSettings                             */
/*                                                                            */
/* DESCRIPTION: Get slow blanking and output mode for TV/VCR.                 */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchGetSwitchSettings(phStbScartSwitch_data_t *pScartSwitchData)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting audio source */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.GetSwitchSettings(pScartSwitchData);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchGetSwitchSettings);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchSetSwitchSettings                             */
/*                                                                            */
/* DESCRIPTION: Set slow blanking and output mode for TV/VCR.                 */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchSetSwitchSettings(phStbScartSwitch_data_t *pScartSwitchData)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before setting audio source */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Call API function */
        ret = gFunctionList.SetSwitchSettings(pScartSwitchData);
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchSetSwitchSettings);

/* -------------------------------------------------------------------------- */
/* FUNCTION:    phStbScartSwitchGetAvSwitchId                                 */
/*                                                                            */
/* DESCRIPTION: Retreive device ID.                                           */
/* RETURN:      tmErrorCode_t                                                 */
/* -------------------------------------------------------------------------- */
int32_t phStbScartSwitchGetDeviceId(uint8_t *Id)
{
    int32_t ret = 0;

    /* Lock access to all driver API (reentrance) */
    up(&gApiReentranceProtectionMutex);

    /* Init must be done before retreiving device ID */
    if (gInitialized == False)
    {
        /* Driver is not initialized */
        ret = -EPERM;
    }
    else
    {
        /* Retreive device ID */
        *Id = gDeviceId;
        ret = TM_OK;
    }

    /* Unlock access to all driver API (reentrance) */
    down(&gApiReentranceProtectionMutex);

    return ret;
}
EXPORT_SYMBOL(phStbScartSwitchGetDeviceId);

module_init(phStbScartSwitch_init);
module_exit(phStbScartSwitch_exit);
MODULE_AUTHOR("Cedric Boudy");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(PH_STB_SCART_SWITCH_DESCRIPTION);
/*============================================================================*/
/*                     END OF FILE                                            */
/*============================================================================*/

