ASoC: sprd: Add Spreadtrum multi-channel data transfer support

On Spreadtrum platform, the audio subsystem will use the multi-channel
data transfer controller to transfer sound stream between audio subsystem
and other AP/CP subsystem.

It can support 10 DAC channel and 10 ADC channel, and each channel has
512 bytes depth data fifo. Moreover each channel can be used DMA mode
or interrupt mode to transfer data.

Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Baolin Wang 2019-04-23 10:26:22 +08:00 committed by Mark Brown
parent c634d3ffc6
commit d7bff893e0
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
4 changed files with 1128 additions and 0 deletions

View File

@ -5,3 +5,11 @@ config SND_SOC_SPRD
help
Say Y or M if you want to add support for codecs attached to
the Spreadtrum SoCs' Audio interfaces.
config SND_SOC_SPRD_MCDT
bool "Spreadtrum multi-channel data transfer support"
depends on SND_SOC_SPRD
help
Say y here to enable multi-channel data transfer support. It
is used for sound stream transmission between audio subsystem
and other AP/CP subsystem.

View File

@ -4,3 +4,5 @@
snd-soc-sprd-platform-objs := sprd-pcm-dma.o sprd-pcm-compress.o
obj-$(CONFIG_SND_SOC_SPRD) += snd-soc-sprd-platform.o
obj-$(CONFIG_SND_SOC_SPRD_MCDT) += sprd-mcdt.o

1011
sound/soc/sprd/sprd-mcdt.c Normal file

File diff suppressed because it is too large Load Diff

107
sound/soc/sprd/sprd-mcdt.h Normal file
View File

@ -0,0 +1,107 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef __SPRD_MCDT_H
#define __SPRD_MCDT_H
enum sprd_mcdt_channel_type {
SPRD_MCDT_DAC_CHAN,
SPRD_MCDT_ADC_CHAN,
SPRD_MCDT_UNKNOWN_CHAN,
};
enum sprd_mcdt_dma_chan {
SPRD_MCDT_DMA_CH0,
SPRD_MCDT_DMA_CH1,
SPRD_MCDT_DMA_CH2,
SPRD_MCDT_DMA_CH3,
SPRD_MCDT_DMA_CH4,
};
struct sprd_mcdt_chan_callback {
void (*notify)(void *data);
void *data;
};
/**
* struct sprd_mcdt_chan - this struct represents a single channel instance
* @mcdt: the mcdt controller
* @id: channel id
* @fifo_phys: channel fifo physical address which is used for DMA transfer
* @type: channel type
* @cb: channel fifo interrupt's callback interface to notify the fifo events
* @dma_enable: indicate if use DMA mode to transfer data
* @int_enable: indicate if use interrupt mode to notify users to read or
* write data manually
* @list: used to link into the global list
*
* Note: users should not modify any members of this structure.
*/
struct sprd_mcdt_chan {
struct sprd_mcdt_dev *mcdt;
u8 id;
unsigned long fifo_phys;
enum sprd_mcdt_channel_type type;
enum sprd_mcdt_dma_chan dma_chan;
struct sprd_mcdt_chan_callback *cb;
bool dma_enable;
bool int_enable;
struct list_head list;
};
#ifdef CONFIG_SND_SOC_SPRD_MCDT
struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel,
enum sprd_mcdt_channel_type type);
void sprd_mcdt_free_chan(struct sprd_mcdt_chan *chan);
int sprd_mcdt_chan_write(struct sprd_mcdt_chan *chan, char *tx_buf, u32 size);
int sprd_mcdt_chan_read(struct sprd_mcdt_chan *chan, char *rx_buf, u32 size);
int sprd_mcdt_chan_int_enable(struct sprd_mcdt_chan *chan, u32 water_mark,
struct sprd_mcdt_chan_callback *cb);
void sprd_mcdt_chan_int_disable(struct sprd_mcdt_chan *chan);
int sprd_mcdt_chan_dma_enable(struct sprd_mcdt_chan *chan,
enum sprd_mcdt_dma_chan dma_chan, u32 water_mark);
void sprd_mcdt_chan_dma_disable(struct sprd_mcdt_chan *chan);
#else
struct sprd_mcdt_chan *sprd_mcdt_request_chan(u8 channel,
enum sprd_mcdt_channel_type type)
{
return NULL;
}
void sprd_mcdt_free_chan(struct sprd_mcdt_chan *chan)
{ }
int sprd_mcdt_chan_write(struct sprd_mcdt_chan *chan, char *tx_buf, u32 size)
{
return -EINVAL;
}
int sprd_mcdt_chan_read(struct sprd_mcdt_chan *chan, char *rx_buf, u32 size)
{
return 0;
}
int sprd_mcdt_chan_int_enable(struct sprd_mcdt_chan *chan, u32 water_mark,
struct sprd_mcdt_chan_callback *cb)
{
return -EINVAL;
}
void sprd_mcdt_chan_int_disable(struct sprd_mcdt_chan *chan)
{ }
int sprd_mcdt_chan_dma_enable(struct sprd_mcdt_chan *chan,
enum sprd_mcdt_dma_chan dma_chan, u32 water_mark)
{
return -EINVAL;
}
void sprd_mcdt_chan_dma_disable(struct sprd_mcdt_chan *chan)
{ }
#endif
#endif /* __SPRD_MCDT_H */