/*
   forward-v4l2-ioctl.h - v4l2 driver controls 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_IOCTL_H
#define FORWARD_V4L2_IOCTL_H

#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>

#define V4L2_CID_USER_FORWARD_BASE (V4L2_CID_USER_BASE | 0x1c00)
#define V4L2_CID_FORWARD_ANALOG_RX_MODE (V4L2_CID_USER_FORWARD_BASE + 1)
#define V4L2_CID_FORWARD_ANALOG_RX_TIMESTAMP (V4L2_CID_USER_FORWARD_BASE + 2)
#define V4L2_CID_FORWARD_ANALOG_RX_TIMECODE (V4L2_CID_USER_FORWARD_BASE + 3)
#define V4L2_CID_FORWARD_BYPASS_DISABLE (V4L2_CID_USER_FORWARD_BASE + 4)
#define V4L2_CID_FORWARD_BYPASS_DISABLE_FORCE (V4L2_CID_USER_FORWARD_BASE + 5)
#define V4L2_CID_FORWARD_WATCHDOG_ENABLE (V4L2_CID_USER_FORWARD_BASE + 6)
#define V4L2_CID_FORWARD_WATCHDOG_KEEP_ALIVE (V4L2_CID_USER_FORWARD_BASE + 7)

#define V4L2_CID_FORWARD_FD2110_STREAM_BPC (V4L2_CID_USER_FORWARD_BASE + 6)
#define V4L2_CID_FORWARD_FD2110_STREAM_COLOR (V4L2_CID_USER_FORWARD_BASE + 7)
#define V4L2_CID_FORWARD_FD2110_STREAM_ADDRESS_STRING (V4L2_CID_USER_FORWARD_BASE + 8)
#define V4L2_CID_FORWARD_FD2110_STREAM_ADDRESS (V4L2_CID_USER_FORWARD_BASE + 9)
#define V4L2_CID_FORWARD_FD2110_STREAM_SOURCE_PORT (V4L2_CID_USER_FORWARD_BASE + 10)
#define V4L2_CID_FORWARD_FD2110_STREAM_PT (V4L2_CID_USER_FORWARD_BASE + 11)
#define V4L2_CID_FORWARD_FD2110_STREAM_SSRC (V4L2_CID_USER_FORWARD_BASE + 12)

#define V4L2_CID_FORWARD_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x1c00)
#define V4L2_CID_FORWARD_ENABLE_VANC (V4L2_CID_FORWARD_IMAGE_SOURCE_CLASS_BASE + 1)

#define V4L2_CID_FORWARD_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x1c00)
#define V4L2_CID_FORWARD_WIDESCREEN (V4L2_CID_FORWARD_DV_CLASS_BASE + 1)
#define V4L2_CID_FORWARD_HW_TIMESTAMP (V4L2_CID_FORWARD_DV_CLASS_BASE + 2)
#define V4L2_CID_FORWARD_FREQUENCY_ADJUST (V4L2_CID_FORWARD_DV_CLASS_BASE + 3)
#define V4L2_CID_FORWARD_ASI_PERIOD (V4L2_CID_FORWARD_DV_CLASS_BASE + 4)
#define V4L2_CID_FORWARD_TIMECODE (V4L2_CID_FORWARD_DV_CLASS_BASE + 5)
#define V4L2_CID_FORWARD_GENLOCK_SOURCE (V4L2_CID_FORWARD_DV_CLASS_BASE + 6)
#define V4L2_CID_FORWARD_GENLOCK_STATE (V4L2_CID_FORWARD_DV_CLASS_BASE + 8)
#define V4L2_CID_FORWARD_GENLOCK_OFFSET (V4L2_CID_FORWARD_DV_CLASS_BASE + 9)
#define V4L2_CID_FORWARD_CLONED_OUTPUT (V4L2_CID_FORWARD_DV_CLASS_BASE + 10)
#define V4L2_CID_FORWARD_MUTE_OUTPUT (V4L2_CID_FORWARD_DV_CLASS_BASE + 11)

struct v4l2_forward_analog_rx_timestamp {
	__u32 valid;
	__u32 timestamp;
	__u32 cur_hw_time;
	__u64 cur_sys_time;
} __attribute__((packed));

struct v4l2_forward_stream_address {
	__u8 ipv6[16];
	__u16 port;
} __attribute__((packed));

struct v4l2_event_forward_timestamp {
	__u32 buffer_sequence;
	__u32 field;
	__u32 eof_timestamp;
	__u32 irq_timestamp;
} __attribute__((packed));

enum v4l2_forward_timecode_type {
	V4L2_FORWARD_TIMECODE_DISABLED = 0,
	V4L2_FORWARD_TIMECODE_LTC = 1,
	V4L2_FORWARD_TIMECODE_VITC = 2,
	V4L2_FORWARD_TIMECODE_ANY = 3
};

enum v4l2_forward_genlock_state {
	V4L_FORWARD_GENLOCK_MASTER = 0, // No genlock
	V4L_FORWARD_GENLOCK_NO_INPUT_SIGNAL = 1, // Genlock enabled, but no signal present
	V4L_FORWARD_GENLOCK_LOCKING = 2, // Frequency locking
	V4L_FORWARD_GENLOCK_LOCKED = 3, // Locked - output is genlocked
	V4L_FORWARD_GENLOCK_HOLDOVER = 4 // Output is genlocked, but input is wrong
};

enum v4l2_forward_genlock_source {
	V4L_FORWARD_GENLOCK_SRC_MASTER = 0,
	V4L_FORWARD_GENLOCK_SRC_ANALOG = 1,
	V4L_FORWARD_GENLOCK_SRC_IN0 = 2,
	V4L_FORWARD_GENLOCK_SRC_IN1 = 3,
	V4L_FORWARD_GENLOCK_SRC_IN2 = 4,
	V4L_FORWARD_GENLOCK_SRC_IN3 = 5,
	V4L_FORWARD_GENLOCK_SRC_IN4 = 6,
	V4L_FORWARD_GENLOCK_SRC_IN5 = 7,
	V4L_FORWARD_GENLOCK_SRC_IN6 = 8,
	V4L_FORWARD_GENLOCK_SRC_IN7 = 9
};

enum v4l2_forward_analog_rx_mode {
	V4L_FORWARD_ANALOG_RX_MODE_GENLOCK = 0,
	V4L_FORWARD_ANALOG_RX_MODE_PPS = 1,
	V4L_FORWARD_ANALOG_RX_MODE_LTC = 2
};

enum v4l2_forward_fd2110_stream_color {
	V4L_FORWARD_FD2110_STREAM_COLOR_YCBCR422 = 0,
	V4L_FORWARD_FD2110_STREAM_COLOR_YCBCR420 = 1,
	V4L_FORWARD_FD2110_STREAM_COLOR_YCBCR444 = 2,
	V4L_FORWARD_FD2110_STREAM_COLOR_RGB = 3
};

enum v4l2_forward_fd2110_stream_bpc {
	V4L_FORWARD_FD2110_STREAM_BPC_8BIT = 0,
	V4L_FORWARD_FD2110_STREAM_BPC_10BIT = 1,
	V4L_FORWARD_FD2110_STREAM_BPC_12BIT = 2
};

#define V4L2_CTRL_TYPE_FORWARD_ANALOG_RX_TIMESTAMP 0x1c00
#define V4L2_CTRL_TYPE_FORWARD_TIMECODE 0x1c01
#define V4L2_CTRL_TYPE_FORWARD_STREAM_ADDRESS 0x1c02

#define V4L2_EVENT_FORWARD_START (V4L2_EVENT_PRIVATE_START | 0x1c1f00)
#define V4L2_EVENT_FORWARD_TIMESTAMP (V4L2_EVENT_FORWARD_START + 0)

#define V4L2_PIX_FMT_V210 v4l2_fourcc('v', '2', '1', '0') /* 21.3  YUV 4:2:2     */
#define V4L2_PIX_FMT_SL_RAW v4l2_fourcc('S', 'L', 'R', 'V') /* 20  SoftLab-NSK Raw Video */
#define V4L2_PIX_FMT_SL_RAW_ASI v4l2_fourcc('S', 'L', 'R', 'A') /* 20  SoftLab-NSK Raw ASI */

#define V4L2_FORWARD_BYPASS_WATCHDOG_PERIOD_MS 500

#define VIDIOC_FORWARD_GET_IO_INDEX _IOR('F', BASE_VIDIOC_PRIVATE + 0, int)

#endif // FORWARD_V4L2_IOCTL_H
