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

#ifndef MDRV_DEMUX_PVR_H
#define MDRV_DEMUX_PVR_H

#include <linux/mutex.h>
#include <linux/dvb/dmx_mtk.h>

#include "mdrv_demux_pvr_trans.h"
#include "mdrv_demux_tee_if.h"
#include "mdrv_demux_fh.h"
#include "mdrv_demux_event.h"

#include "mhal_demux_pvr.h"

enum pvr_state {
	PVR_STATE_FREE,
	PVR_STATE_ALLOC,
	PVR_STATE_START,
	PVR_STATE_STOP,
	PVR_STATE_SUSPEND,
	PVR_STATE_MAX
};

struct pvr_buffer_info {
	void __iomem *vBufAddr;
	u64 pBufAddr, pBufWrite;
	u32 size, packet_len;
	int dmabuf_fd;
};

struct pvr_slot {
	struct kobject kobj;
	struct dmx_fh_mgr fh_mgr;
	struct mdrv_demux_pvr *pvr;
	enum pvr_packet_type rec_type;
	enum pvr_data_trans_mode trans_mode;
	enum pvr_data_trans_type trans_type;
	aesdma_type_t encrypt_type;
	pvr_stream_type_t vcodec_type;
	pvr_data_trans_fn fn;
	bool rec_all;
	enum pvr_state state;
	u16 eng_id, src_path;
	u32 pause_time;
	struct dvb_demux *dvbdemux;
	struct pvr_buffer_info buf_info;
	struct task_struct *rec_task;
};

struct mdrv_demux_pvr {
	struct mdrv_demux_res *res;
	struct mutex pvr_mutex;
	struct pvr_slot *pvr_slot_map;
};

int mdrv_demux_pvr_init(struct platform_device *pdev, struct mdrv_demux_pvr *pvr);
int mdrv_demux_pvr_exit(struct platform_device *pdev, struct mdrv_demux_pvr *pvr);

int mdrv_demux_pvr_suspend(struct mdrv_demux_pvr *pvr);
int mdrv_demux_pvr_resume(struct mdrv_demux_pvr *pvr);

int mdrv_demux_pvr_alloc_engine(struct mdrv_demux_pvr *pvr, u16 path_id);
int mdrv_demux_pvr_free_engine(struct mdrv_demux_pvr *pvr, u16 path_id);
int mdrv_demux_pvr_start_engine(struct mdrv_demux_pvr *pvr, u16 path_id);
int mdrv_demux_pvr_stop_engine(struct mdrv_demux_pvr *pvr, u16 path_id);
int mdrv_demux_pvr_pause_engine(struct mdrv_demux_pvr *pvr, u16 path_id);
int mdrv_demux_pvr_resume_engine(struct mdrv_demux_pvr *pvr, u16 path_id);

int mdrv_demux_pvr_get_state(struct mdrv_demux_pvr *pvr, u16 path_id, dmx_module_state *pstate);
int mdrv_demux_pvr_set_record_cfg(struct mdrv_demux_pvr *pvr,
								  u16 path_id,
								  struct dvr_rec_config *pcfg);
int mdrv_demux_pvr_set_record_time(struct mdrv_demux_pvr *pvr, u16 path_id, u64 timestamp);
int mdrv_demux_pvr_get_record_time(struct mdrv_demux_pvr *pvr, u16 path_id, u64 *ptimestamp);

int mdrv_demux_pvr_subscribe_ev(struct mdrv_demux_pvr *pvr,
	u16 path_id, struct dmx_event_subscription *sub);
int mdrv_demux_pvr_unsubscribe_ev(struct mdrv_demux_pvr *pvr,
	u16 path_id, struct dmx_event_subscription *sub);
int mdrv_demux_pvr_dequeue_ev(struct mdrv_demux_pvr *pvr,
	u16 path_id, struct dmx_event *ev, int non_blocking);

#endif	/* MDRV_DEMUX_PVR_H */
