Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit d7bff893 authored by Baolin Wang's avatar Baolin Wang Committed by Mark Brown
Browse files

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: default avatarBaolin Wang <baolin.wang@linaro.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c634d3ff
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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.
+2 −0
Original line number Diff line number Diff line
@@ -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 −0

File added.

Preview size limit exceeded, changes collapsed.

+107 −0
Original line number Diff line number Diff line
// 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 */