blob: 5d24af9291cf08dfe86827d6e60e506d8289f673 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#ifndef __AML_AUDIO_DDR_MANAGER_H_
#define __AML_AUDIO_DDR_MANAGER_H_
#include <linux/device.h>
#include <linux/interrupt.h>
#include <sound/soc.h>
#include "audio_io.h"
#define MEMIF_INT_ADDR_FINISH BIT(0)
#define MEMIF_INT_ADDR_INT BIT(1)
#define MEMIF_INT_COUNT_REPEAT BIT(2)
#define MEMIF_INT_COUNT_ONCE BIT(3)
#define MEMIF_INT_FIFO_ZERO BIT(4)
#define MEMIF_INT_FIFO_DEPTH BIT(5)
#define MEMIF_INT_MASK GENMASK(7, 0)
#define TODDR_FIFO_CNT GENMASK(19, 8)
#define FRDDR_FIFO_CNT GENMASK(17, 8)
#define FIFO_BURST 8
#define FIFO_DEPTH_32K 0x8000
#define FIFO_DEPTH_2K 0x800
#define FIFO_DEPTH_1K 0x400
#define FIFO_DEPTH_512 0x200
#define DDRMAX 4
enum ddr_num {
DDR_A,
DDR_B,
DDR_C,
DDR_D,
DDR_E,
DDR_MAX,
};
enum ddr_types {
LJ_8BITS,
LJ_16BITS,
RJ_16BITS,
LJ_32BITS,
RJ_32BITS,
};
/*
* from tl1, add new source FRATV, FRHDMIRX, LOOPBACK_B, SPDIFIN_LB, VAD
*/
enum toddr_src {
TODDR_INVAL = -1,
TDMIN_A = 0,
TDMIN_B = 1,
TDMIN_C = 2,
SPDIFIN = 3,
PDMIN = 4,
FRATV = 5, /* NONE for axg, g12a, g12b */
TDMIN_LB = 6,
LOOPBACK_A = 7,
FRHDMIRX = 8, /* from tl1 chipset*/
LOOPBACK_B = 9,
SPDIFIN_LB = 10,
EARCRX_DMAC = 11,/* from sm1 chipset */
FRHDMIRX_PAO = 12, /* tm2 */
RESAMPLEA = 13, /* t5 */
RESAMPLEB = 14,
VAD = 15,
PDMIN_B = 16,
TDMINB_LB = 17,
TDMIN_D = 18,
TODDR_SRC_MAX = 19
};
enum resample_idx {
RESAMPLE_A,
RESAMPLE_B
};
enum resample_src {
ASRC_TODDR_A,
ASRC_TODDR_B,
ASRC_TODDR_C,
ASRC_TODDR_D, /* from tl1 chipset */
ASRC_LOOPBACK_A,
ASRC_LOOPBACK_B,
};
enum frddr_dest {
TDMOUT_A,
TDMOUT_B,
TDMOUT_C,
SPDIFOUT_A,
SPDIFOUT_B,
EARCTX_DMAC,
TDMOUT_D,
FRDDR_MAX
};
enum status_sel {
CURRENT_DDR_ADDR,
NEXT_FINISH_ADDR,
COUNT_CURRENT_DDR_ACK,
COUNT_NEXT_FINISH_DDR_ACK,
VAD_WAKEUP_ADDR, /* from tl1, vad */
VAD_FS_ADDR,
VAD_FIFO_CNT,
};
struct toddr_fmt {
unsigned int type;
unsigned int msb;
unsigned int lsb;
unsigned int endian;
unsigned int bit_depth;
unsigned int ch_num;
unsigned int rate;
};
struct toddr_src_conf {
char name[32];
unsigned int val;
unsigned int reg;
unsigned int shift;
unsigned int mask;
};
struct frddr_src_conf {
char name[32];
unsigned int val;
unsigned int reg;
unsigned int shift;
unsigned int mask;
};
struct ddr_chipinfo {
/* INT and Start address is same or separated */
bool int_start_same_addr;
/* force finished */
bool force_finished;
/* same source */
bool same_src_fn;
/* insert channel number */
bool insert_chnum;
/* ddr bus in urgent */
bool ugt;
/* source sel switch to ctrl1
* for toddr, 0: source sel is controlled by ctrl0
* 1: source sel is controlled by ctrl1
* for frddr, 0: source sel is controlled by ctrl0
* 1: source sel is controlled by ctrl2
*/
bool src_sel_ctrl;
/*
* resample source sel switch
* resample : from ctrl0 to ctrl3
* toddr : from ctrl0 to ctrl1
*/
bool asrc_src_sel_ctrl;
/* spdif in 32bit, only support left justified */
bool asrc_only_left_j;
/* toddr number max
* 0: default, 3 toddr, axg, g12a, g12b
* 4: 4 toddr, tl1
*/
int fifo_num;
unsigned int fifo_depth;
/* power detect or VAD
* 0: disabled
* 1: power detect
* 2: vad
*/
int wakeup;
bool chnum_sync;
bool burst_finished_flag;
struct toddr_src_conf *to_srcs;
struct toddr_src_conf *fr_srcs;
};
struct toddr {
struct device *dev;
unsigned int resample: 1;
unsigned int ext_signed: 1;
unsigned int reg_base;
struct toddr_fmt fmt;
unsigned int start_addr;
unsigned int end_addr;
unsigned int threshold;
enum toddr_src src;
unsigned int fifo_id;
int is_lb; /* check whether for loopback */
int irq;
bool in_use: 1;
struct aml_audio_controller *actrl;
struct ddr_chipinfo *chipinfo;
};
enum status {
DISABLED,
READY, /* controls has set enable, but ddr is not in running */
RUNNING,
};
struct toddr_attach {
bool enable;
enum resample_idx id;
int status;
/* which module should be attached,
* check which toddr in use should be attached
*/
enum toddr_src attach_module;
int resample_version;
struct mutex lock; /* device lock */
};
struct frddr_attach {
bool enable;
int status;
/* which module for attach ,
* check which frddr in use should be added
*/
enum frddr_dest attach_module;
};
struct frddr {
struct device *dev;
enum frddr_dest dest;
/* dest for same source, whether enable */
enum frddr_dest ss_dest;
bool ss_en;
enum frddr_dest ss2_dest;
bool ss2_en;
struct aml_audio_controller *actrl;
unsigned int reg_base;
enum ddr_num fifo_id;
unsigned int channels;
unsigned int rate;
unsigned int msb;
unsigned int type;
int irq;
bool in_use;
struct ddr_chipinfo *chipinfo;
bool reserved;
};
struct ddr_info {
unsigned int toddr_addr;
unsigned int frddr_addr;
char *toddr_name;
char *frddr_name;
};
/* to ddrs */
struct toddr *fetch_toddr_by_src(int toddr_src);
struct toddr *aml_audio_register_toddr(struct device *dev,
struct aml_audio_controller *actrl,
irq_handler_t handler, void *data);
int aml_audio_unregister_toddr(struct device *dev, void *data);
void audio_toddr_irq_enable(struct toddr *to, bool en);
int aml_toddr_set_buf(struct toddr *to, unsigned int start,
unsigned int end);
int aml_toddr_set_buf_startaddr(struct toddr *to, unsigned int start);
int aml_toddr_set_buf_endaddr(struct toddr *to, unsigned int end);
int aml_toddr_set_intrpt(struct toddr *to, unsigned int intrpt);
unsigned int aml_toddr_get_position(struct toddr *to);
unsigned int aml_toddr_get_addr(struct toddr *to, enum status_sel sel);
void aml_toddr_select_src(struct toddr *to, enum toddr_src);
void aml_toddr_enable(struct toddr *to, bool enable);
void aml_toddr_set_fifos(struct toddr *to, unsigned int threshold);
void aml_toddr_force_finish(struct toddr *to);
void aml_toddr_set_format(struct toddr *to, struct toddr_fmt *fmt);
unsigned int aml_toddr_get_status(struct toddr *to);
unsigned int aml_toddr_get_fifo_cnt(struct toddr *to);
void aml_toddr_ack_irq(struct toddr *to, int status);
void aml_toddr_insert_chanum(struct toddr *to);
unsigned int aml_toddr_read(struct toddr *to);
void aml_toddr_write(struct toddr *to, unsigned int val);
unsigned int aml_toddr_read1(struct toddr *to);
void aml_toddr_write1(struct toddr *to, unsigned int val);
unsigned int aml_toddr_read_status2(struct toddr *to);
bool aml_toddr_burst_finished(struct toddr *to);
/* resample */
void aml_set_resample(enum resample_idx id,
bool enable, enum toddr_src resample_module);
/* power detect */
void aml_pwrdet_enable(bool enable, int pwrdet_module);
/* Voice Activity Detection */
void aml_set_vad(bool enable, int module);
/* from ddrs */
struct frddr *fetch_frddr_by_src(int frddr_src);
struct frddr *aml_audio_register_frddr(struct device *dev,
struct aml_audio_controller *actrl,
irq_handler_t handler, void *data, bool rvd_dst);
int aml_audio_unregister_frddr(struct device *dev, void *data);
int aml_frddr_set_buf(struct frddr *fr, unsigned int start,
unsigned int end);
int aml_frddr_set_intrpt(struct frddr *fr, unsigned int intrpt);
unsigned int aml_frddr_get_position(struct frddr *fr);
void aml_frddr_enable(struct frddr *fr, bool enable);
void aml_frddr_select_dst(struct frddr *fr, enum frddr_dest);
void aml_frddr_select_dst_ss(struct frddr *fr,
enum frddr_dest dst, int sel, bool enable);
int aml_check_sharebuffer_valid(struct frddr *fr, int ss_sel);
void aml_frddr_set_fifos(struct frddr *fr,
unsigned int depth, unsigned int threshold);
unsigned int aml_frddr_get_fifo_id(struct frddr *fr);
void aml_frddr_set_format(struct frddr *fr,
unsigned int chnum,
unsigned int rate,
unsigned int msb,
unsigned int frddr_type);
void aml_frddr_reset(struct frddr *fr, int offset);
/* audio eq drc */
void aml_set_aed(bool enable, int aed_module);
void aml_aed_top_enable(struct frddr *fr, bool enable);
void frddr_init_without_mngr(unsigned int frddr_index, unsigned int src0_sel);
void frddr_deinit_without_mngr(unsigned int frddr_index);
enum toddr_src toddr_src_get(void);
const char *toddr_src_get_str(enum toddr_src idx);
int frddr_src_get(void);
const char *frddr_src_get_str(int idx);
int card_add_ddr_kcontrols(struct snd_soc_card *card);
void pm_audio_set_suspend(bool is_suspend);
bool pm_audio_is_suspend(void);
void aml_frddr_check(struct frddr *fr);
void aml_aed_set_frddr_reserved(void);
void get_toddr_bits_config(enum toddr_src src,
int bit_depth, int *msb, int *lsb);
int aml_check_and_release_sharebuffer(struct frddr *fr, enum frddr_dest ss_sel);
#endif