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

#ifndef MTK_DSCMB_H
#define MTK_DSCMB_H

#include <media/dvbdev.h>
#include <linux/platform_device.h>
#include <linux/module.h>

#include <linux/dvb/dmx2_mtk.h>
#include "mtk_dmx_internal_if.h"
#include <media/dvb_ca_en50221.h>

#include "drvDSCMB.h"
#include <uapi/linux/dvb/dsc_mtk.h>
#include "mtk_dmx_filter.h"
#include "mtk_dmx_dev.h"

extern struct dvb_adapter *mdrv_get_dvb_adapter(void);


#define IPV6_Len    16
#define MarkReordKeytoken   0x8000
#define MarkLiveKeytoken   0x4000

#define CA_CRTL_SLOT_MAX    80
#define PIDFLT_NUM  256
#define DSC_CB_NUM  4
#define KEYSKOT_NUM 16
#define ERROR      (-1)
#define CA_KEYSLOT (0)


#define dsc_op(fops, op, args...)	\
	((fops.op) ? fops.op(args) : -ENOTTY)


struct mdrv_dscmb_res {
	void __iomem *RIU_vaddr;
	void __iomem *extRIU_vaddr;
};

struct mdrv_dscmb {
	//int irq;
	struct mdrv_dscmb_res *regmaps;
};

struct dscmb_key_reset {
	__u32           eng_id;
	__u32           dscmb_flt_id;
	DSCMB_Key_Type  key_type;
};

struct dscmb_connect_info {
	bool set_tlv_avsrc;
	u16 path_id;
	u16 pid;
	u16 pid_flt_id;
	dmx_purpose_t purpose;
	enum filter_dst_type filter_dst_type;
	u16 fifo_id;
	struct dmx2_ip_addr ip_addr;
};

struct delay_pid_info {
	u16 pid[CA_CRTL_SLOT_MAX];
	struct dmx2_ip_addr ip_addr[CA_CRTL_SLOT_MAX];
	dmx_purpose_t purpose;
	u8  delay_pid_num;
};

struct dsc_ca_crtl_info {
	u16 path_id;
	u8  eng_id;
	u8  dscmb_flt_id;
	bool pass_through;
	bool used;

//use in shared frontend playback filter
	struct delay_pid_info playback_pid_info;

//use in shared frontend record filter
	struct delay_pid_info rec_pid_info;

//use in non shared frontend case (forward compatible)
	struct delay_pid_info pid_info;

	unsigned long long keytoken;
	dmx_purpose_t purpose;
	s8  process_num;

	bool set_tlv_avsrc;
	u16 fifo_id[FILTER_DST_TYPE_MAX];
	bool fifo_id_used[FILTER_DST_TYPE_MAX];
};

enum register_cb {
	DSC_GET_FILTER_ID,
	DSC_SET_CA_CRTL,
	DSC_SET_SECURE_MODE,
	DSC_SET_CRYPTO_TYPE,
	DSC_CB_MAX,
};

struct mtk_dscmb_cb {
	int (*get_filter_id)(struct dmx_query_info *info);
	int (*set_ca_ctrl)(struct dmx_ca_info info);
	int (*set_secure_mode)(struct dmx_secure_info info, dmx_purpose_t purpose);
	int (*set_crypto_type)(struct dmx_crypto_info info);
	int (*get_tlv_path)(struct dmx_tlv_path *info);
	enum filter_dst_type (*get_dst_type)(u16 filter_id);
};

typedef int (*funptr)(void*);

int mtk_dscmb_dev_init(struct platform_device *pdev, struct mtk_dmx2dev *mtkdev);
int mtk_dscmb_dev_exit(struct platform_device *pdev);
void mtk_dscmb_connect_pid(struct dscmb_connect_info connect_info);
int mtk_dscmb_register_cb(struct mtk_dscmb_cb *mtk_dsc_cb);
void mtk_dscmb_disconnect_pid(struct dscmb_connect_info connect_info);
u64 mtk_dscmb_get_keytoken(u16 path_id, dmx_purpose_t purpose);

extern struct dvb_adapter *mdrv_get_dvb_adapter(void);


#define DRVIVER_NAME    "mediatek,dscmb"
enum keytoken_purpose {
	KEY_DTV,
	KEY_PLAYBACK,
	KEY_RECORD,
	KEY_TIMESHIFT,
	KEY_PURPOSE_MAX
};

struct mtk_dvb_dscmb {
	struct platform_device *pdev;
	struct mdrv_dscmb_res resource;
	struct dvb_ca_en50221 ca;
	struct dvb_adapter *adapter;
	struct mdrv_dscmb dscmb;
};



#endif /* MTK_DSCMB_H */
