lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <9209a588-b859-1da7-fd4f-2ab317b5c517@linaro.org>
Date:   Sun, 21 Feb 2021 18:15:16 +0300
From:   Andrey Konovalov <andrey.konovalov@...aro.org>
To:     Robert Foss <robert.foss@...aro.org>, agross@...nel.org,
        bjorn.andersson@...aro.org, todor.too@...il.com,
        mchehab@...nel.org, robh+dt@...nel.org,
        angelogioacchino.delregno@...ainline.org,
        linux-arm-msm@...r.kernel.org, linux-media@...r.kernel.org,
        devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
        AngeloGioacchino Del Regno <kholk11@...il.com>,
        Sakari Ailus <sakari.ailus@....fi>,
        Nicolas Boichat <drinkcat@...omium.org>
Cc:     Rob Herring <robh@...nel.org>, Tomasz Figa <tfiga@...omium.org>,
        Azam Sadiq Pasha Kapatrala Syed <akapatra@...cinc.com>,
        Sarvesh Sridutt <Sarvesh.Sridutt@...rtwirelesscompute.com>,
        Laurent Pinchart <laurent.pinchart@...asonboard.com>,
        Jonathan Marek <jonathan@...ek.ca>
Subject: Re: [PATCH v5 09/22] media: camss: Refactor CSID HW version support

Hi Robert,

Thank you for your patch!

Reviewed-by: Andrey Konovalov <andrey.konovalov@...aro.org>

Thanks,
Andrey

On 17.02.2021 14:21, Robert Foss wrote:
> In order to support Qualcomm ISP hardware architectures that diverge
> from older architectures, the CSID subdevice drivers needs to be refactored
> to better abstract the different ISP hardware architectures.
> 
> Signed-off-by: Robert Foss <robert.foss@...aro.org>
> ---
> 
> Changes since v1
>   - kernel test robot: Add missing include, interrupt.h
> 
> Changes since v4
>   - Andrey: Removed whitespace from some includes
>   - Andrey: Removed unused enum
> 
> 
>   drivers/media/platform/qcom/camss/Makefile    |   2 +
>   .../platform/qcom/camss/camss-csid-4-1.c      | 330 ++++++++++
>   .../platform/qcom/camss/camss-csid-4-7.c      | 406 ++++++++++++
>   .../media/platform/qcom/camss/camss-csid.c    | 616 +-----------------
>   .../media/platform/qcom/camss/camss-csid.h    | 126 +++-
>   5 files changed, 890 insertions(+), 590 deletions(-)
>   create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-1.c
>   create mode 100644 drivers/media/platform/qcom/camss/camss-csid-4-7.c
> 
> diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile
> index 052c4f405fa3..cff388b653ba 100644
> --- a/drivers/media/platform/qcom/camss/Makefile
> +++ b/drivers/media/platform/qcom/camss/Makefile
> @@ -4,6 +4,8 @@
>   qcom-camss-objs += \
>   		camss.o \
>   		camss-csid.o \
> +		camss-csid-4-1.o \
> +		camss-csid-4-7.o \
>   		camss-csiphy-2ph-1-0.o \
>   		camss-csiphy-3ph-1-0.o \
>   		camss-csiphy.o \
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-1.c b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
> new file mode 100644
> index 000000000000..c92077a7f758
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csid-4-1.c
> @@ -0,0 +1,330 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-csid-4-1.c
> + *
> + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
> + *
> + * Copyright (C) 2020 Linaro Ltd.
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +
> +#include "camss-csid.h"
> +#include "camss.h"
> +
> +#define CAMSS_CSID_HW_VERSION		0x0
> +#define CAMSS_CSID_CORE_CTRL_0		0x004
> +#define CAMSS_CSID_CORE_CTRL_1		0x008
> +#define CAMSS_CSID_RST_CMD		0x00c
> +#define CAMSS_CSID_CID_LUT_VC_n(n)	(0x010 + 0x4 * (n))
> +#define CAMSS_CSID_CID_n_CFG(n)		(0x020 + 0x4 * (n))
> +#define CAMSS_CSID_CID_n_CFG_ISPIF_EN	BIT(0)
> +#define CAMSS_CSID_CID_n_CFG_RDI_EN	BIT(1)
> +#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT	4
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8		(0 << 8)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16		(1 << 8)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB	(0 << 9)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB	(1 << 9)
> +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP		(0 << 10)
> +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING	(1 << 10)
> +#define CAMSS_CSID_IRQ_CLEAR_CMD	0x060
> +#define CAMSS_CSID_IRQ_MASK		0x064
> +#define CAMSS_CSID_IRQ_STATUS		0x068
> +#define CAMSS_CSID_TG_CTRL		0x0a0
> +#define CAMSS_CSID_TG_CTRL_DISABLE	0xa06436
> +#define CAMSS_CSID_TG_CTRL_ENABLE	0xa06437
> +#define CAMSS_CSID_TG_VC_CFG		0x0a4
> +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING		0x3ff
> +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING		0x7f
> +#define CAMSS_CSID_TG_DT_n_CGG_0(n)	(0x0ac + 0xc * (n))
> +#define CAMSS_CSID_TG_DT_n_CGG_1(n)	(0x0b0 + 0xc * (n))
> +#define CAMSS_CSID_TG_DT_n_CGG_2(n)	(0x0b4 + 0xc * (n))
> +
> +
> +static const struct csid_format csid_formats[] = {
> +	{
> +		MEDIA_BUS_FMT_UYVY8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_VYUY8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_YUYV8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_YVYU8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_Y10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +};
> +
> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
> +{
> +	struct csid_testgen_config *tg = &csid->testgen;
> +	u32 val;
> +
> +	if (enable) {
> +		struct v4l2_mbus_framefmt *input_format;
> +		const struct csid_format *format;
> +		u8 vc = 0; /* Virtual Channel 0 */
> +		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
> +		u8 dt_shift;
> +
> +		if (tg->enabled) {
> +			/* Config Test Generator */
> +			u32 num_lines, num_bytes_per_line;
> +
> +			input_format = &csid->fmt[MSM_CSID_PAD_SRC];
> +			format = csid_get_fmt_entry(csid->formats, csid->nformats,
> +						    input_format->code);
> +			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
> +			num_lines = input_format->height;
> +
> +			/* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
> +			/* 1:0 VC */
> +			val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
> +				  ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);
> +
> +			/* 28:16 bytes per lines, 12:0 num of lines */
> +			val = ((num_bytes_per_line & 0x1fff) << 16) |
> +				  (num_lines & 0x1fff);
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));
> +
> +			/* 5:0 data type */
> +			val = format->data_type;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));
> +
> +			/* 2:0 output test pattern */
> +			val = tg->mode;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));
> +		} else {
> +			struct csid_phy_config *phy = &csid->phy;
> +
> +			input_format = &csid->fmt[MSM_CSID_PAD_SINK];
> +			format = csid_get_fmt_entry(csid->formats, csid->nformats,
> +						    input_format->code);
> +
> +			val = phy->lane_cnt - 1;
> +			val |= phy->lane_assign << 4;
> +
> +			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);
> +
> +			val = phy->csiphy_id << 17;
> +			val |= 0x9;
> +
> +			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);
> +		}
> +
> +		/* Config LUT */
> +
> +		dt_shift = (cid % 4) * 8;
> +		val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
> +		val &= ~(0xff << dt_shift);
> +		val |= format->data_type << dt_shift;
> +		writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
> +
> +		val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
> +		val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
> +		val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
> +		val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
> +		writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));
> +
> +		if (tg->enabled) {
> +			val = CAMSS_CSID_TG_CTRL_ENABLE;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
> +		}
> +	} else {
> +		if (tg->enabled) {
> +			val = CAMSS_CSID_TG_CTRL_DISABLE;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
> +		}
> +	}
> +}
> +
> +static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
> +{
> +	s32 regval = val - 1;
> +
> +	if (regval > 0 || regval <= CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1)
> +		csid->testgen.mode = regval;
> +
> +	return 0;
> +}
> +
> +static u32 csid_hw_version(struct csid_device *csid)
> +{
> +	u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
> +
> +	dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);
> +
> +	return hw_version;
> +}
> +
> +static irqreturn_t csid_isr(int irq, void *dev)
> +{
> +	struct csid_device *csid = dev;
> +	u32 value;
> +
> +	value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);
> +	writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);
> +
> +	if ((value >> 11) & 0x1)
> +		complete(&csid->reset_complete);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int csid_reset(struct csid_device *csid)
> +{
> +	unsigned long time;
> +
> +	reinit_completion(&csid->reset_complete);
> +
> +	writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);
> +
> +	time = wait_for_completion_timeout(&csid->reset_complete,
> +		msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
> +	if (!time) {
> +		dev_err(csid->camss->dev, "CSID reset timeout\n");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
> +			     unsigned int match_format_idx, u32 match_code)
> +{
> +	if (match_format_idx > 0)
> +		return 0;
> +
> +	return sink_code;
> +}
> +
> +static void csid_subdev_init(struct csid_device *csid)
> +{
> +	csid->formats = csid_formats;
> +	csid->nformats = ARRAY_SIZE(csid_formats);
> +	csid->testgen.modes = csid_testgen_modes;
> +	csid->testgen.nmodes = CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1;
> +}
> +
> +const struct csid_hw_ops csid_ops_4_1 = {
> +	.configure_stream = csid_configure_stream,
> +	.configure_testgen_pattern = csid_configure_testgen_pattern,
> +	.hw_version = csid_hw_version,
> +	.isr = csid_isr,
> +	.reset = csid_reset,
> +	.src_pad_code = csid_src_pad_code,
> +	.subdev_init = csid_subdev_init,
> +};
> diff --git a/drivers/media/platform/qcom/camss/camss-csid-4-7.c b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
> new file mode 100644
> index 000000000000..16a69b140f4e
> --- /dev/null
> +++ b/drivers/media/platform/qcom/camss/camss-csid-4-7.c
> @@ -0,0 +1,406 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * camss-csid-4-7.c
> + *
> + * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
> + *
> + * Copyright (C) 2020 Linaro Ltd.
> + */
> +#include <linux/completion.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +
> +#include "camss-csid.h"
> +#include "camss.h"
> +
> +#define CAMSS_CSID_HW_VERSION		0x0
> +#define CAMSS_CSID_CORE_CTRL_0		0x004
> +#define CAMSS_CSID_CORE_CTRL_1		0x008
> +#define CAMSS_CSID_RST_CMD		0x010
> +#define CAMSS_CSID_CID_LUT_VC_n(n)	(0x014 + 0x4 * (n))
> +#define CAMSS_CSID_CID_n_CFG(n)		(0x024 + 0x4 * (n))
> +#define CAMSS_CSID_CID_n_CFG_ISPIF_EN	BIT(0)
> +#define CAMSS_CSID_CID_n_CFG_RDI_EN	BIT(1)
> +#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT	4
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8		(0 << 8)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16		(1 << 8)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB	(0 << 9)
> +#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB	(1 << 9)
> +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP		(0 << 10)
> +#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING	(1 << 10)
> +#define CAMSS_CSID_IRQ_CLEAR_CMD	0x064
> +#define CAMSS_CSID_IRQ_MASK		0x068
> +#define CAMSS_CSID_IRQ_STATUS		0x06c
> +#define CAMSS_CSID_TG_CTRL		0x0a8
> +#define CAMSS_CSID_TG_CTRL_DISABLE	0xa06436
> +#define CAMSS_CSID_TG_CTRL_ENABLE	0xa06437
> +#define CAMSS_CSID_TG_VC_CFG		0x0ac
> +#define CAMSS_CSID_TG_VC_CFG_H_BLANKING		0x3ff
> +#define CAMSS_CSID_TG_VC_CFG_V_BLANKING		0x7f
> +#define CAMSS_CSID_TG_DT_n_CGG_0(n)	(0x0b4 + 0xc * (n))
> +#define CAMSS_CSID_TG_DT_n_CGG_1(n)	(0x0b8 + 0xc * (n))
> +#define CAMSS_CSID_TG_DT_n_CGG_2(n)	(0x0bc + 0xc * (n))
> +
> +
> +static const struct csid_format csid_formats[] = {
> +	{
> +		MEDIA_BUS_FMT_UYVY8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_VYUY8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_YUYV8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_YVYU8_2X8,
> +		DATA_TYPE_YUV422_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		2,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB8_1X8,
> +		DATA_TYPE_RAW_8BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> +		8,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB12_1X12,
> +		DATA_TYPE_RAW_12BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> +		12,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SBGGR14_1X14,
> +		DATA_TYPE_RAW_14BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> +		14,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGBRG14_1X14,
> +		DATA_TYPE_RAW_14BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> +		14,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SGRBG14_1X14,
> +		DATA_TYPE_RAW_14BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> +		14,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_SRGGB14_1X14,
> +		DATA_TYPE_RAW_14BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> +		14,
> +		1,
> +	},
> +	{
> +		MEDIA_BUS_FMT_Y10_1X10,
> +		DATA_TYPE_RAW_10BIT,
> +		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> +		10,
> +		1,
> +	},
> +};
> +
> +static void csid_configure_stream(struct csid_device *csid, u8 enable)
> +{
> +	struct csid_testgen_config *tg = &csid->testgen;
> +	u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
> +	u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
> +	u32 val;
> +
> +	if (enable) {
> +		struct v4l2_mbus_framefmt *input_format;
> +		const struct csid_format *format;
> +		u8 vc = 0; /* Virtual Channel 0 */
> +		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
> +		u8 dt_shift;
> +
> +		if (tg->enabled) {
> +			/* Config Test Generator */
> +			u32 num_bytes_per_line, num_lines;
> +
> +			input_format = &csid->fmt[MSM_CSID_PAD_SRC];
> +			format = csid_get_fmt_entry(csid->formats, csid->nformats,
> +						    input_format->code);
> +			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
> +			num_lines = input_format->height;
> +
> +			/* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
> +			/* 1:0 VC */
> +			val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
> +				  ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_VC_CFG);
> +
> +			/* 28:16 bytes per lines, 12:0 num of lines */
> +			val = ((num_bytes_per_line & 0x1fff) << 16) |
> +				  (num_lines & 0x1fff);
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_0(0));
> +
> +			/* 5:0 data type */
> +			val = format->data_type;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_1(0));
> +
> +			/* 2:0 output test pattern */
> +			val = tg->mode;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_DT_n_CGG_2(0));
> +		} else {
> +			struct csid_phy_config *phy = &csid->phy;
> +
> +			input_format = &csid->fmt[MSM_CSID_PAD_SINK];
> +			format = csid_get_fmt_entry(csid->formats, csid->nformats,
> +						    input_format->code);
> +
> +			val = phy->lane_cnt - 1;
> +			val |= phy->lane_assign << 4;
> +
> +			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_0);
> +
> +			val = phy->csiphy_id << 17;
> +			val |= 0x9;
> +
> +			writel_relaxed(val, csid->base + CAMSS_CSID_CORE_CTRL_1);
> +		}
> +
> +		/* Config LUT */
> +
> +		dt_shift = (cid % 4) * 8;
> +
> +		val = readl_relaxed(csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
> +		val &= ~(0xff << dt_shift);
> +		val |= format->data_type << dt_shift;
> +		writel_relaxed(val, csid->base + CAMSS_CSID_CID_LUT_VC_n(vc));
> +
> +		val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
> +		val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
> +		val |= format->decode_format << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
> +		val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
> +
> +		if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
> +		     src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
> +		    (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
> +		     src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
> +			val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
> +			val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
> +			val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
> +		}
> +
> +		writel_relaxed(val, csid->base + CAMSS_CSID_CID_n_CFG(cid));
> +
> +		if (tg->enabled) {
> +			val = CAMSS_CSID_TG_CTRL_ENABLE;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
> +		}
> +	} else {
> +		if (tg->enabled) {
> +			val = CAMSS_CSID_TG_CTRL_DISABLE;
> +			writel_relaxed(val, csid->base + CAMSS_CSID_TG_CTRL);
> +		}
> +	}
> +}
> +
> +static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
> +{
> +	s32 regval = val - 1;
> +
> +	if (regval > 0 || regval <= CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7)
> +		csid->testgen.mode = regval;
> +
> +	return 0;
> +}
> +
> +static u32 csid_hw_version(struct csid_device *csid)
> +{
> +	u32 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
> +
> +	dev_dbg(csid->camss->dev, "CSID HW Version = 0x%08x\n", hw_version);
> +
> +	return hw_version;
> +}
> +
> +/*
> + * isr - CSID module interrupt service routine
> + * @irq: Interrupt line
> + * @dev: CSID device
> + *
> + * Return IRQ_HANDLED on success
> + */
> +static irqreturn_t csid_isr(int irq, void *dev)
> +{
> +	struct csid_device *csid = dev;
> +	u32 value;
> +
> +	value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS);
> +	writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD);
> +
> +	if ((value >> 11) & 0x1)
> +		complete(&csid->reset_complete);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +/*
> + * csid_reset - Trigger reset on CSID module and wait to complete
> + * @csid: CSID device
> + *
> + * Return 0 on success or a negative error code otherwise
> + */
> +static int csid_reset(struct csid_device *csid)
> +{
> +	unsigned long time;
> +
> +	reinit_completion(&csid->reset_complete);
> +
> +	writel_relaxed(0x7fff, csid->base + CAMSS_CSID_RST_CMD);
> +
> +	time = wait_for_completion_timeout(&csid->reset_complete,
> +		msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
> +	if (!time) {
> +		dev_err(csid->camss->dev, "CSID reset timeout\n");
> +		return -EIO;
> +	}
> +
> +	return 0;
> +}
> +
> +static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
> +			     unsigned int match_format_idx, u32 match_code)
> +{
> +	switch (sink_code) {
> +	case MEDIA_BUS_FMT_SBGGR10_1X10:
> +	{
> +		u32 src_code[] = {
> +			MEDIA_BUS_FMT_SBGGR10_1X10,
> +			MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
> +		};
> +
> +		return csid_find_code(src_code, ARRAY_SIZE(src_code),
> +				      match_format_idx, match_code);
> +	}
> +	case MEDIA_BUS_FMT_Y10_1X10:
> +	{
> +		u32 src_code[] = {
> +			MEDIA_BUS_FMT_Y10_1X10,
> +			MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
> +		};
> +
> +		return csid_find_code(src_code, ARRAY_SIZE(src_code),
> +				      match_format_idx, match_code);
> +	}
> +	default:
> +		if (match_format_idx > 0)
> +			return 0;
> +
> +		return sink_code;
> +	}
> +}
> +
> +static void csid_subdev_init(struct csid_device *csid)
> +{
> +	csid->formats = csid_formats;
> +	csid->nformats = ARRAY_SIZE(csid_formats);
> +	csid->testgen.modes = csid_testgen_modes;
> +	csid->testgen.nmodes = CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7;
> +}
> +
> +const struct csid_hw_ops csid_ops_4_7 = {
> +	.configure_stream = csid_configure_stream,
> +	.configure_testgen_pattern = csid_configure_testgen_pattern,
> +	.hw_version = csid_hw_version,
> +	.isr = csid_isr,
> +	.reset = csid_reset,
> +	.src_pad_code = csid_src_pad_code,
> +	.subdev_init = csid_subdev_init,
> +};
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
> index be3fe76f3dc3..601bd810f2b0 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.c
> +++ b/drivers/media/platform/qcom/camss/camss-csid.c
> @@ -26,405 +26,35 @@
>   
>   #define MSM_CSID_NAME "msm_csid"
>   
> -#define CAMSS_CSID_HW_VERSION		0x0
> -#define CAMSS_CSID_CORE_CTRL_0		0x004
> -#define CAMSS_CSID_CORE_CTRL_1		0x008
> -#define CAMSS_CSID_RST_CMD(v)		((v) == CAMSS_8x16 ? 0x00c : 0x010)
> -#define CAMSS_CSID_CID_LUT_VC_n(v, n)	\
> -			(((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
> -#define CAMSS_CSID_CID_n_CFG(v, n)	\
> -			(((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
> -#define CAMSS_CSID_CID_n_CFG_ISPIF_EN	BIT(0)
> -#define CAMSS_CSID_CID_n_CFG_RDI_EN	BIT(1)
> -#define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT	4
> -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8		(0 << 8)
> -#define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16		(1 << 8)
> -#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB	(0 << 9)
> -#define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB	(1 << 9)
> -#define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP		(0 << 10)
> -#define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING	(1 << 10)
> -#define CAMSS_CSID_IRQ_CLEAR_CMD(v)	((v) == CAMSS_8x16 ? 0x060 : 0x064)
> -#define CAMSS_CSID_IRQ_MASK(v)		((v) == CAMSS_8x16 ? 0x064 : 0x068)
> -#define CAMSS_CSID_IRQ_STATUS(v)	((v) == CAMSS_8x16 ? 0x068 : 0x06c)
> -#define CAMSS_CSID_TG_CTRL(v)		((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
> -#define CAMSS_CSID_TG_CTRL_DISABLE	0xa06436
> -#define CAMSS_CSID_TG_CTRL_ENABLE	0xa06437
> -#define CAMSS_CSID_TG_VC_CFG(v)		((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
> -#define CAMSS_CSID_TG_VC_CFG_H_BLANKING		0x3ff
> -#define CAMSS_CSID_TG_VC_CFG_V_BLANKING		0x7f
> -#define CAMSS_CSID_TG_DT_n_CGG_0(v, n)	\
> -			(((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
> -#define CAMSS_CSID_TG_DT_n_CGG_1(v, n)	\
> -			(((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
> -#define CAMSS_CSID_TG_DT_n_CGG_2(v, n)	\
> -			(((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
> -
> -#define DATA_TYPE_EMBEDDED_DATA_8BIT	0x12
> -#define DATA_TYPE_YUV422_8BIT		0x1e
> -#define DATA_TYPE_RAW_6BIT		0x28
> -#define DATA_TYPE_RAW_8BIT		0x2a
> -#define DATA_TYPE_RAW_10BIT		0x2b
> -#define DATA_TYPE_RAW_12BIT		0x2c
> -#define DATA_TYPE_RAW_14BIT		0x2d
> -
> -#define DECODE_FORMAT_UNCOMPRESSED_6_BIT	0x0
> -#define DECODE_FORMAT_UNCOMPRESSED_8_BIT	0x1
> -#define DECODE_FORMAT_UNCOMPRESSED_10_BIT	0x2
> -#define DECODE_FORMAT_UNCOMPRESSED_12_BIT	0x3
> -#define DECODE_FORMAT_UNCOMPRESSED_14_BIT	0x8
> -
> -#define CSID_RESET_TIMEOUT_MS 500
> -
> -struct csid_format {
> -	u32 code;
> -	u8 data_type;
> -	u8 decode_format;
> -	u8 bpp;
> -	u8 spp; /* bus samples per pixel */
> -};
> -
> -static const struct csid_format csid_formats_8x16[] = {
> -	{
> -		MEDIA_BUS_FMT_UYVY8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_VYUY8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_YUYV8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_YVYU8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_Y10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -};
> -
> -static const struct csid_format csid_formats_8x96[] = {
> -	{
> -		MEDIA_BUS_FMT_UYVY8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_VYUY8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_YUYV8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_YVYU8_2X8,
> -		DATA_TYPE_YUV422_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		2,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB8_1X8,
> -		DATA_TYPE_RAW_8BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
> -		8,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB12_1X12,
> -		DATA_TYPE_RAW_12BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
> -		12,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SBGGR14_1X14,
> -		DATA_TYPE_RAW_14BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> -		14,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGBRG14_1X14,
> -		DATA_TYPE_RAW_14BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> -		14,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SGRBG14_1X14,
> -		DATA_TYPE_RAW_14BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> -		14,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_SRGGB14_1X14,
> -		DATA_TYPE_RAW_14BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
> -		14,
> -		1,
> -	},
> -	{
> -		MEDIA_BUS_FMT_Y10_1X10,
> -		DATA_TYPE_RAW_10BIT,
> -		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
> -		10,
> -		1,
> -	},
> -};
>   
> -static u32 csid_find_code(u32 *code, unsigned int n_code,
> -			  unsigned int index, u32 req_code)
> +u32 csid_find_code(u32 *codes, unsigned int ncodes,
> +		   unsigned int match_format_idx, u32 match_code)
>   {
>   	int i;
>   
> -	if (!req_code && (index >= n_code))
> +	if (!match_code && (match_format_idx >= ncodes))
>   		return 0;
>   
> -	for (i = 0; i < n_code; i++)
> -		if (req_code) {
> -			if (req_code == code[i])
> -				return req_code;
> +	for (i = 0; i < ncodes; i++)
> +		if (match_code) {
> +			if (codes[i] == match_code)
> +				return match_code;
>   		} else {
> -			if (i == index)
> -				return code[i];
> -		}
> -
> -	return code[0];
> -}
> -
> -static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
> -			     unsigned int index, u32 src_req_code)
> -{
> -	if (csid->camss->version == CAMSS_8x16) {
> -		if (index > 0)
> -			return 0;
> -
> -		return sink_code;
> -	} else if (csid->camss->version == CAMSS_8x96 ||
> -		   csid->camss->version == CAMSS_660) {
> -		switch (sink_code) {
> -		case MEDIA_BUS_FMT_SBGGR10_1X10:
> -		{
> -			u32 src_code[] = {
> -				MEDIA_BUS_FMT_SBGGR10_1X10,
> -				MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
> -			};
> -
> -			return csid_find_code(src_code, ARRAY_SIZE(src_code),
> -					      index, src_req_code);
> -		}
> -		case MEDIA_BUS_FMT_Y10_1X10:
> -		{
> -			u32 src_code[] = {
> -				MEDIA_BUS_FMT_Y10_1X10,
> -				MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
> -			};
> -
> -			return csid_find_code(src_code, ARRAY_SIZE(src_code),
> -					      index, src_req_code);
> +			if (i == match_format_idx)
> +				return codes[i];
>   		}
> -		default:
> -			if (index > 0)
> -				return 0;
>   
> -			return sink_code;
> -		}
> -	} else {
> -		return 0;
> -	}
> +	return codes[0];
>   }
>   
> -static const struct csid_format *csid_get_fmt_entry(
> +const struct csid_format *csid_get_fmt_entry(
>   					const struct csid_format *formats,
> -					unsigned int nformat,
> +					unsigned int nformats,
>   					u32 code)
>   {
>   	unsigned int i;
>   
> -	for (i = 0; i < nformat; i++)
> +	for (i = 0; i < nformats; i++)
>   		if (code == formats[i].code)
>   			return &formats[i];
>   
> @@ -433,28 +63,6 @@ static const struct csid_format *csid_get_fmt_entry(
>   	return &formats[0];
>   }
>   
> -/*
> - * csid_isr - CSID module interrupt handler
> - * @irq: Interrupt line
> - * @dev: CSID device
> - *
> - * Return IRQ_HANDLED on success
> - */
> -static irqreturn_t csid_isr(int irq, void *dev)
> -{
> -	struct csid_device *csid = dev;
> -	enum camss_version ver = csid->camss->version;
> -	u32 value;
> -
> -	value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver));
> -	writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver));
> -
> -	if ((value >> 11) & 0x1)
> -		complete(&csid->reset_complete);
> -
> -	return IRQ_HANDLED;
> -}
> -
>   /*
>    * csid_set_clock_rates - Calculate and set clock rates on CSID module
>    * @csiphy: CSID device
> @@ -521,31 +129,6 @@ static int csid_set_clock_rates(struct csid_device *csid)
>   	return 0;
>   }
>   
> -/*
> - * csid_reset - Trigger reset on CSID module and wait to complete
> - * @csid: CSID device
> - *
> - * Return 0 on success or a negative error code otherwise
> - */
> -static int csid_reset(struct csid_device *csid)
> -{
> -	unsigned long time;
> -
> -	reinit_completion(&csid->reset_complete);
> -
> -	writel_relaxed(0x7fff, csid->base +
> -		       CAMSS_CSID_RST_CMD(csid->camss->version));
> -
> -	time = wait_for_completion_timeout(&csid->reset_complete,
> -		msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
> -	if (!time) {
> -		dev_err(csid->camss->dev, "CSID reset timeout\n");
> -		return -EIO;
> -	}
> -
> -	return 0;
> -}
> -
>   /*
>    * csid_set_power - Power on/off CSID module
>    * @sd: CSID V4L2 subdevice
> @@ -560,8 +143,6 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>   	int ret;
>   
>   	if (on) {
> -		u32 hw_version;
> -
>   		ret = pm_runtime_get_sync(dev);
>   		if (ret < 0) {
>   			pm_runtime_put_sync(dev);
> @@ -590,7 +171,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>   
>   		enable_irq(csid->irq);
>   
> -		ret = csid_reset(csid);
> +		ret = csid->ops->reset(csid);
>   		if (ret < 0) {
>   			disable_irq(csid->irq);
>   			camss_disable_clocks(csid->nclocks, csid->clock);
> @@ -599,8 +180,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>   			return ret;
>   		}
>   
> -		hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
> -		dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version);
> +		csid->ops->hw_version(csid);
>   	} else {
>   		disable_irq(csid->irq);
>   		camss_disable_clocks(csid->nclocks, csid->clock);
> @@ -623,16 +203,9 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
>   static int csid_set_stream(struct v4l2_subdev *sd, int enable)
>   {
>   	struct csid_device *csid = v4l2_get_subdevdata(sd);
> -	struct csid_testgen_config *tg = &csid->testgen;
> -	enum camss_version ver = csid->camss->version;
> -	u32 val;
> +	int ret;
>   
>   	if (enable) {
> -		u8 vc = 0; /* Virtual Channel 0 */
> -		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
> -		u8 dt, dt_shift, df;
> -		int ret;
> -
>   		ret = v4l2_ctrl_handler_setup(&csid->ctrls);
>   		if (ret < 0) {
>   			dev_err(csid->camss->dev,
> @@ -640,116 +213,13 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
>   			return ret;
>   		}
>   
> -		if (!tg->enabled &&
> +		if (!csid->testgen.enabled &&
>   		    !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
>   			return -ENOLINK;
> -
> -		if (tg->enabled) {
> -			/* Config Test Generator */
> -			struct v4l2_mbus_framefmt *f =
> -					&csid->fmt[MSM_CSID_PAD_SRC];
> -			const struct csid_format *format = csid_get_fmt_entry(
> -					csid->formats, csid->nformats, f->code);
> -			u32 num_bytes_per_line =
> -				f->width * format->bpp * format->spp / 8;
> -			u32 num_lines = f->height;
> -
> -			/* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
> -			/* 1:0 VC */
> -			val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
> -			      ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_VC_CFG(ver));
> -
> -			/* 28:16 bytes per lines, 12:0 num of lines */
> -			val = ((num_bytes_per_line & 0x1fff) << 16) |
> -			      (num_lines & 0x1fff);
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_DT_n_CGG_0(ver, 0));
> -
> -			dt = format->data_type;
> -
> -			/* 5:0 data type */
> -			val = dt;
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_DT_n_CGG_1(ver, 0));
> -
> -			/* 2:0 output test pattern */
> -			val = tg->payload_mode;
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_DT_n_CGG_2(ver, 0));
> -
> -			df = format->decode_format;
> -		} else {
> -			struct v4l2_mbus_framefmt *f =
> -					&csid->fmt[MSM_CSID_PAD_SINK];
> -			const struct csid_format *format = csid_get_fmt_entry(
> -					csid->formats, csid->nformats, f->code);
> -			struct csid_phy_config *phy = &csid->phy;
> -
> -			val = phy->lane_cnt - 1;
> -			val |= phy->lane_assign << 4;
> -
> -			writel_relaxed(val,
> -				       csid->base + CAMSS_CSID_CORE_CTRL_0);
> -
> -			val = phy->csiphy_id << 17;
> -			val |= 0x9;
> -
> -			writel_relaxed(val,
> -				       csid->base + CAMSS_CSID_CORE_CTRL_1);
> -
> -			dt = format->data_type;
> -			df = format->decode_format;
> -		}
> -
> -		/* Config LUT */
> -
> -		dt_shift = (cid % 4) * 8;
> -
> -		val = readl_relaxed(csid->base +
> -				    CAMSS_CSID_CID_LUT_VC_n(ver, vc));
> -		val &= ~(0xff << dt_shift);
> -		val |= dt << dt_shift;
> -		writel_relaxed(val, csid->base +
> -			       CAMSS_CSID_CID_LUT_VC_n(ver, vc));
> -
> -		val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
> -		val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
> -		val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
> -		val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
> -
> -		if (csid->camss->version == CAMSS_8x96 ||
> -		    csid->camss->version == CAMSS_660) {
> -			u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
> -			u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
> -
> -			if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
> -			     src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
> -			    (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
> -			     src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
> -				val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
> -				val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
> -				val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
> -			}
> -		}
> -
> -		writel_relaxed(val, csid->base +
> -			       CAMSS_CSID_CID_n_CFG(ver, cid));
> -
> -		if (tg->enabled) {
> -			val = CAMSS_CSID_TG_CTRL_ENABLE;
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_CTRL(ver));
> -		}
> -	} else {
> -		if (tg->enabled) {
> -			val = CAMSS_CSID_TG_CTRL_DISABLE;
> -			writel_relaxed(val, csid->base +
> -				       CAMSS_CSID_TG_CTRL(ver));
> -		}
>   	}
>   
> +	csid->ops->configure_stream(csid, enable);
> +
>   	return 0;
>   }
>   
> @@ -818,7 +288,7 @@ static void csid_try_format(struct csid_device *csid,
>   
>   			*fmt = *__csid_get_format(csid, cfg,
>   						      MSM_CSID_PAD_SINK, which);
> -			fmt->code = csid_src_pad_code(csid, fmt->code, 0, code);
> +			fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code);
>   		} else {
>   			/* Test generator is enabled, set format on source */
>   			/* pad to allow test generator usage */
> @@ -868,7 +338,7 @@ static int csid_enum_mbus_code(struct v4l2_subdev *sd,
>   						     MSM_CSID_PAD_SINK,
>   						     code->which);
>   
> -			code->code = csid_src_pad_code(csid, sink_fmt->code,
> +			code->code = csid->ops->src_pad_code(csid, sink_fmt->code,
>   						       code->index, 0);
>   			if (!code->code)
>   				return -EINVAL;
> @@ -1004,15 +474,6 @@ static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
>   	return csid_set_format(sd, fh ? fh->pad : NULL, &format);
>   }
>   
> -static const char * const csid_test_pattern_menu[] = {
> -	"Disabled",
> -	"Incrementing",
> -	"Alternating 0x55/0xAA",
> -	"All Zeros 0x00",
> -	"All Ones 0xFF",
> -	"Pseudo-random Data",
> -};
> -
>   /*
>    * csid_set_test_pattern - Set test generator's pattern mode
>    * @csid: CSID device
> @@ -1030,25 +491,7 @@ static int csid_set_test_pattern(struct csid_device *csid, s32 value)
>   
>   	tg->enabled = !!value;
>   
> -	switch (value) {
> -	case 1:
> -		tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING;
> -		break;
> -	case 2:
> -		tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA;
> -		break;
> -	case 3:
> -		tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES;
> -		break;
> -	case 4:
> -		tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES;
> -		break;
> -	case 5:
> -		tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM;
> -		break;
> -	}
> -
> -	return 0;
> +	return csid->ops->configure_testgen_pattern(csid, value);
>   }
>   
>   /*
> @@ -1097,17 +540,14 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>   	csid->id = id;
>   
>   	if (camss->version == CAMSS_8x16) {
> -		csid->formats = csid_formats_8x16;
> -		csid->nformats =
> -				ARRAY_SIZE(csid_formats_8x16);
> +		csid->ops = &csid_ops_4_1;
>   	} else if (camss->version == CAMSS_8x96 ||
>   		   camss->version == CAMSS_660) {
> -		csid->formats = csid_formats_8x96;
> -		csid->nformats =
> -				ARRAY_SIZE(csid_formats_8x96);
> +		csid->ops = &csid_ops_4_7;
>   	} else {
>   		return -EINVAL;
>   	}
> +	csid->ops->subdev_init(csid);
>   
>   	/* Memory */
>   
> @@ -1130,7 +570,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>   	csid->irq = r->start;
>   	snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
>   		 dev_name(dev), MSM_CSID_NAME, csid->id);
> -	ret = devm_request_irq(dev, csid->irq, csid_isr,
> +	ret = devm_request_irq(dev, csid->irq, csid->ops->isr,
>   		IRQF_TRIGGER_RISING, csid->irq_name, csid);
>   	if (ret < 0) {
>   		dev_err(dev, "request_irq failed: %d\n", ret);
> @@ -1341,8 +781,8 @@ int msm_csid_register_entity(struct csid_device *csid,
>   
>   	csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
>   				&csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
> -				ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0,
> -				csid_test_pattern_menu);
> +				csid->testgen.nmodes, 0, 0,
> +				csid->testgen.modes);
>   
>   	if (csid->ctrls.error) {
>   		dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
> diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
> index 02fc34ee8a41..d40194e2bed3 100644
> --- a/drivers/media/platform/qcom/camss/camss-csid.h
> +++ b/drivers/media/platform/qcom/camss/camss-csid.h
> @@ -11,6 +11,7 @@
>   #define QC_MSM_CAMSS_CSID_H
>   
>   #include <linux/clk.h>
> +#include <linux/interrupt.h>
>   #include <media/media-entity.h>
>   #include <media/v4l2-ctrls.h>
>   #include <media/v4l2-device.h>
> @@ -70,19 +71,50 @@
>   #define PLAIN_FORMAT_PLAIN16	0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */
>   #define PLAIN_FORMAT_PLAIN32	0x2 /* supports UNCOMPRESSED_20_BIT */
>   
> +#define CSID_RESET_TIMEOUT_MS 500
>   
> -enum csid_payload_mode {
> +
> +enum csid_testgen_mode {
>   	CSID_PAYLOAD_MODE_INCREMENTING = 0,
>   	CSID_PAYLOAD_MODE_ALTERNATING_55_AA = 1,
>   	CSID_PAYLOAD_MODE_ALL_ZEROES = 2,
>   	CSID_PAYLOAD_MODE_ALL_ONES = 3,
>   	CSID_PAYLOAD_MODE_RANDOM = 4,
>   	CSID_PAYLOAD_MODE_USER_SPECIFIED = 5,
> +	CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_1 = 5,
> +	CSID_PAYLOAD_MODE_MAX_SUPPORTED_4_7 = 5,
> +	CSID_PAYLOAD_MODE_COMPLEX_PATTERN = 6,
> +	CSID_PAYLOAD_MODE_COLOR_BOX = 7,
> +	CSID_PAYLOAD_MODE_COLOR_BARS = 8,
> +	CSID_PAYLOAD_MODE_MAX_SUPPORTED_170 = 8,
> +};
> +
> +static const char * const csid_testgen_modes[] = {
> +	"Disabled",
> +	"Incrementing",
> +	"Alternating 0x55/0xAA",
> +	"All Zeros 0x00",
> +	"All Ones 0xFF",
> +	"Pseudo-random Data",
> +	"User Specified",
> +	"Complex pattern",
> +	"Color box",
> +	"Color bars",
> +};
> +
> +struct csid_format {
> +	u32 code;
> +	u8 data_type;
> +	u8 decode_format;
> +	u8 bpp;
> +	u8 spp; /* bus samples per pixel */
>   };
>   
>   struct csid_testgen_config {
> +	enum csid_testgen_mode mode;
> +	const char * const*modes;
> +	u8 nmodes;
>   	u8 enabled;
> -	enum csid_payload_mode payload_mode;
>   };
>   
>   struct csid_phy_config {
> @@ -91,6 +123,65 @@ struct csid_phy_config {
>   	u32 lane_assign;
>   };
>   
> +struct csid_device;
> +
> +struct csid_hw_ops {
> +	/*
> +	 * configure_stream - Configures and starts CSID input stream
> +	 * @csid: CSID device
> +	 */
> +	void (*configure_stream)(struct csid_device *csid, u8 enable);
> +
> +	/*
> +	 * configure_testgen_pattern - Validates and configures output pattern mode
> +	 * of test pattern generator
> +	 * @csid: CSID device
> +	 */
> +	int (*configure_testgen_pattern)(struct csid_device *csid, s32 val);
> +
> +	/*
> +	 * hw_version - Read hardware version register from hardware
> +	 * @csid: CSID device
> +	 */
> +	u32 (*hw_version)(struct csid_device *csid);
> +
> +	/*
> +	 * isr - CSID module interrupt service routine
> +	 * @irq: Interrupt line
> +	 * @dev: CSID device
> +	 *
> +	 * Return IRQ_HANDLED on success
> +	 */
> +	irqreturn_t (*isr)(int irq, void *dev);
> +
> +	/*
> +	 * reset - Trigger reset on CSID module and wait to complete
> +	 * @csid: CSID device
> +	 *
> +	 * Return 0 on success or a negative error code otherwise
> +	 */
> +	int (*reset)(struct csid_device *csid);
> +
> +	/*
> +	 * src_pad_code - Pick an output/src format based on the input/sink format
> +	 * @csid: CSID device
> +	 * @sink_code: The sink format of the input
> +	 * @match_format_idx: Request preferred index, as defined by subdevice csid_format.
> +	 *	Set @match_code to 0 if used.
> +	 * @match_code: Request preferred code, set @match_format_idx to 0 if used
> +	 *
> +	 * Return 0 on failure or src format code otherwise
> +	 */
> +	u32 (*src_pad_code)(struct csid_device *csid, u32 sink_code,
> +			    unsigned int match_format_idx, u32 match_code);
> +
> +	/*
> +	 * subdev_init - Initialize CSID device according for hardware revision
> +	 * @csid: CSID device
> +	 */
> +	void (*subdev_init)(struct csid_device *csid);
> +};
> +
>   struct csid_device {
>   	struct camss *camss;
>   	u8 id;
> @@ -110,10 +201,37 @@ struct csid_device {
>   	struct v4l2_ctrl *testgen_mode;
>   	const struct csid_format *formats;
>   	unsigned int nformats;
> +	const struct csid_hw_ops *ops;
>   };
>   
>   struct resources;
>   
> +
> +/*
> + * csid_find_code - Find a format code in an array using array index or format code
> + * @codes: Array of format codes
> + * @ncodes: Length of @code array
> + * @req_format_idx: Request preferred index, as defined by subdevice csid_format.
> + *	Set @match_code to 0 if used.
> + * @match_code: Request preferred code, set @req_format_idx to 0 if used
> + *
> + * Return 0 on failure or format code otherwise
> + */
> +u32 csid_find_code(u32 *codes, unsigned int ncode,
> +		   unsigned int match_format_idx, u32 match_code);
> +
> +/*
> + * csid_get_fmt_entry - Find csid_format entry with matching format code
> + * @formats: Array of format csid_format entries
> + * @nformats: Length of @nformats array
> + * @code: Desired format code
> + *
> + * Return formats[0] on failure to find code
> + */
> +const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
> +					     unsigned int nformats,
> +					     u32 code);
> +
>   int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
>   			 const struct resources *res, u8 id);
>   
> @@ -124,4 +242,8 @@ void msm_csid_unregister_entity(struct csid_device *csid);
>   
>   void msm_csid_get_csid_id(struct media_entity *entity, u8 *id);
>   
> +
> +extern const struct csid_hw_ops csid_ops_4_1;
> +extern const struct csid_hw_ops csid_ops_4_7;
> +
>   #endif /* QC_MSM_CAMSS_CSID_H */
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ