/*
   forward-v4l2-io.h - v4l2 driver for SoftLab-NSK Forward video boards

   Copyright (C) 2017 - 2024 SoftLab-NSK <forward@softlab.tv>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef FORWARD_V4L2_IO_H
#define FORWARD_V4L2_IO_H

#include "forward.h"
#include "forward-v4l2.h"
#include "forward-v4l2-ioctl.h"

struct forward_v4l2_io_dev {
	struct forward_v4l2_io *io;
	enum v4l2_buf_type type;
	struct video_device vdev;
	struct v4l2_ctrl_handler ctl;
	struct vb2_queue queue;
	spinlock_t q_slock;
	struct mutex lock;
	struct list_head buffers;
	spinlock_t buffers_slock;
};

struct forward_v4l2_io_buffers {
	bool mapped;
	struct forward_v4l2_buffer *video;
	struct forward_v4l2_buffer *vbi;
};

struct forward_v4l2_io_stats {
	u32 frame_drops;
	u32 no_signal_time;
	u32 hw_noseq_count, sw_noseq_count;
	u64 max_irq_period;
	u64 max_proc_delay;
	u64 max_proc_time;
	u64 max_proc_period;
	u64 data_errors;
	u64 alsa_hw_samples;
	u64 alsa_sw_samples;
	u64 alsa_expected_samples;
	u32 alsa_last_hw_samples;
	u32 alsa_last_sw_samples;
	u32 alsa_resyncs;

	u64 last_irq_time, last_proc_time;
	int hw_last_buf, sw_last_buf;
	u32 alsa_last_hw_samples_p, alsa_last_sw_samples_p;
};

struct forward_v4l2_io {
	struct forward_v4l2 *v4l2;
	void *private;

	enum forward_io_state state;
	int index;
	int number;
	struct mutex lock;
	bool ready;
	wait_queue_head_t wait;
	struct forward_irq_listener irq;

	struct forward_v4l2_io_dev video;
	struct forward_v4l2_io_dev vbi;

	bool cd;
	bool locked;
	struct forward_v4l2_timings timings;
	struct forward_v4l2_timings hw_timings;
	bool hw_interlaced;
	struct v4l2_pix_format format;
	struct v4l2_vbi_format vbi_format;
	enum forward_v4l2_pixfmt_conv format_conv;

	bool interleave;
	bool streaming, toggle_streaming;
	bool asi;
	bool raw;
	int asi_period;
	bool vbi_en;
	bool widescreen;
	enum v4l2_forward_timecode_type atc_type;
	int atc_freq;
	bool clone;
	bool bypass_disabled;
	bool mute;
	bool manual_mute;
	bool watchdog_enabled;

	int sequence, buf_sequence;

	u32 frame_hw_time;

	struct forward_v4l2_io_buffers *mapped_buffers;
	int hw_prev_buffer;
	size_t buffer_map_offset;
	size_t buffer_map_size;

	void *hanc_buffer;
	size_t hanc_buffer_size;

	struct forward_v4l2_io_stats stats;

	struct delayed_work bypass_work;

	struct forward_v4l2_genlock *genlock;
};

int forward_v4l2_io_init(struct forward_v4l2_io *io);
void forward_v4l2_io_deinit(struct forward_v4l2_io *io);

#endif // FORWARD_V4L2_IO_H
