/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#ifndef MTK_MAD_PARSER_H
#define MTK_MAD_PARSER_H
#include <linux/platform_device.h>

#define _BIT_0_     BIT(0)
#define _BIT_1_     BIT(1)
#define _BIT_2_     BIT(2)
#define _BIT_3_     BIT(3)
#define _BIT_4_     BIT(4)
#define _BIT_5_     BIT(5)
#define _BIT_6_     BIT(6)
#define _BIT_7_     BIT(7)
#define _BIT_8_     BIT(8)
#define _BIT_9_     BIT(9)
#define _BIT_10_    BIT(10)
#define _BIT_11_    BIT(11)
#define _BIT_12_    BIT(12)
#define _BIT_13_    BIT(13)
#define _BIT_14_    BIT(14)
#define _BIT_15_    BIT(15)
#define _BIT_16_    BIT(16)
#define _BIT_17_    BIT(17)
#define _BIT_18_    BIT(18)
#define _BIT_19_    BIT(19)
#define _BIT_20_    BIT(20)
#define _BIT_21_    BIT(21)
#define _BIT_22_    BIT(22)
#define _BIT_23_    BIT(23)
#define _BIT_24_    BIT(24)
#define _BIT_25_    BIT(25)
#define _BIT_26_    BIT(26)
#define _BIT_27_    BIT(27)
#define _BIT_28_    BIT(28)
#define _BIT_29_    BIT(29)
#define _BIT_30_    BIT(30)
#define _BIT_31_    BIT(31)

#ifndef BIT
#define BIT(_bit_)					(1 << (_bit_))
#endif

#define PAS_LOG_LEVEL_ERROR			BIT(0)
#define PAS_LOG_LEVEL_WARN			BIT(1)
#define PAS_LOG_LEVEL_INFO			BIT(2)
#define PAS_LOG_LEVEL_DEBUG			BIT(3)

#define MAX_TLV_INFO_TAG     64
#define TLV_SYNC_WORD_BYTES               3
#define MAX_LOAS_FRAME_SIZE               8192

#define MAX_MAD_NUM 4
#define MAX_PTS_NUM 256
#define MAD_META_COUNT 256
#define MAX_TLV_INFO_NUM 256
#define BIT_PER_LINE 16

typedef struct {
	u32     isdbParserLng;    //isdb_parser_lng, unit:byte
	u32     isdbParserSeq;    //isdb_parser_seq
	u32     esWrAccumCnt;
} MAD_TLV_INFO;

typedef struct {
	MAD_TLV_INFO     tlvInfo[MAX_TLV_INFO_TAG];
	u16                     rd_idx;
	u16                     wr_idx;
	u16                     isr_cnt;
	u16                     fail_cnt;
} MAD_TLV_INFO_TBL;

struct audio_parser_ctrl {
	u32 size;		/* size of control parameter, valid when ptr != NULL */
	union {			/* control parameter */
		u32 value;
		void *ptr;
	};
};

typedef enum {
	PAS_RESULT_OK = 0,
	PAS_RESULT_FAIL,
	PAS_RESULT_NOT_INIT,
	PAS_RESULT_INVALID_PARAM,
	PAS_RESULT_ILLEGAL_ACCESS,
} parser_drv_result;

enum audio_parser_control_command {
	/* set control */
	APAS_CMD_SET_CONTROL_BASE = 0x0,
	APAS_CMD_SET_SECURE,	/* in param: value = 0 disable, value = 1 enable, default 0. */

	/* get control */
	APAS_CMD_GET_CONTROL_BASE = 0x1000,
};

extern int mad_pas_log_level;
#define PAS_DEBUG_LOG(_dbgLevel_, _fmt, _args...) { \
	if ((_dbgLevel_ & mad_pas_log_level) != 0) { \
		if (_dbgLevel_ & PAS_LOG_LEVEL_ERROR) { \
			pr_err("<mdbgerr_apas> %s,%u "_fmt, __func__, __LINE__, ##_args); \
		} \
		else if (_dbgLevel_ & PAS_LOG_LEVEL_WARN) { \
			pr_warn("<mdbgwrn_apas> %s,%u "_fmt, __func__, __LINE__, ##_args); \
		} \
		else if (_dbgLevel_ & PAS_LOG_LEVEL_INFO) { \
			pr_info("<mdbginfo_apas> %s,%u "_fmt, __func__, __LINE__, ##_args); \
		} \
		else if (_dbgLevel_ & PAS_LOG_LEVEL_DEBUG) { \
			pr_debug("<mdbgdbg_apas> %s,%u "_fmt, __func__, __LINE__, ##_args); \
		} \
	} \
}
#define MAD_PARSER_ES_MATA_VERSION 0
#define sleeptime 3

#define Extraheader 0x44
#define Extraheader2 0x54
#define Extraheader3 0x32
#define Extraheaderparam0 0x0080
#define Extraheaderparam1 0x0100
#define Extraheaderparam2 0x0380
#define Extraheaderparam3 0x0400
#define Extraheaderparam4 0x0480
#define Extraheaderparam5 0x0500
#define Extraheaderparam6 0x0580
#define Extraheaderparam7 0x0300

#define StreamID1 0x3FC0
#define StreamID2 0x00BD
#define BusrtlengthMask 0xFF03
#define ParserControlMask 0x421E
#define ParserRdataSelMask1 0xFFF0
#define ParserRdataSelMask2 0xF0FF
#define ParserStopMask 0x80

#define Pts_shift 14
#define Pts_shift16 16
#define Pts_shift32 32
#define Bitshift1 1
#define Bitshift2 2
#define Bitshift3 3
#define Bitshift4 4
#define Bitshift16 16
#define BitMask16 0xFFFF
#define BitMask8  0x00FF

#define mad_0 0
#define mad_1 1
#define mad_2 2
#define mad_3 3

#define reg_0 0
#define reg_1 1
#define reg_2 2
#define reg_3 3

#define time_10 10
#define time_15 15
#define time_20 20
#define time_500 500
#define time_1000 1000
#define time_2000 2000
#define time_3000 3000
#define time_5000 5000
#define time_6000 6000
#define time_9000 9000
#define time_10000 10000
#define time_1000000 1000000

int mdrv_pes_parser_mad_init(u16 u16ParserID, struct platform_device *pdev,
	struct mtk_dmx2dev *dmxdev,	struct dvb2_vb2_ctx *vb2_ctx,
	struct mtk_bc_ctx *buf_ctx, enum dmx2_main_filter_type type, struct dmx2_filter *filter);
int mdrv_pes_parser_mad_exit(u16 u16ParserID, struct platform_device *pdev, struct mtk_dmx2dev *dmxdev);
int audio_parser_isr(int irq, void *dev_id);
int audio_parser_get_entry(u16 parser_id, struct dmx2_ts_audio_metadata *p_meta, u32 es_memcnt);
void mdrv_pes_parser_mad_create_thread(u16 u16ParserID);
void MDrv_MAD_Update_PTS(u16 u16ParserID);
u16 _MDrv_MAD_GetStrType(u16 u16ParserID);
void _MDrv_MAD_SetCtrl(void);
int audio_parser_set_control(u16 parser_id,
	enum audio_parser_control_command cmd, struct audio_parser_ctrl *p_ctrl);
int mtk_dtv_mad_parser_create_sysfs_attr(struct mtk_dmx2dev *dmxdev);
int mtk_dtv_mad_parser_remove_sysfs_attr(struct mtk_dmx2dev *dmxdev);
int audio_parser_qbuf(u16 u16ParserID, struct dmx2_buffer *pBuf);
int audio_parser_dqbuf(u16 u16ParserID, struct dmx2_buffer *pBuf);
#endif
