forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
firmware: cs_dsp: Add memory chunk helpers
Add helpers that can be layered on top of a buffer read from or to be written to the DSP to faciliate accessing datastructures within the DSP memory. These functions handle adding the padding bytes for the DSP, converting to big endian, and packing arbitrary length data. Signed-off-by: Charles Keepax <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
- Loading branch information
1 parent
dea9977
commit a4b9765
Showing
2 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3180,6 +3180,110 @@ static const struct cs_dsp_ops cs_dsp_halo_ops = { | |
.stop_core = cs_dsp_halo_stop_core, | ||
}; | ||
|
||
/** | ||
* cs_dsp_chunk_write() - Format data to a DSP memory chunk | ||
* @ch: Pointer to the chunk structure | ||
* @nbits: Number of bits to write | ||
* @val: Value to write | ||
* | ||
* This function sequentially writes values into the format required for DSP | ||
* memory, it handles both inserting of the padding bytes and converting to | ||
* big endian. Note that data is only committed to the chunk when a whole DSP | ||
* words worth of data is available. | ||
* | ||
* Return: Zero for success, a negative number on error. | ||
*/ | ||
int cs_dsp_chunk_write(struct cs_dsp_chunk *ch, int nbits, u32 val) | ||
{ | ||
int nwrite, i; | ||
|
||
nwrite = min(CS_DSP_DATA_WORD_BITS - ch->cachebits, nbits); | ||
|
||
ch->cache <<= nwrite; | ||
ch->cache |= val >> (nbits - nwrite); | ||
ch->cachebits += nwrite; | ||
nbits -= nwrite; | ||
|
||
if (ch->cachebits == CS_DSP_DATA_WORD_BITS) { | ||
if (cs_dsp_chunk_end(ch)) | ||
return -ENOSPC; | ||
|
||
ch->cache &= 0xFFFFFF; | ||
for (i = 0; i < sizeof(ch->cache); i++, ch->cache <<= BITS_PER_BYTE) | ||
*ch->data++ = (ch->cache & 0xFF000000) >> CS_DSP_DATA_WORD_BITS; | ||
|
||
ch->bytes += sizeof(ch->cache); | ||
ch->cachebits = 0; | ||
} | ||
|
||
if (nbits) | ||
return cs_dsp_chunk_write(ch, nbits, val); | ||
|
||
return 0; | ||
} | ||
EXPORT_SYMBOL_GPL(cs_dsp_chunk_write); | ||
|
||
/** | ||
* cs_dsp_chunk_flush() - Pad remaining data with zero and commit to chunk | ||
* @ch: Pointer to the chunk structure | ||
* | ||
* As cs_dsp_chunk_write only writes data when a whole DSP word is ready to | ||
* be written out it is possible that some data will remain in the cache, this | ||
* function will pad that data with zeros upto a whole DSP word and write out. | ||
* | ||
* Return: Zero for success, a negative number on error. | ||
*/ | ||
int cs_dsp_chunk_flush(struct cs_dsp_chunk *ch) | ||
{ | ||
if (!ch->cachebits) | ||
return 0; | ||
|
||
return cs_dsp_chunk_write(ch, CS_DSP_DATA_WORD_BITS - ch->cachebits, 0); | ||
} | ||
EXPORT_SYMBOL_GPL(cs_dsp_chunk_flush); | ||
|
||
/** | ||
* cs_dsp_chunk_read() - Parse data from a DSP memory chunk | ||
* @ch: Pointer to the chunk structure | ||
* @nbits: Number of bits to read | ||
* | ||
* This function sequentially reads values from a DSP memory formatted buffer, | ||
* it handles both removing of the padding bytes and converting from big endian. | ||
* | ||
* Return: A negative number is returned on error, otherwise the read value. | ||
*/ | ||
int cs_dsp_chunk_read(struct cs_dsp_chunk *ch, int nbits) | ||
{ | ||
int nread, i; | ||
u32 result; | ||
|
||
if (!ch->cachebits) { | ||
if (cs_dsp_chunk_end(ch)) | ||
return -ENOSPC; | ||
|
||
ch->cache = 0; | ||
ch->cachebits = CS_DSP_DATA_WORD_BITS; | ||
|
||
for (i = 0; i < sizeof(ch->cache); i++, ch->cache <<= BITS_PER_BYTE) | ||
ch->cache |= *ch->data++; | ||
|
||
ch->bytes += sizeof(ch->cache); | ||
} | ||
|
||
nread = min(ch->cachebits, nbits); | ||
nbits -= nread; | ||
|
||
result = ch->cache >> ((sizeof(ch->cache) * BITS_PER_BYTE) - nread); | ||
ch->cache <<= nread; | ||
ch->cachebits -= nread; | ||
|
||
if (nbits) | ||
result = (result << nbits) | cs_dsp_chunk_read(ch, nbits); | ||
|
||
return result; | ||
} | ||
EXPORT_SYMBOL_GPL(cs_dsp_chunk_read); | ||
|
||
MODULE_DESCRIPTION("Cirrus Logic DSP Support"); | ||
MODULE_AUTHOR("Simon Trimmer <[email protected]>"); | ||
MODULE_LICENSE("GPL v2"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters