Commit cce13969 authored by Baolin Wang's avatar Baolin Wang Committed by Mark Brown

ASoC: sprd: Add Spreadtrum audio compress offload support

We use 2-stage DMA mode to support Spreadtrum audio compress offload,
which means we use one DMA source channel to transfer data from IRAM
buffer to the DSP fifo to do decoding/encoding, once IRAM buffer is
empty by transferring done, another DMA destination channel will be
triggered automatically to start to transfer data from DDR buffer to
the IRAM buffer. This can reduce the AP subsystem wakeup times to save
power.
Co-developed-by: default avatarYintang Ren <yintang.ren@unisoc.com>
Signed-off-by: default avatarBaolin Wang <baolin.wang@linaro.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent f661fa28
config SND_SOC_SPRD config SND_SOC_SPRD
tristate "SoC Audio for the Spreadtrum SoC chips" tristate "SoC Audio for the Spreadtrum SoC chips"
depends on ARCH_SPRD || COMPILE_TEST depends on ARCH_SPRD || COMPILE_TEST
select SND_SOC_COMPRESS
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to
the Spreadtrum SoCs' Audio interfaces. the Spreadtrum SoCs' Audio interfaces.
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
# Spreadtrum Audio Support # Spreadtrum Audio Support
obj-$(CONFIG_SND_SOC_SPRD) += sprd-pcm-dma.o obj-$(CONFIG_SND_SOC_SPRD) += sprd-pcm-dma.o sprd-pcm-compress.o
This diff is collapsed.
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "sprd-pcm-dma.h" #include "sprd-pcm-dma.h"
#define DRV_NAME "sprd_pcm_dma"
#define SPRD_PCM_DMA_LINKLIST_SIZE 64 #define SPRD_PCM_DMA_LINKLIST_SIZE 64
#define SPRD_PCM_DMA_BRUST_LEN 640 #define SPRD_PCM_DMA_BRUST_LEN 640
...@@ -524,6 +523,7 @@ static void sprd_pcm_free(struct snd_pcm *pcm) ...@@ -524,6 +523,7 @@ static void sprd_pcm_free(struct snd_pcm *pcm)
static const struct snd_soc_component_driver sprd_soc_component = { static const struct snd_soc_component_driver sprd_soc_component = {
.name = DRV_NAME, .name = DRV_NAME,
.ops = &sprd_pcm_ops, .ops = &sprd_pcm_ops,
.compr_ops = &sprd_platform_compr_ops,
.pcm_new = sprd_pcm_new, .pcm_new = sprd_pcm_new,
.pcm_free = sprd_pcm_free, .pcm_free = sprd_pcm_free,
}; };
......
...@@ -3,8 +3,11 @@ ...@@ -3,8 +3,11 @@
#ifndef __SPRD_PCM_DMA_H #ifndef __SPRD_PCM_DMA_H
#define __SPRD_PCM_DMA_H #define __SPRD_PCM_DMA_H
#define DRV_NAME "sprd_pcm_dma"
#define SPRD_PCM_CHANNEL_MAX 2 #define SPRD_PCM_CHANNEL_MAX 2
extern const struct snd_compr_ops sprd_platform_compr_ops;
struct sprd_pcm_dma_params { struct sprd_pcm_dma_params {
dma_addr_t dev_phys[SPRD_PCM_CHANNEL_MAX]; dma_addr_t dev_phys[SPRD_PCM_CHANNEL_MAX];
u32 datawidth[SPRD_PCM_CHANNEL_MAX]; u32 datawidth[SPRD_PCM_CHANNEL_MAX];
...@@ -12,4 +15,44 @@ struct sprd_pcm_dma_params { ...@@ -12,4 +15,44 @@ struct sprd_pcm_dma_params {
const char *chan_name[SPRD_PCM_CHANNEL_MAX]; const char *chan_name[SPRD_PCM_CHANNEL_MAX];
}; };
struct sprd_compr_playinfo {
int total_time;
int current_time;
int total_data_length;
int current_data_offset;
};
struct sprd_compr_params {
u32 direction;
u32 rate;
u32 sample_rate;
u32 channels;
u32 format;
u32 period;
u32 periods;
u32 info_phys;
u32 info_size;
};
struct sprd_compr_callback {
void (*drain_notify)(void *data);
void *drain_data;
};
struct sprd_compr_ops {
int (*open)(int str_id, struct sprd_compr_callback *cb);
int (*close)(int str_id);
int (*start)(int str_id);
int (*stop)(int str_id);
int (*pause)(int str_id);
int (*pause_release)(int str_id);
int (*drain)(int received_total);
int (*set_params)(int str_id, struct sprd_compr_params *params);
};
struct sprd_compr_data {
struct sprd_compr_ops *ops;
struct sprd_pcm_dma_params *dma_params;
};
#endif /* __SPRD_PCM_DMA_H */ #endif /* __SPRD_PCM_DMA_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment