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

#ifndef MDRV_ADAPTER_H
#define MDRV_ADAPTER_H

#define MAX_PROPERTY_DATA_SIZE  32

#include "cfm.h"

/* media links define for dtsi*/
#define LINK_LINE (2)

#define ADAP_CMD_FILEIN_STREAMING_ON	0xAD33
#define ADAP_CMD_CI2_BUFFER_INFO		0xAD34
#define ADAP_CMD_CI2_BUFFER_ACK			0xAD35
#define ADAP_CMD_CI2_STREAMING_STATUS	0xAD36
	#define ADAP_CI2_STREAMING_ON		(1)
	#define ADAP_CI2_STREAMING_OFF		(0)
	#define ADAP_CI2_STREAMING_SOURCE	(1)
	#define ADAP_CI2_STREAMING_SINK		(0)
#define ADAP_CMD_CI2_CAM_REMOVED_CB		0xAD37
#define ADAP_CMD_CIFPGA_SERIAL_MODE		0xAD38

#define time_1000						1000
#define time_1000000					1000000
#define ONE_MB							(1024*1024)
#define ONE_KB							(1024)

enum file_operator {
	FILE_OPEN,
	FILE_WRITE,
	FILE_CLOSE
};

typedef enum {
	LINK_STATE_DISCONNECT,
	LINK_STATE_CONNECT
} link_state_t;

enum link_end {
	LINK_END_SOURCE,
	LINK_END_SINK,
};

struct dvbdev_link {
	// link_notify
	struct dvb_device *remote;
	// link_notify
	struct media_entity *remote_entity;
	link_state_t state;

	// prelink_notify/postlink_notify
	enum link_end end;
};

struct dvbdev_property {
	int result;
	u32 cmd;
	union {
		u32 value;
		u8 data[MAX_PROPERTY_DATA_SIZE];
		struct {
			void *buf;
			u32 len;
		} buffer;
	};
};

struct dvbdev_properties {
	u32 num;
	struct dvbdev_property *props;
};

struct dvbdev_notifier {
	int (*link_notify)(struct dvb_device *dev, struct dvbdev_link *link);
	int (*query_notify)(struct dvb_device *dev, struct dvbdev_properties *prop);
	int (*streaming_event_notify)(struct dvb_device *dev, enum cfm_notify_event_type_t ev_type,
		struct cfm_properties *props, void *notify_data);
	int (*data_ready_notify)(struct dvb_device *dev, void *addr, u32 size, void *notify_data);

	int (*prelink_notify)(struct dvb_device *dev, struct dvbdev_link *link);
	int (*postlink_notify)(struct dvb_device *dev, struct dvbdev_link *link);
};

struct dvb_adapter *mdrv_get_dvb_adapter(void);

struct dvb_device *mdrv_adapter_find_device(enum dvb_device_type type, u32 id);

int mdrv_adapter_register_device_notifier(
	struct dvb_device *dev, struct dvbdev_notifier *notifier);

int mdrv_adapter_unregister_device_notifier(struct dvb_device *dev);

int mdrv_adapter_query_device_params(
	struct dvb_device *dev, struct dvbdev_properties *props);

static inline bool is_ci_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "dvb-ca-en50221"));
}

static inline bool is_ci2_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "dvb-ca-usbcam"));
}

static inline bool is_ca_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "dvb-ca-dscmb"));
}

static inline bool is_ts_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "dvb-demux2"));
}

static inline bool is_tso_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "dvb-mtk-tso"));
}

static inline bool is_cifpga_device(struct media_entity *entity)
{
	if (!entity)
		return false;
	if (!entity->name)
		return false;

	return (!strcmp(entity->name, "mtk-cifpga"));
}

#endif /* MDRV_ADAPTER_H */
