[alsa-devel] [PATCH - ASIHPI 7/8] Support variable size cached control information.
linux at audioscience.com
linux at audioscience.com
Thu Jun 5 06:07:00 CEST 2008
From: Eliot Blennerhassett <linux at audioscience.com>
Signed-off-by: Eliot Blennerhassett <eblennerhassett at audioscience.com>
diff --git a/pci/asihpi/hpi6000.c b/pci/asihpi/hpi6000.c
index ec2ae66..6d1834e 100644
--- a/pci/asihpi/hpi6000.c
+++ b/pci/asihpi/hpi6000.c
@@ -158,6 +158,7 @@ struct hpi_hw_obj {
u16 wDspCrashed; /* when '1' DSP has crashed/died/OTL */
struct hpi_control_cache_single aControlCache[HPI_NMIXER_CONTROLS];
+ struct hpi_control_cache *pCache;
};
static u16 Hpi6000_DspBlockWrite32(
@@ -319,8 +320,7 @@ static void ControlMessage(
}
if (HpiCheckControlCache
- (&((struct hpi_hw_obj *)pao->priv)->
- aControlCache[phm->u.c.wControlIndex],
+ (((struct hpi_hw_obj *)pao->priv)->pCache,
phm, phr))
break;
}
@@ -331,8 +331,8 @@ static void ControlMessage(
break;
case HPI_CONTROL_SET_STATE:
HW_Message(pao, phm, phr);
- HpiSyncControlCache(&((struct hpi_hw_obj *)pao->priv)->
- aControlCache[phm->u.c.wControlIndex], phm, phr);
+ HpiSyncControlCache(
+ ((struct hpi_hw_obj *)pao->priv)->pCache, phm, phr);
break;
default:
phr->wError = HPI_ERROR_INVALID_FUNC;
@@ -431,7 +431,7 @@ void HPI_6000(
/* subsytem messages get executed by every HPI. */
/* All other messages are ignored unless the adapter index matches */
/* an adapter in the HPI */
- HPI_DEBUG_LOG(DEBUG, "O %d,F %d\n", phm->wObject, phm->wFunction);
+ HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction);
/* if Dsp has crashed then do not communicate with it any more */
if (phm->wObject != HPI_OBJ_SUBSYSTEM) {
@@ -573,15 +573,19 @@ static void SubSysDeleteAdapter(
)
{
struct hpi_adapter_obj *pao = NULL;
- void *priv;
+ struct hpi_hw_obj *phw;
pao = HpiFindAdapter(phm->wAdapterIndex);
if (!pao)
return;
- priv = pao->priv;
+ phw = (struct hpi_hw_obj *)pao->priv;
+
+ if (pao->wHasControlCache)
+ HpiFreeControlCache(phw->pCache);
+
HpiDeleteAdapter(pao);
- kfree(priv);
+ kfree(phw);
phr->wError = 0;
}
@@ -594,6 +598,8 @@ static short CreateAdapterObj(
{
short nBootError = 0;
u32 dwDspIndex = 0;
+ u32 dwControlCacheSize = 0;
+ u32 dwControlCacheCount = 0;
struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv;
/* init error reporting */
@@ -693,10 +699,18 @@ static short CreateAdapterObj(
sizeof(struct hpi_control_cache_single) *
HPI_NMIXER_CONTROLS);
/* Read the control cache length to figure out if it is turned on */
- if (HpiReadWord
- (&phw->ado[0], HPI_HIF_ADDR(dwControlCacheSizeInBytes)))
+ dwControlCacheSize = HpiReadWord(&phw->ado[0],
+ HPI_HIF_ADDR(dwControlCacheSizeInBytes));
+ if (dwControlCacheSize) {
+ dwControlCacheCount = HpiReadWord(&phw->ado[0],
+ HPI_HIF_ADDR(dwControlCacheCount));
pao->wHasControlCache = 1;
- else
+
+ phw->pCache = HpiAllocControlCache(dwControlCacheCount,
+ dwControlCacheSize, (struct hpi_control_cache_info *)
+ &phw->aControlCache[0]
+ );
+ } else
pao->wHasControlCache = 0;
HPI_DEBUG_LOG(DEBUG, "Get adapter info ASI%04X index %d\n",
diff --git a/pci/asihpi/hpi6000.h b/pci/asihpi/hpi6000.h
index ba75b0b..348ad8d 100644
--- a/pci/asihpi/hpi6000.h
+++ b/pci/asihpi/hpi6000.h
@@ -45,6 +45,7 @@ struct hpi_hif_6000 {
u32 dwControlCacheIsDirty;
u32 dwControlCacheAddress;
u32 dwControlCacheSizeInBytes;
+ u32 dwControlCacheCount;
};
#define HPI_HIF_PACK_ADAPTER_INFO(adapter, versionMajor, versionMinor) \
diff --git a/pci/asihpi/hpi6205.c b/pci/asihpi/hpi6205.c
index b74add0..ff010a7 100644
--- a/pci/asihpi/hpi6205.c
+++ b/pci/asihpi/hpi6205.c
@@ -126,8 +126,10 @@ struct hpi_hw_obj {
struct consistent_dma_area hControlCache;
struct consistent_dma_area hAsyncEventBuffer;
- struct hpi_control_cache_single *pControlCache;
+/* struct hpi_control_cache_single *pControlCache; */
struct hpi_async_event *pAsyncEventBuffer;
+ struct hpi_control_cache *pCache;
+
};
/*****************************************************************************/
@@ -172,12 +174,6 @@ static void SubSysDeleteAdapter(
struct hpi_response *phr
);
-static void AdapterGetAsserts(
- struct hpi_adapter_obj *pao,
- struct hpi_message *phm,
- struct hpi_response *phr
-);
-
static u16 CreateAdapterObj(
struct hpi_adapter_obj *pao,
u32 *pdwOsErrorCode
@@ -325,9 +321,7 @@ static void ControlMessage(
case HPI_CONTROL_GET_STATE:
if (pao->wHasControlCache) {
rmb(); /* make sure we see updates DMAed from DSP */
- if (HpiCheckControlCache
- (&pHw6205->pControlCache[phm->u.c.
- wControlIndex], phm, phr))
+ if (HpiCheckControlCache(pHw6205->pCache, phm, phr))
break;
}
HW_Message(pao, phm, phr);
@@ -338,9 +332,7 @@ static void ControlMessage(
case HPI_CONTROL_SET_STATE:
HW_Message(pao, phm, phr);
if (pao->wHasControlCache)
- HpiSyncControlCache(&pHw6205->
- pControlCache[phm->u.c.
- wControlIndex], phm, phr);
+ HpiSyncControlCache(pHw6205->pCache, phm, phr);
break;
default:
phr->wError = HPI_ERROR_INVALID_FUNC;
@@ -354,14 +346,7 @@ static void AdapterMessage(
struct hpi_response *phr
)
{
-
switch (phm->wFunction) {
- case HPI_ADAPTER_GET_INFO:
- HW_Message(pao, phm, phr);
- break;
- case HPI_ADAPTER_GET_ASSERT:
- AdapterGetAsserts(pao, phm, phr);
- break;
default:
HW_Message(pao, phm, phr);
break;
@@ -506,6 +491,7 @@ void HPI_6205(
AdapterMessage(pao, phm, phr);
break;
+ case HPI_OBJ_CONTROLEX:
case HPI_OBJ_CONTROL:
ControlMessage(pao, phm, phr);
break;
@@ -694,20 +680,25 @@ static u16 CreateAdapterObj(
* Allocate bus mastering control cache buffer and tell the DSP about it
*/
if (interface->aControlCache.dwNumberOfControls) {
+ void *pControlCacheVirtual;
+
err = HpiOs_LockedMem_Alloc(&pHw6205->hControlCache,
- interface->aControlCache.
- dwNumberOfControls *
- sizeof(struct hpi_control_cache_single),
+ interface->aControlCache.dwSizeInBytes,
pao->Pci.pOsData);
if (!err)
err = HpiOs_LockedMem_GetVirtAddr(&pHw6205->
- hControlCache, (void *)
- &pHw6205->pControlCache);
- if (!err)
- memset((void *)pHw6205->pControlCache, 0,
- interface->aControlCache.
- dwNumberOfControls *
- sizeof(struct hpi_control_cache_single));
+ hControlCache, &pControlCacheVirtual);
+ if (!err) {
+ memset(pControlCacheVirtual, 0,
+ interface->aControlCache.dwSizeInBytes);
+
+ pHw6205->pCache =
+ HpiAllocControlCache(interface->aControlCache.
+ dwNumberOfControls,
+ interface->aControlCache.dwSizeInBytes,
+ (struct hpi_control_cache_info *)
+ pControlCacheVirtual);
+ }
if (!err) {
err = HpiOs_LockedMem_GetPhysAddr(&pHw6205->
hControlCache, &dwPhysAddr);
@@ -718,10 +709,8 @@ static u16 CreateAdapterObj(
if (!err)
pao->wHasControlCache = 1;
else {
- if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache)) {
+ if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache))
HpiOs_LockedMem_Free(&pHw6205->hControlCache);
- pHw6205->pControlCache = NULL;
- }
pao->wHasControlCache = 0;
}
}
@@ -816,7 +805,7 @@ static void DeleteAdapterObj(
if (HpiOs_LockedMem_Valid(&pHw6205->hControlCache)) {
HpiOs_LockedMem_Free(&pHw6205->hControlCache);
- pHw6205->pControlCache = NULL;
+ HpiFreeControlCache(pHw6205->pCache);
}
if (HpiOs_LockedMem_Valid(&pHw6205->hLockedMem)) {
@@ -846,19 +835,6 @@ static void DeleteAdapterObj(
}
/*****************************************************************************/
-/* ADAPTER */
-
-static void AdapterGetAsserts(
- struct hpi_adapter_obj *pao,
- struct hpi_message *phm,
- struct hpi_response *phr
-)
-{
- HW_Message(pao, phm, phr); /*get DSP asserts */
- return;
-}
-
-/*****************************************************************************/
/* OutStream Host buffer functions */
/** Allocate or attach buffer for busmastering
diff --git a/pci/asihpi/hpi6205.h b/pci/asihpi/hpi6205.h
index c5309cb..2c92d59 100644
--- a/pci/asihpi/hpi6205.h
+++ b/pci/asihpi/hpi6205.h
@@ -67,7 +67,7 @@ This is used for dynamic control cache allocation
struct controlcache_6205 {
u32 dwNumberOfControls;
u32 dwPhysicalPCI32address;
- u32 dwSpare;
+ u32 dwSizeInBytes;
};
/*********************************************************************
diff --git a/pci/asihpi/hpicmn.c b/pci/asihpi/hpicmn.c
index 29fe40f..af83a2e 100644
--- a/pci/asihpi/hpicmn.c
+++ b/pci/asihpi/hpicmn.c
@@ -21,6 +21,7 @@
(C) Copyright AudioScience Inc. 1998-2003
*******************************************************************************/
#define SOURCEFILE_NAME "hpicmn.c"
+
#include "hpi.h"
#include "hpidebug.h"
#include "hpicmn.h"
@@ -106,12 +107,16 @@ struct hpi_adapter_obj *HpiFindAdapter(
pao = &adapters.adapter[wAdapterIndex];
if (pao->wAdapterType != 0) {
- HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
- wAdapterIndex);
+ /*
+ HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n",
+ wAdapterIndex);
+ */
return (pao);
} else {
- HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
- wAdapterIndex);
+ /*
+ HPI_DEBUG_LOG(VERBOSE, "No adapter index %d\n",
+ wAdapterIndex);
+ */
return (NULL);
}
}
@@ -171,25 +176,141 @@ static void SubSysGetAdapters(
phr->wError = 0; /* the function completed OK; */
}
-/**
-* CheckControlCache checks if a given struct hpi_control_cache_single control
-* value is in the cache and fills the struct hpi_response accordingly.
-* It returns nonzero if a cache hit occurred, zero otherwise.
+static unsigned int ControlCacheAllocCheck(
+ struct hpi_control_cache *pC
+)
+{
+ unsigned int i;
+ int nCached = 0;
+ if (!pC)
+ return 0;
+ if ((!pC->dwInit) &&
+ (pC->pCache != NULL) &&
+ (pC->dwControlCount) && (pC->dwCacheSizeInBytes)
+ ) {
+ u32 *pMasterCache;
+ pC->dwInit = 1;
+
+ pMasterCache = (u32 *)pC->pCache;
+ for (i = 0; i < pC->dwControlCount; i++) {
+ struct hpi_control_cache_info *info =
+ (struct hpi_control_cache_info *)pMasterCache;
+
+ if (info->ControlType) {
+ pC->pInfo[i] = info;
+ nCached++;
+ } else
+ pC->pInfo[i] = NULL;
+
+ if (info->nSizeIn32bitWords)
+ pMasterCache += info->nSizeIn32bitWords;
+ else
+ pMasterCache +=
+ sizeof(struct
+ hpi_control_cache_single) /
+ sizeof(u32);
+
+ }
+ /*
+ We didn't find anything to cache, so try again later !
+ */
+ if (!nCached)
+ pC->dwInit = 0;
+ }
+ return pC->dwInit;
+}
+
+/** Find a control.
+*/
+static short FindControl(
+ struct hpi_message *phm,
+ struct hpi_control_cache *pCache,
+ struct hpi_control_cache_info **pI,
+ u16 *pwControlIndex
+)
+{
+ if (phm->wObject == HPI_OBJ_CONTROL) {
+ *pwControlIndex = phm->u.c.wControlIndex;
+ } else { /* controlex */
+ *pwControlIndex = phm->u.cx.wControlIndex;
+ HPI_DEBUG_LOG(VERBOSE,
+ "HpiCheckControlCache() ControlEx %d\n",
+ *pwControlIndex);
+ }
+
+ if (!ControlCacheAllocCheck(pCache)) {
+ HPI_DEBUG_LOG(VERBOSE,
+ "ControlCacheAllocCheck() failed. adap%d ci%d\n",
+ phm->wAdapterIndex, *pwControlIndex);
+ return 0;
+ }
+
+ *pI = pCache->pInfo[*pwControlIndex];
+ if (!*pI) {
+ HPI_DEBUG_LOG(VERBOSE,
+ "Uncached Adap %d, Control %d\n",
+ phm->wAdapterIndex, *pwControlIndex);
+ return 0;
+ } else {
+ HPI_DEBUG_LOG(VERBOSE,
+ "HpiCheckControlCache() Type %d\n",
+ (*pI)->ControlType);
+ }
+ return 1;
+}
+
+/** Used by the kernel driver to figure out if a buffer needs mapping.
+ */
+short HpiCheckBufferMapping(
+ struct hpi_control_cache *pCache,
+ struct hpi_message *phm,
+ void **p,
+ unsigned int *pN
+)
+{
+ *pN = 0;
+ *p = NULL;
+ if ((phm->wFunction == HPI_CONTROL_GET_STATE) &&
+ (phm->wObject == HPI_OBJ_CONTROLEX)
+ ) {
+ u16 wControlIndex;
+ struct hpi_control_cache_info *pI;
+
+ if (!FindControl(phm, pCache, &pI, &wControlIndex))
+ return 0;
+ }
+ return 0;
+}
+
+/** CheckControlCache checks the cache and fills the struct hpi_response
+* accordingly. It returns one if a cache hit occurred, zero otherwise.
*/
short HpiCheckControlCache(
- struct hpi_control_cache_single *pC,
+ struct hpi_control_cache *pCache,
struct hpi_message *phm,
struct hpi_response *phr
)
{
short found = 1;
- /* if the control type in the cache is non-zero then */
- /* we have cached control information to process */
+ u16 wControlIndex;
+ struct hpi_control_cache_info *pI;
+ struct hpi_control_cache_single *pC;
+
+ if (!FindControl(phm, pCache, &pI, &wControlIndex))
+ return 0;
+
phr->wSize =
sizeof(struct hpi_response_header) +
sizeof(struct hpi_control_res);
phr->wError = 0;
- switch (pC->ControlType) {
+
+ /* pC is the default cached control strucure. May be cast to
+ something else in the following switch statement.
+ */
+ pC = (struct hpi_control_cache_single *)pI;
+
+ switch (pI->ControlType) {
+
case HPI_CONTROL_METER:
if (phm->u.c.wAttribute == HPI_METER_PEAK) {
phr->u.c.anLogValue[0] = pC->u.p.anLogPeak[0];
@@ -198,45 +319,50 @@ short HpiCheckControlCache(
phr->u.c.anLogValue[0] = pC->u.p.anLogRMS[0];
phr->u.c.anLogValue[1] = pC->u.p.anLogRMS[1];
} else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_VOLUME:
if (phm->u.c.wAttribute == HPI_VOLUME_GAIN) {
phr->u.c.anLogValue[0] = pC->u.v.anLog[0];
phr->u.c.anLogValue[1] = pC->u.v.anLog[1];
} else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_MULTIPLEXER:
if (phm->u.c.wAttribute == HPI_MULTIPLEXER_SOURCE) {
phr->u.c.dwParam1 = pC->u.x.wSourceNodeType;
phr->u.c.dwParam2 = pC->u.x.wSourceNodeIndex;
} else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_CHANNEL_MODE:
if (phm->u.c.wAttribute == HPI_CHANNEL_MODE_MODE)
phr->u.c.dwParam1 = pC->u.m.wMode;
else
- found = 0; /* signal that message was not cached */
-
+ found = 0;
+ break;
case HPI_CONTROL_LEVEL:
if (phm->u.c.wAttribute == HPI_LEVEL_GAIN) {
phr->u.c.anLogValue[0] = pC->u.l.anLog[0];
phr->u.c.anLogValue[1] = pC->u.l.anLog[1];
} else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_TUNER:
- if (phm->u.c.wAttribute == HPI_TUNER_FREQ)
- phr->u.c.dwParam1 = pC->u.t.dwFreqInkHz;
- else if (phm->u.c.wAttribute == HPI_TUNER_BAND)
- phr->u.c.dwParam1 = pC->u.t.wBand;
- else if ((phm->u.c.wAttribute == HPI_TUNER_LEVEL) &&
- (phm->u.c.dwParam1 == HPI_TUNER_LEVEL_AVERAGE))
- phr->u.c.dwParam1 = pC->u.t.wLevel;
- else
- found = 0; /* signal that message was not cached */
+ {
+ struct hpi_control_cache_single *pCT =
+ (struct hpi_control_cache_single *)pI;
+ if (phm->u.c.wAttribute == HPI_TUNER_FREQ)
+ phr->u.c.dwParam1 = pCT->u.t.dwFreqInkHz;
+ else if (phm->u.c.wAttribute == HPI_TUNER_BAND)
+ phr->u.c.dwParam1 = pCT->u.t.wBand;
+ else if ((phm->u.c.wAttribute == HPI_TUNER_LEVEL) &&
+ (phm->u.c.dwParam1 ==
+ HPI_TUNER_LEVEL_AVERAGE))
+ phr->u.c.dwParam1 = pCT->u.t.wLevel;
+ else
+ found = 0;
+ }
break;
case HPI_CONTROL_AESEBU_RECEIVER:
if (phm->u.c.wAttribute == HPI_AESEBURX_ERRORSTATUS)
@@ -244,26 +370,26 @@ short HpiCheckControlCache(
else if (phm->u.c.wAttribute == HPI_AESEBURX_FORMAT)
phr->u.c.dwParam1 = pC->u.aes3rx.dwSource;
else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_AESEBU_TRANSMITTER:
if (phm->u.c.wAttribute == HPI_AESEBUTX_FORMAT)
phr->u.c.dwParam1 = pC->u.aes3tx.dwFormat;
else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_TONEDETECTOR:
if (phm->u.c.wAttribute == HPI_TONEDETECTOR_STATE)
phr->u.c.dwParam1 = pC->u.tone.wState;
else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_SILENCEDETECTOR:
if (phm->u.c.wAttribute == HPI_SILENCEDETECTOR_STATE) {
phr->u.c.dwParam1 = pC->u.silence.dwState;
phr->u.c.dwParam2 = pC->u.silence.dwCount;
} else
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
case HPI_CONTROL_SAMPLECLOCK:
if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SOURCE)
@@ -278,17 +404,105 @@ short HpiCheckControlCache(
} else if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SAMPLERATE)
phr->u.c.dwParam1 = pC->u.clk.dwSampleRate;
else
- found = 0; /* signal that message was not cached */
+ found = 0;
+ break;
+#ifndef HPI_OS_WIN16 /* SGT - below does not compile in Borland C */
+ case HPI_CONTROL_PAD:
+ {
+ struct hpi_control_cache_pad *pPad =
+ (struct hpi_control_cache_pad *)pC;
+
+ if (!(pPad->dwFieldValidFlags &
+ (1 << HPI_CTL_ATTR_INDEX(phm->u.c.
+ wAttribute)))) {
+ /* attribute not supported */
+ phr->wError =
+ HPI_ERROR_INVALID_CONTROL_ATTRIBUTE;
+ break;
+ }
+
+ if (phm->u.c.wAttribute == HPI_PAD_PROGRAM_ID)
+ phr->u.c.dwParam1 = pPad->dwPI;
+ else if (phm->u.c.wAttribute == HPI_PAD_PROGRAM_TYPE)
+ phr->u.c.dwParam1 = pPad->dwPTY;
+ else {
+ struct attribs {
+ u8 *pData;
+ unsigned int nSize;
+ };
+ struct attribs aDesc[] = {
+ {NULL, 0},
+ /* HPI_PAD_CHANNEL_NAME */
+ {pPad->cChannel, sizeof(pPad->
+ cChannel)}
+ ,
+ /* HPI_PAD_ARTIST */
+ {pPad->cArtist, sizeof(pPad->cArtist)}
+ ,
+ /* HPI_PAD_TITLE */
+ {pPad->cTitle, sizeof(pPad->cTitle)}
+ ,
+ /* HPI_PAD_COMMENT */
+ {pPad->cComment, sizeof(pPad->
+ cComment)}
+ ,
+ };
+
+ const u32 dwAttribute = phm->u.c.wAttribute;
+ const u32 dwIndex =
+ HPI_CTL_ATTR_INDEX(dwAttribute);
+ const u32 dwOffset = phm->u.c.dwParam1;
+ int nStringLength = 0;
+ int nRemainingChars = 0;
+
+ HPI_DEBUG_LOG(VERBOSE, "PADS control\n");
+
+ /* check the field type */
+ HPI_DEBUG_LOG(VERBOSE,
+ "PADS HPI_PADS_ %d\n", dwAttribute);
+
+ switch (dwAttribute) {
+ case HPI_PAD_CHANNEL_NAME:
+ case HPI_PAD_ARTIST:
+ case HPI_PAD_TITLE:
+ case HPI_PAD_COMMENT:
+ break;
+ default:
+ phr->wError = HPI_ERROR_INVALID_FUNC;
+ }
+ if (phr->wError)
+ break;
+
+ nStringLength = strlen(aDesc[dwIndex].pData);
+ if (dwOffset > (unsigned)nStringLength) {
+ phr->wError =
+ HPI_ERROR_INVALID_CONTROL_VALUE;
+ break;
+ }
+ HPI_DEBUG_LOG(VERBOSE,
+ "PADS memcpy (%d), offset %d \n",
+ 8, dwOffset);
+ memcpy(&phr->u.cu.chars8.szData[0],
+ &aDesc[dwIndex].pData[dwOffset], 8);
+ nRemainingChars =
+ nStringLength - dwOffset - 8;
+ if (nRemainingChars < 0)
+ nRemainingChars = 0;
+ phr->u.cu.chars8.dwRemainingChars =
+ nRemainingChars;
+ }
+ }
break;
+#endif
default:
- found = 0; /* signal that message was not cached */
+ found = 0;
break;
}
- if (found == 0)
- HPI_DEBUG_LOG(VERBOSE, "Adap %d, Control %d, "
- "Control type %d, Cached %d\n",
- phm->wAdapterIndex, pC->ControlIndex,
- pC->ControlType, found);
+ if (pI->ControlType && !found)
+ HPI_DEBUG_LOG(VERBOSE,
+ "Uncached Adap %d, Control %d, Control type %d\n",
+ phm->wAdapterIndex, pI->ControlIndex,
+ pI->ControlType);
return found;
}
@@ -300,15 +514,24 @@ Volume and Level return the limited values in the response, so use these
Multiplexer does so use sent values
*/
void HpiSyncControlCache(
- struct hpi_control_cache_single *pC,
+ struct hpi_control_cache *pCache,
struct hpi_message *phm,
struct hpi_response *phr
)
{
- if (phr->wError)
+ u16 wControlIndex;
+ struct hpi_control_cache_single *pC;
+ struct hpi_control_cache_info *pI;
+
+ if (!FindControl(phm, pCache, &pI, &wControlIndex))
return;
- switch (pC->ControlType) {
+ /* pC is the default cached control strucure.
+ May be cast to something else in the following switch statement.
+ */
+ pC = (struct hpi_control_cache_single *)pI;
+
+ switch (pI->ControlType) {
case HPI_CONTROL_VOLUME:
if (phm->u.c.wAttribute == HPI_VOLUME_GAIN) {
pC->u.v.anLog[0] = phr->u.c.anLogValue[0];
@@ -323,8 +546,8 @@ void HpiSyncControlCache(
}
break;
case HPI_CONTROL_CHANNEL_MODE:
- /* mux does not return its setting on Set command. */
- if (phm->u.c.wAttribute == HPI_MULTIPLEXER_SOURCE)
+ /* mode does not return its setting on Set command. */
+ if (phm->u.c.wAttribute == HPI_CHANNEL_MODE_MODE)
pC->u.m.wMode = (u16)phm->u.c.dwParam1;
break;
case HPI_CONTROL_LEVEL:
@@ -340,6 +563,7 @@ void HpiSyncControlCache(
case HPI_CONTROL_AESEBU_RECEIVER:
if (phm->u.c.wAttribute == HPI_AESEBURX_FORMAT)
pC->u.aes3rx.dwSource = phm->u.c.dwParam1;
+ break;
case HPI_CONTROL_SAMPLECLOCK:
if (phm->u.c.wAttribute == HPI_SAMPLECLOCK_SOURCE)
pC->u.clk.wSource = (u16)phm->u.c.dwParam1;
@@ -358,6 +582,35 @@ void HpiSyncControlCache(
break;
}
}
+struct hpi_control_cache *HpiAllocControlCache(
+ const u32 dwNumberOfControls,
+ const u32 dwSizeInBytes,
+ struct hpi_control_cache_info *pDSPControlBuffer
+)
+{
+ struct hpi_control_cache *pCache =
+ kmalloc(sizeof(*pCache), GFP_KERNEL);
+ pCache->dwCacheSizeInBytes = dwSizeInBytes;
+ pCache->dwControlCount = dwNumberOfControls;
+ pCache->pCache = (struct hpi_control_cache_single *)pDSPControlBuffer;
+ pCache->dwInit = 0;
+ pCache->pInfo =
+ kmalloc(sizeof(*pCache->pInfo) * pCache->dwControlCount,
+ GFP_KERNEL);
+ return pCache;
+}
+
+void HpiFreeControlCache(
+ struct hpi_control_cache *pCache
+)
+{
+ if ((pCache->dwInit) && (pCache->pInfo)) {
+ kfree(pCache->pInfo);
+ pCache->pInfo = NULL;
+ pCache->dwInit = 0;
+ kfree(pCache);
+ }
+}
static void SubSysMessage(
struct hpi_message *phm,
diff --git a/pci/asihpi/hpicmn.h b/pci/asihpi/hpicmn.h
index 4b7692a..b0763e2 100644
--- a/pci/asihpi/hpicmn.h
+++ b/pci/asihpi/hpicmn.h
@@ -32,6 +32,18 @@ struct hpi_adapter_obj {
void *priv;
};
+struct hpi_control_cache {
+ u32 dwInit; /**< indicates whether the
+ structures are initialized */
+ u32 dwControlCount;
+ u32 dwCacheSizeInBytes;
+ struct hpi_control_cache_info
+ **pInfo; /**< pointer to allocated memory of
+ lookup pointers. */
+ struct hpi_control_cache_single
+ *pCache; /**< pointer to DSP's control cache. */
+};
+
struct hpi_adapter_obj *HpiFindAdapter(
u16 wAdapterIndex
);
@@ -44,12 +56,22 @@ void HpiDeleteAdapter(
);
short HpiCheckControlCache(
- struct hpi_control_cache_single *pC,
+ struct hpi_control_cache *pC,
struct hpi_message *phm,
struct hpi_response *phr
);
+struct hpi_control_cache *HpiAllocControlCache(
+ const u32 dwNumberOfControls,
+ const u32 dwSizeInBytes,
+ struct hpi_control_cache_info
+ *pDSPControlBuffer
+);
+void HpiFreeControlCache(
+ struct hpi_control_cache *pCache
+);
+
void HpiSyncControlCache(
- struct hpi_control_cache_single *pC,
+ struct hpi_control_cache *pC,
struct hpi_message *phm,
struct hpi_response *phr
);
@@ -57,3 +79,9 @@ u16 HpiValidateResponse(
struct hpi_message *phm,
struct hpi_response *phr
);
+short HpiCheckBufferMapping(
+ struct hpi_control_cache *pCache,
+ struct hpi_message *phm,
+ void **p,
+ unsigned int *pN
+);
--
1.5.4.3
More information about the Alsa-devel
mailing list