📄 tmspdo.c
字号:
/*
* Copyright (c) 1998, 1999 by TriMedia Technologies.
*
* +------------------------------------------------------------------+
* | This software is furnished under a license and may only be used |
* | and copied in accordance with the terms and conditions of such |
* | a license and with the inclusion of this copyright notice. This |
* | software or any other copies of this software may not be provided|
* | or otherwise made available to any other person. The ownership |
* | and title of this software is not transferred. |
* | |
* | The information in this software is subject to change without |
* | any prior notice and should not be construed as a commitment by |
* | TriMedia Technologies. |
* | |
* | this code and information is provided "as is" without any |
* | warranty of any kind, either expressed or implied, including but |
* | not limited to the implied warranties of merchantability and/or |
* | fitness for any particular purpose. |
* +------------------------------------------------------------------+
*
* Module name : tmSPDO.c 1.6
*
* Last update : 19:40:53 - 00/11/09
*
* Description :
*
* TriMedia S/PDIF audio output library.
* Supports control and use of TriMedia S/PDIF output hardware
*
* This is part of the TriMedia device libraries.
*
* The SPDO driver relies on the board support package.
*
* Revision :
* Built for the TCS 2.0 release
*
*
*/
#include <tmlib/tmtypes.h>
#include <tm1/tmProcessor.h>
#include <tm1/tmInterrupts.h>
#include <tm1/tmSPDO.h>
#include <tm1/tmSPDOmmio.h>
#include <tm1/tmBoard.h>
#include <tm1/tmAssert.h>
#include <tmlib/dprintf.h> /* for debugging with DP(()) */
#include <tmlib/AppModel.h>
#include <tm1/tmGPIO.h>
#include <string.h>
/*-------------------------------defines-------------------------------------*/
#define SPDO_MAJOR_VERSION 2
#define SPDO_MINOR_VERSION 0
#define SPDO_MAGIC 0x46782987
/*------------------------------types----------------------------------------*/
typedef struct spdoInstanceInfo_t {
UInt32 magic;
spdoInstanceSetup_t setup;
Bool initialized;
unitSelect_t unitName;
boardSPDOConfig_t *boardSPDOConfig;
Int gpioInstance;
} spdoInstVars_t, *pspdoInstVars_t;
typedef struct
{
UInt32 numberOfUnits;
spdoCapabilities_t *unitCapabilities;
} spdoCapabilitiesList_t;
/*------------------------------statics------------------------------------*/
static spdoCapabilitiesList_t spdoCaps =
{
0, /* numberOfUnits */
Null /* array of capabilities */
};
static tmLibdevErr_t prepareCapabilities(void);
/*------------------------------functions------------------------------------*/
/* This code is only executed once. */
static tmLibdevErr_t prepareCapabilities(void)
{
UInt32 numberOfUnits, i;
boardSPDOConfig_t *SPDOConfig;
tmLibdevErr_t err = TMLIBDEV_OK;
AppModel_suspend_scheduling();
if (spdoCaps.unitCapabilities == Null)
{
/* the number of units should not be contained in the board */
/* structure. Indeed, a developer might want to add a new unit */
/* without being able to modify the board config struct, since */
/* (s)he does not have access to the source */
if ((err = spdoGetNumberOfUnits(&numberOfUnits)) != TMLIBDEV_OK)
goto prepareCapabilitiesExit;
if (numberOfUnits == 0)
{
err = TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
goto prepareCapabilitiesExit;
}
spdoCaps.numberOfUnits = numberOfUnits;
spdoCaps.unitCapabilities = (pspdoCapabilities_t) malloc(spdoCaps.numberOfUnits * sizeof(spdoCapabilities_t));
if (spdoCaps.unitCapabilities == Null)
{
err = TMLIBDEV_ERR_MEMALLOC_FAILED;
goto prepareCapabilitiesExit;
}
for (i = 0; i < spdoCaps.numberOfUnits; i++)
{
if (TMLIBDEV_OK != tsaBoardGetSPDO(i, &SPDOConfig))
{
/* this should never happen, since we have just checked the */
/* number of units */
/* FIXME : anyway, the error code should not be not supported */
free(spdoCaps.unitCapabilities);
spdoCaps.unitCapabilities = Null;
err = TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
goto prepareCapabilitiesExit;
}
spdoCaps.unitCapabilities[i].version.majorVersion = SPDO_MAJOR_VERSION;
spdoCaps.unitCapabilities[i].version.minorVersion = SPDO_MINOR_VERSION;
spdoCaps.unitCapabilities[i].version.buildVersion = BUILD_VERSION;
spdoCaps.unitCapabilities[i].numSupportedInstances = 1;
spdoCaps.unitCapabilities[i].numCurrentInstances = 0;
spdoCaps.unitCapabilities[i].audioTypeFormats = SPDOConfig->audioTypeFormats;
spdoCaps.unitCapabilities[i].audioSubtypeFormats = SPDOConfig->audioSubtypeFormats;
spdoCaps.unitCapabilities[i].audioAdapters = SPDOConfig->audioAdapters;
spdoCaps.unitCapabilities[i].maxSRate = SPDOConfig->maxSRate;
spdoCaps.unitCapabilities[i].minSRate = SPDOConfig->minSRate;
spdoCaps.unitCapabilities[i].mmioBase = SPDOConfig->mmioBase;
spdoCaps.unitCapabilities[i].intNumber = SPDOConfig->intNumber;
if (SPDOConfig->codecName != Null)
{
strncpy(spdoCaps.unitCapabilities[i].codecName, SPDOConfig->codecName, DEVICE_NAME_LENGTH);
}
}
}
prepareCapabilitiesExit:
AppModel_resume_scheduling();
return err;
}
/**************************************************************************************/
extern tmLibdevErr_t spdoGetNumberOfUnits(UInt32 *pNumberOfUnits)
{
UInt32 i = 0;
boardSPDOConfig_t *dummyConfig;
tmAssert(pNumberOfUnits, TMLIBDEV_ERR_NULL_PARAMETER);
/* this code is not very fast, since it uses the different layers */
/* we can make it faster by directly accessing the registry, since*/
/* in this function, we do not need the contents of the registry */
/* but only the number of units */
/* one memcpy per call can be avoided */
while (tsaBoardGetSPDO(i, &dummyConfig) == TMLIBDEV_OK)
i++;
*pNumberOfUnits = i;
return TMLIBDEV_OK;
}
/**************************************************************************************/
extern tmLibdevErr_t spdoGetCapabilities(pspdoCapabilities_t * pCap)
{
return spdoGetCapabilitiesM(pCap, unit0);
}
/**************************************************************************************/
extern tmLibdevErr_t spdoGetCapabilitiesM(pspdoCapabilities_t * pCap, unitSelect_t unitName)
{
boardSPDOConfig_t *SPDOConfig;
tmLibdevErr_t rval;
tmAssert(pCap, TMLIBDEV_ERR_NULL_PARAMETER);
rval = prepareCapabilities();
if (rval != TMLIBDEV_OK)
return rval;
if (unitName >= spdoCaps.numberOfUnits)
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
if (TMLIBDEV_OK != tsaBoardGetSPDO(unitName, &SPDOConfig))
{
/* this should never happen, since we have just checked the */
/* number of units */
/* FIXME : anyway, the error code should not be not supported */
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
}
/* Update capabilities, prepareCapabilities() only writes initial values into this struct.
Some of the values can change (depending on the selected input). */
spdoCaps.unitCapabilities[unitName].maxSRate = SPDOConfig->maxSRate;
spdoCaps.unitCapabilities[unitName].minSRate = SPDOConfig->minSRate;
if ((SPDOConfig->codecName != Null))
{
strncpy(spdoCaps.unitCapabilities[unitName].codecName, SPDOConfig->codecName, DEVICE_NAME_LENGTH);
}
*pCap = &spdoCaps.unitCapabilities[unitName];
return TMLIBDEV_OK;
}
/**************************************************************************************/
extern tmLibdevErr_t spdoOpen(Int * instance)
{
return spdoOpenM(instance, unit0);
}
/**************************************************************************************/
extern tmLibdevErr_t spdoOpenM(Int * instance, unitSelect_t unitName)
{
gpioInstanceSetup_t gpioSetup;
tmLibdevErr_t rVal;
pspdoInstVars_t instVars;
boardSPDOConfig_t *spdoBoardConfig;
UInt32 i;
tmAssert(instance != Null, TMLIBDEV_ERR_NULL_PARAMETER);
rVal = tsaBoardGetSPDO(unitName, &spdoBoardConfig);
if (rVal != TMLIBDEV_OK)
return TMLIBDEV_ERR_NOT_AVAILABLE_IN_HW;
AppModel_suspend_scheduling();
/* make sure the capabilities are valid */
rVal = prepareCapabilities();
if (rVal != TMLIBDEV_OK)
goto spdoOpenExit;
if (spdoCaps.unitCapabilities[unitName].numCurrentInstances >=
spdoCaps.unitCapabilities[unitName].numSupportedInstances)
{
rVal = TMLIBDEV_ERR_NO_MORE_INSTANCES;
goto spdoOpenExit;
}
rVal = intOpen(spdoBoardConfig->intNumber);
if (rVal != TMLIBDEV_OK)
{
goto spdoOpenExit;
}
spdoCaps.unitCapabilities[unitName].numCurrentInstances++;
/* allocate and initialize instVars struct */
instVars = (pspdoInstVars_t) malloc(sizeof(spdoInstVars_t));
if (instVars == Null)
{
rVal = TMLIBDEV_ERR_MEMALLOC_FAILED;
intClose(spdoBoardConfig->intNumber);
goto spdoOpenExit;
}
instVars->magic = SPDO_MAGIC;
instVars->unitName = unitName;
instVars->boardSPDOConfig = spdoBoardConfig;
instVars->initialized = False;
if (gpioOpen(&(instVars->gpioInstance)) == TMLIBDEV_OK)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -