343 lines
9.0 KiB
C
343 lines
9.0 KiB
C
/**
|
|
* @file sdrv_pdm.h
|
|
* @brief SemiDrive pdm driver header file.
|
|
*
|
|
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifndef SDRV_PDM_H_
|
|
#define SDRV_PDM_H_
|
|
|
|
#include <types.h>
|
|
|
|
#include "sdrv_ckgen.h"
|
|
#include "sdrv_common.h"
|
|
#include "sdrv_dma.h"
|
|
|
|
/* sdrv pdm max transfres */
|
|
#define SDRV_PDM_XFER_NUM_TRANSFERS (4U)
|
|
/* sdrv pdm dma buff size default value */
|
|
#define SDRV_PDM_CHANNELS_COUNT 1
|
|
#define SDRV_PDM_CHANNELS_BYTES (SDRV_PDM_SAMPLE_WIDTH_16BITS / 8)
|
|
#define SDRV_PDM_DMA_PERIOD_FRAME_SIZE 1024 * 4
|
|
#define SDRV_PDM_DMA_PERIOD_SIZE \
|
|
SDRV_PDM_DMA_PERIOD_FRAME_SIZE *SDRV_PDM_CHANNELS_COUNT \
|
|
*SDRV_PDM_CHANNELS_BYTES
|
|
#define SDRV_PDM_DMA_PERIOD_COUNT 2
|
|
#define SDRV_PDM_DMA_BUF_TOTAL_SIZE \
|
|
SDRV_PDM_DMA_PERIOD_SIZE *SDRV_PDM_DMA_PERIOD_COUNT
|
|
|
|
/**
|
|
* @brief pdm channel
|
|
*
|
|
*/
|
|
typedef enum sdrv_pdm_channel {
|
|
SDRV_PDM_CHANNEL_LEFT = 0x00,
|
|
SDRV_PDM_CHANNEL_RIGHT = 0x01,
|
|
SDRV_PDM_CHANNEL_STEREO = 0x02,
|
|
} sdrv_pdm_channel_t;
|
|
|
|
/**
|
|
* @brief pdm gain
|
|
*
|
|
*/
|
|
typedef enum sdrv_pdm_gain {
|
|
SDRV_PDM_GAIN_N6DB = 0x01,
|
|
SDRV_PDM_GAIN_N12DB = 0x02,
|
|
SDRV_PDM_GAIN_N18DB = 0x03,
|
|
SDRV_PDM_GAIN_N24DB = 0x04,
|
|
SDRV_PDM_GAIN_P0DB = 0x05,
|
|
SDRV_PDM_GAIN_P6DB = 0x06,
|
|
SDRV_PDM_GAIN_P12DB = 0x07,
|
|
SDRV_PDM_GAIN_P18DB = 0x08,
|
|
SDRV_PDM_GAIN_P24DB = 0x09,
|
|
} sdrv_pdm_gain_t;
|
|
|
|
/**
|
|
* @brief pdm sample rate
|
|
*
|
|
*/
|
|
typedef enum sdrv_pdm_sample_rate {
|
|
SDRV_PDM_SR_5512 = 5512,
|
|
SDRV_PDM_SR_8000 = 8000,
|
|
SDRV_PDM_SR_11025 = 11025,
|
|
SDRV_PDM_SR_16000 = 16000,
|
|
SDRV_PDM_SR_22050 = 22050,
|
|
SDRV_PDM_SR_32000 = 32000,
|
|
SDRV_PDM_SR_44100 = 44100,
|
|
SDRV_PDM_SR_48000 = 48000,
|
|
SDRV_PDM_SR_64000 = 64000,
|
|
SDRV_PDM_SR_88200 = 88200,
|
|
SDRV_PDM_SR_96000 = 96000,
|
|
SDRV_PDM_SR_176400 = 176400,
|
|
SDRV_PDM_SR_192000 = 192000,
|
|
} sdrv_pdm_sample_rate_t;
|
|
|
|
/**
|
|
* @brief pdm sample width
|
|
*
|
|
*/
|
|
typedef enum sdrv_pdm_sample_width {
|
|
SDRV_PDM_SAMPLE_WIDTH_8BITS = 8,
|
|
SDRV_PDM_SAMPLE_WIDTH_16BITS = 16,
|
|
SDRV_PDM_SAMPLE_WIDTH_24BITS = 24,
|
|
SDRV_PDM_SAMPLE_WIDTH_32BITS = 32,
|
|
} sdrv_pdm_sample_width_t;
|
|
|
|
/**
|
|
* @brief pdm status
|
|
*
|
|
*/
|
|
typedef enum sdrv_pdm_status {
|
|
/* status for Success */
|
|
SDRV_PDM_STATUS_SUCCESS = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_COMMON, 0),
|
|
/* status for Fail */
|
|
SDRV_PDM_STATUS_FAIL = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 1),
|
|
/* status for invalid argument check */
|
|
SDRV_PDM_STATUS_INVALID_PARAMS =
|
|
SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 2),
|
|
/* status for Overrun */
|
|
SDRV_PDM_STATUS_OVERRUN = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 3),
|
|
/* status for underrun */
|
|
SDRV_PDM_STATUS_UNDERRUN = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 4),
|
|
} sdrv_pdm_status_t;
|
|
|
|
/**
|
|
* @brief pdm dma fifo descriptions
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_dma_data {
|
|
/**< pdm fifo base addr */
|
|
paddr_t addr;
|
|
/**< pdm fifo width */
|
|
sdrv_dma_bus_width_e addr_width;
|
|
/**< pdm fifo max transfer size */
|
|
unsigned int max_burst;
|
|
/**< pdm fifo fifo size */
|
|
unsigned int fifo_size;
|
|
} sdrv_pdm_dma_data_t;
|
|
|
|
/**
|
|
* @brief pdm dma buff descriptions
|
|
*
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_dma_buf {
|
|
/**< dma mode ,buffer address */
|
|
uint8_t *addr;
|
|
/**< buffer size */
|
|
int32_t buffer_bytes;
|
|
/**< buffer period_size */
|
|
int32_t period_bytes;
|
|
/**< buffer period count */
|
|
int32_t periods;
|
|
/**< app write pointer during playback, dma read pointer
|
|
during capture */
|
|
uint32_t appl_ptr;
|
|
/**< dma read pointer during playback, dma write pointer
|
|
during capture */
|
|
uint32_t hw_ptr;
|
|
/**< dma buff boundary */
|
|
uint32_t boundary;
|
|
} sdrv_pdm_dma_buf_t;
|
|
|
|
/**
|
|
* @brief pdm transfer
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_transfer {
|
|
/**< audio data addr */
|
|
uint8_t *data;
|
|
/**< audio data length */
|
|
uint32_t length;
|
|
/**< transfer tag */
|
|
uint8_t id;
|
|
} sdrv_pdm_transfer_t;
|
|
|
|
/* @brief sdrv pdm transfer callback function. */
|
|
typedef void (*sdrv_pdm_callback)(sdrv_pdm_transfer_t *transfer, void *context,
|
|
sdrv_pdm_status_t state);
|
|
/**
|
|
* @brief pdm config params
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_params {
|
|
/**< data channels */
|
|
sdrv_pdm_channel_t channels;
|
|
/**< data width */
|
|
sdrv_pdm_sample_width_t sample_width;
|
|
/**< data sample rate */
|
|
sdrv_pdm_sample_rate_t sample_rate;
|
|
/**< data gain */
|
|
sdrv_pdm_gain_t gain;
|
|
/**< dma mode must set, dma generates an interrupt
|
|
transmission data size */
|
|
unsigned int period_bytes;
|
|
/**< dma mode must set, dma generates an interrupt
|
|
transmission data size */
|
|
unsigned int periods;
|
|
/**< dma mode need set dma_buf addr, size=period_count*period_size */
|
|
uint8_t *dma_buff;
|
|
/**< true :dma mode; false:irq mode */
|
|
bool usedma;
|
|
|
|
} sdrv_pdm_params_t;
|
|
|
|
/**
|
|
* @brief pdm capture stream descriptions
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_stream {
|
|
/**< pdm config params */
|
|
sdrv_pdm_params_t params;
|
|
/**< app submit transfer ,max is SDRV_PDM_XFER_NUM_TRANSFERS */
|
|
sdrv_pdm_transfer_t queue[SDRV_PDM_XFER_NUM_TRANSFERS];
|
|
/**< stream status; true : running false:idle */
|
|
bool active;
|
|
/**< app submit enqueue transfer index */
|
|
uint8_t queue_appl;
|
|
/**< hw dequeue transfer index */
|
|
uint8_t queue_hw;
|
|
/**< user callback */
|
|
sdrv_pdm_callback callback;
|
|
/**< user callback context */
|
|
void *context;
|
|
/**< data pack or loose mode in fifo */
|
|
bool pack_mode;
|
|
/**< data format in fifo */
|
|
bool data_lsb;
|
|
/**< pdm request dma transfer when fifo data is <= threshold for capture */
|
|
unsigned threshold;
|
|
/**< dma module instance handle */
|
|
sdrv_dma_t dma_instance;
|
|
/**< dma module channel handle */
|
|
sdrv_dma_channel_t dma_channel;
|
|
/**< dma fifo descriptions */
|
|
sdrv_pdm_dma_data_t dma_data;
|
|
/**< dma mode must set dma_buf addr, size=period_count*period_size */
|
|
sdrv_pdm_dma_buf_t dma_buf;
|
|
bool dma_abort;
|
|
} sdrv_pdm_stream_t;
|
|
|
|
/**
|
|
* @brief pdm board config
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm_config {
|
|
/**< pdm module base addr */
|
|
paddr_t base;
|
|
/**< pdm index in saci */
|
|
int id;
|
|
/**< pdm module irq num */
|
|
uint32_t irq;
|
|
/**< pdm module clk */
|
|
sdrv_ckgen_node_t *clk;
|
|
/**< dma used by pdm, which is dma base addr */
|
|
paddr_t dma_base;
|
|
/**< dma used by pdm, which is dma channel */
|
|
sdrv_dma_channel_id_e dma_channel;
|
|
} sdrv_pdm_config_t;
|
|
|
|
/**
|
|
* @brief pdm module descriptions
|
|
*
|
|
*/
|
|
typedef struct sdrv_pdm {
|
|
/**< pdm board config */
|
|
sdrv_pdm_config_t *config;
|
|
/**< pdm_ctrl work clk rate */
|
|
uint32_t clk_rate;
|
|
/**< pdm capture descriptions */
|
|
sdrv_pdm_stream_t stream;
|
|
} sdrv_pdm_t;
|
|
|
|
/**
|
|
* @brief sdrv pdm controller initialization.
|
|
*
|
|
* This function is used to initialize pdm module
|
|
* function.
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @param [in] cfg sdrv pdm controller configurations
|
|
* @return sdrv_pdm_status_t
|
|
*
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_init(sdrv_pdm_t *pdm, sdrv_pdm_config_t *cfg);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_get_default_params
|
|
*
|
|
* This function is used to get pdm default params
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @param [out] params sdrv pdm params
|
|
* @return sdrv_pdm_status_t
|
|
*
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_get_default_params(sdrv_pdm_t *pdm,
|
|
sdrv_pdm_params_t *params);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_set_params
|
|
*
|
|
* This function is used to set pdm params
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @param [in] params sdrv pdm params
|
|
* @return sdrv_pdm_status_t
|
|
*
|
|
*
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_set_params(sdrv_pdm_t *pdm,
|
|
sdrv_pdm_params_t *params);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_create_transfer
|
|
*
|
|
* This function is used to create transfer and attach transfer callback
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @param [in] callback sdrv pdm transfer callback function.
|
|
* @param [in] context sdrv pdm transfer callback param.
|
|
* @return sdrv_pdm_status_t
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_create_transfer(sdrv_pdm_t *pdm,
|
|
sdrv_pdm_callback callback,
|
|
void *context);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_submit_transfer
|
|
*
|
|
* This function is used to submit transfer, which's max num is
|
|
* SDRV_PDM_XFER_NUM_BUFFERS
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @param [in] transfer sdrv pdm transfer
|
|
* @return sdrv_pdm_status_t
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_submit_transfer(sdrv_pdm_t *pdm,
|
|
sdrv_pdm_transfer_t *transfer);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_start
|
|
*
|
|
* This function is used to start pdm transfer
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @return sdrv_pdm_status_t
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_start(sdrv_pdm_t *pdm);
|
|
|
|
/**
|
|
* @brief sdrv_pdm_stop
|
|
*
|
|
* This function is used to stop pdm transfer
|
|
*
|
|
* @param [in] pdm sdrv pdm controller
|
|
* @return sdrv_pdm_status_t
|
|
*/
|
|
sdrv_pdm_status_t sdrv_pdm_stop(sdrv_pdm_t *pdm);
|
|
|
|
#endif /* SDRV_PDM_H_ */
|