// SPDX-License-Identifier: GPL-2.0
/*
* Intersil ISL7998x analog to MIPI CSI-2 or BT.656 decoder driver.
*
* Copyright (C) 2018-2019 Marek Vasut <marex@denx.de>
* Copyright (C) 2021 Michael Tretter <kernel@pengutronix.de>
*/
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/v4l2-mediabus.h>
#include <linux/videodev2.h>
#include <media/v4l2-async.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-ioctl.h>
/*
* This control allows to activate and deactivate the test pattern on
* selected output channels.
* This value is ISL7998x specific.
*/
#define V4L2_CID_TEST_PATTERN_CHANNELS (V4L2_CID_USER_ISL7998X_BASE + 0)
/*
* This control allows to specify the color of the test pattern.
* This value is ISL7998x specific.
*/
#define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_ISL7998X_BASE + 1)
/*
* This control allows to specify the bar pattern in the test pattern.
* This value is ISL7998x specific.
*/
#define V4L2_CID_TEST_PATTERN_BARS (V4L2_CID_USER_ISL7998X_BASE + 2)
#define ISL7998X_INPUTS 4
#define ISL7998X_REG(page, reg) (((page) << 8) | (reg))
#define ISL7998X_REG_PN_SIZE 256
#define ISL7998X_REG_PN_BASE(n) ((n) * ISL7998X_REG_PN_SIZE)
#define ISL7998X_REG_PX_DEC_PAGE(page) ISL7998X_REG((page), 0xff)
#define ISL7998X_REG_PX_DEC_PAGE_MASK 0xf
#define ISL7998X_REG_P0_PRODUCT_ID_CODE ISL7998X_REG(0, 0x00)
#define ISL7998X_REG_P0_PRODUCT_REV_CODE ISL7998X_REG(0, 0x01)
#define ISL7998X_REG_P0_SW_RESET_CTL ISL7998X_REG(0, 0x02)
#define ISL7998X_REG_P0_IO_BUFFER_CTL ISL7998X_REG(0, 0x03)
#define ISL7998X_REG_P0_IO_BUFFER_CTL_1_1 ISL7998X_REG(0, 0x04)
#define ISL7998X_REG_P0_IO_PAD_PULL_EN_CTL ISL7998X_REG(0, 0x05)
#define ISL7998X_REG_P0_IO_BUFFER_CTL_1_2 ISL7998X_REG(0, 0x06)
#define ISL7998X_REG_P0_VIDEO_IN_CHAN_CTL ISL7998X_REG(0, 0x07)
#define ISL7998X_REG_P0_CLK_CTL_1 ISL7998X_REG(0, 0x08)
#define ISL7998X_REG_P0_CLK_CTL_2 ISL7998X_REG(0, 0x09)
#define ISL7998X_REG_P0_CLK_CTL_3 ISL7998X_REG(0, 0x0a)
#define ISL7998X_REG_P0_CLK_CTL_4 ISL7998X_REG(0, 0x0b)
#define ISL7998X_REG_P0_MPP1_SYNC_CTL ISL7998X_REG(0, 0x0c)
#define ISL7998X_REG_P0_MPP2_SYNC_CTL ISL7998X_REG(0, 0x0d)
#define ISL7998X_REG_P0_IRQ_SYNC_CTL ISL7998X_REG(0, 0x0e)
#define ISL7998X_REG_P0_INTERRUPT_STATUS ISL7998X_REG(0, 0x10)
#define ISL7998X_REG_P0_CHAN_1_IRQ ISL7998X_REG(0, 0x11)
#define ISL7998X_REG_P0_CHAN_2_IRQ ISL7998X_REG(0, 0x12)
#define ISL7998X_REG_P0_CHAN_3_IRQ ISL7998X_REG(0, 0x13)
#define ISL7998X_REG_P0_CHAN_4_IRQ ISL7998X_REG(0, 0x14)
#define ISL7998X_REG_P0_SHORT_DIAG_IRQ ISL7998X_REG(0, 0x15)
#define ISL7998X_REG_P0_CHAN_1_IRQ_EN ISL7998X_REG(0, 0x16)
#define ISL7998X_REG_P0_CHAN_2_IRQ_EN ISL7998X_REG(0, 0x17)
#define ISL7998X_REG_P0_CHAN_3_IRQ_EN ISL7998X_REG(0, 0x18)
#define ISL7998X_REG_P0_CHAN_4_IRQ_EN ISL7998X_REG(0, 0x19)
#define ISL7998X_REG_P0_SHORT_DIAG_IRQ_EN ISL7998X_REG(0, 0x1a)
#define ISL7998X_REG_P0_CHAN_1_STATUS ISL7998X_REG(0, 0x1b)
#define ISL7998X_REG_P0_CHAN_2_STATUS ISL7998X_REG(0, 0x1c)
#define ISL7998X_REG_P0_CHAN_3_STATUS ISL7998X_REG(0, 0x1d)
#define ISL7998X_REG_P0_CHAN_4_STATUS ISL7998X_REG(0, 0x1e)
#define ISL7998X_REG_P0_SHORT_DIAG_STATUS ISL7998X_REG(0, 0x1f)
#define ISL7998X_REG_P0_CLOCK_DELAY ISL7998X_REG(0, 0x20)
#define ISL7998X_REG_PX_DEC_INPUT_FMT(pg) ISL7998X_REG((pg), 0x02)
#define ISL7998X_REG_PX_DEC_STATUS_1(pg) ISL7998X_REG((pg), 0x03)
#define ISL7998X_REG_PX_DEC_STATUS_1_VDLOSS BIT(7)
#define ISL7998X_REG_PX_DEC_STATUS_1_HLOCK BIT(6)
#define ISL7998X_REG_PX_DE
|