From: Neil Armstrong <narmstrong@baylibre.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
linux-media@vger.kernel.org
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>,
Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>,
Benoit Parrot <bparrot@ti.com>
Subject: Re: [PATCH v2 2/2] media: i2c: Add OV1063x sensor driver
Date: Wed, 23 Mar 2022 17:12:10 +0100 [thread overview]
Message-ID: <5a2b6171-e784-e40c-7142-b69d4b99fd77@baylibre.com> (raw)
In-Reply-To: <b1a1fd6c-e203-3cab-e04b-ab67a9be40af@baylibre.com>
On 23/03/2022 15:01, Neil Armstrong wrote:
> Hi Laurent,
>
>
> On 07/12/2021 00:07, Laurent Pinchart wrote:
>> Add a new V4L2 subdev driver for the OmniVision OV10633 and OV10635
>> camera sensors. The work is based on the driver from the TI BSP, itself
>> based on original work by Phil Edworthy posted to the linux-media
>> mailing list ([1]). This version of the code is a large rewrite of many
>> parts.
>>
>> [1] http://www.spinics.net/lists/linux-media/msg64347.html
>>
>> Signed-off-by: Nikhil Devshatwar <nikhil.nd@ti.com>
>> Signed-off-by: Benoit Parrot <bparrot@ti.com>
>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> ---
>> Changes since v1:
>>
>> - Drop unneeded debug message
>> - Fix MODULE_LICENSE
>> - Fix priv pointer retrieval in remove()
>> - Add more registers macros
>> - Fix PLL calculation
>> - Update to subdev state API
>> - Fix test pattern when starting streaming
>> ---
>> MAINTAINERS | 2 +
>> drivers/media/i2c/Kconfig | 12 +
>> drivers/media/i2c/Makefile | 1 +
>> drivers/media/i2c/ov1063x.c | 1716 ++++++++++++++++++++++++++++++
>> drivers/media/i2c/ov1063x_regs.h | 627 +++++++++++
>> 5 files changed, 2358 insertions(+)
>> create mode 100644 drivers/media/i2c/ov1063x.c
>> create mode 100644 drivers/media/i2c/ov1063x_regs.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 9c7748b160dd..eb24dc54e046 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -14044,6 +14044,8 @@ L: linux-media@vger.kernel.org
>> S: Maintained
>> T: git git://linuxtv.org/media_tree.git
>> F: Documentation/devicetree/bindings/media/i2c/ov1063x.yaml
>> +F: drivers/media/i2c/ov1063x.c
>> +F: drivers/media/i2c/ov1063x_regs.h
>> OMNIVISION OV13858 SENSOR DRIVER
>> M: Sakari Ailus <sakari.ailus@linux.intel.com>
>> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
>> index d6a5d4ca439a..7a0d7bd17a3c 100644
>> --- a/drivers/media/i2c/Kconfig
>> +++ b/drivers/media/i2c/Kconfig
>> @@ -1192,6 +1192,18 @@ config VIDEO_OV9734
>> To compile this driver as a module, choose M here: the
>> module's name is ov9734.
>> +config VIDEO_OV10633
>> + tristate "OmniVision OV10633/OV10635 sensor support"
>> + depends on I2C && VIDEO_V4L2
>> + depends on GPIOLIB && OF
>> + select MEDIA_CONTROLLER
>> + select REGMAP_I2C
>> + select V4L2_FWNODE
>> + select VIDEO_V4L2_SUBDEV_API
>> + help
>> + This is a Video4Linux2 driver for the OmniVision
>> + OV10633 and OV10635 camera sensors.
>> +
>> config VIDEO_OV13858
>> tristate "OmniVision OV13858 sensor support"
>> depends on I2C && VIDEO_V4L2
>> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
>> index 4d4fe08d7a6a..a16299de56c0 100644
>> --- a/drivers/media/i2c/Makefile
>> +++ b/drivers/media/i2c/Makefile
>> @@ -88,6 +88,7 @@ obj-$(CONFIG_VIDEO_OV9282) += ov9282.o
>> obj-$(CONFIG_VIDEO_OV9640) += ov9640.o
>> obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
>> obj-$(CONFIG_VIDEO_OV9734) += ov9734.o
>> +obj-$(CONFIG_VIDEO_OV10633) += ov1063x.o
>> obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
>> obj-$(CONFIG_VIDEO_OV13B10) += ov13b10.o
>> obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
>> diff --git a/drivers/media/i2c/ov1063x.c b/drivers/media/i2c/ov1063x.c
>> new file mode 100644
>> index 000000000000..fb4ef5ea9a9f
>> --- /dev/null
>> +++ b/drivers/media/i2c/ov1063x.c
>> @@ -0,0 +1,1716 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * OmniVision OV10633/OV10635 Camera Driver
>> + *
>> + * Based on the original driver written by Phil Edworthy.
>> + * Copyright (C) 2013 Phil Edworthy
>> + * Copyright (C) 2013 Renesas Electronics
>> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
>> + * Copyright (C) 2020 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/i2c.h>
>> +#include <linux/init.h>
>> +#include <linux/module.h>
>> +#include <linux/of.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-common.h>
>> +#include <media/v4l2-ctrls.h>
>> +#include <media/v4l2-event.h>
>> +#include <media/v4l2-fwnode.h>
>> +#include <media/v4l2-subdev.h>
>> +
>> +/* Register definitions */
>> +#define OV1063X_REG_8BIT(n) ((1 << 16) | (n))
>> +#define OV1063X_REG_16BIT(n) ((2 << 16) | (n))
>> +#define OV1063X_REG_24BIT(n) ((3 << 16) | (n))
>> +#define OV1063X_REG_32BIT(n) ((4 << 16) | (n))
>> +#define OV1063X_REG_SIZE_SHIFT 16
>> +#define OV1063X_REG_ADDR_MASK 0xffff
>> +
>> +#define OV1063X_STREAM_MODE OV1063X_REG_8BIT(0x0100)
>> +#define OV1063X_STREAM_MODE_ON BIT(0)
>> +#define OV1063X_SOFTWARE_RESET OV1063X_REG_8BIT(0x0103)
>> +
>> +#define OV1063X_SC_CMMN_PLL_CTRL0 OV1063X_REG_8BIT(0x3003)
>> +#define OV1063X_SC_CMMN_PLL_SCLK_CP(n) ((n) << 6)
>> +#define OV1063X_SC_CMMN_PLL_SCLK_MULTI(n) ((n) << 0)
>> +#define OV1063X_SC_CMMN_PLL_CTRL1 OV1063X_REG_8BIT(0x3004)
>> +#define OV1063X_SC_CMMN_PLL_SCLK_BYPASS BIT(7)
>> +#define OV1063X_SC_CMMN_PLL_SCLK_PRE_DIV(n) ((n) << 4) /* /1, /1.5, /2, /3, /4, /5, /6, /7 */
>> +#define OV1063X_SC_CMMN_PLL_SCLK_CP2(n) ((n) << 3)
>> +#define OV1063X_SC_CMMN_PLL_SCLK_DIV(n) ((n) << 0) /* Divider = 2 * (1 + n) */
>> +#define OV1063X_SC_CMMN_PLL_CTRL2 OV1063X_REG_8BIT(0x3005)
>> +#define OV1063X_SC_CMMN_PLL_PCLK_CP(n) ((n) << 6)
>> +#define OV1063X_SC_CMMN_PLL_PCLK_MULTI(n) ((n) << 0)
>> +#define OV1063X_SC_CMMN_PLL_CTRL3 OV1063X_REG_8BIT(0x3006)
>> +#define OV1063X_SC_CMMN_PLL_PCLK_BYPASS BIT(7)
>> +#define OV1063X_SC_CMMN_PLL_PCLK_PRE_DIV(n) ((n) << 4) /* /1, /1.5, /2, /3, /4, /5, /6, /7 */
>> +#define OV1063X_SC_CMMN_PLL_PCLK_CP2(n) ((n) << 3)
>> +#define OV1063X_SC_CMMN_PLL_PCLK_DIV(n) ((n) << 0) /* Divider = 2 * (1 + n) */
>> +#define OV1063X_SC_CMMN_PCLK_DIV_CTRL OV1063X_REG_8BIT(0x3007)
>> +#define OV1063X_PID OV1063X_REG_16BIT(0x300a)
>> +#define OV1063X_SC_CMMN_SCCB_ID OV1063X_REG_8BIT(0x300c)
>> +#define OV1063X_SC_CMMN_SCCB_ID_ADDR(n) ((n) << 1)
>> +#define OV1063X_SC_CMMN_SCCB_ID_SEL BIT(0)
>> +#define OV1063X_SC_CMMN_PAD OV1063X_REG_8BIT(0x3011)
>> +#define OV1063X_SC_CMMN_PAD_DRIVE(n) ((n) << 6)
>> +#define OV1063X_SC_CMMN_CLKRST0 OV1063X_REG_8BIT(0x301a)
>> +#define OV1063X_SC_CMMN_CLKRST0_SCLK GENMASK(7, 4)
>> +#define OV1063X_SC_CMMN_CLKRST0_RST GENMASK(3, 0)
>> +#define OV1063X_SC_CMMN_CLKRST1 OV1063X_REG_8BIT(0x301b)
>> +#define OV1063X_SC_CMMN_CLKRST1_SCLK GENMASK(7, 4)
>> +#define OV1063X_SC_CMMN_CLKRST1_RST GENMASK(3, 0)
>> +#define OV1063X_SC_CMMN_CLKRST2 OV1063X_REG_8BIT(0x301c)
>> +#define OV1063X_SC_CMMN_CLKRST2_PCLK_DVP BIT(7)
>> +#define OV1063X_SC_CMMN_CLKRST2_SCLK GENMASK(6, 4)
>> +#define OV1063X_SC_CMMN_CLKRST2_RST_DVP BIT(3)
>> +#define OV1063X_SC_CMMN_CLKRST2_RST GENMASK(2, 0)
>> +#define OV1063X_SC_CMMN_CLOCK_SEL OV1063X_REG_8BIT(0x3020)
>> +#define OV1063X_SC_CMMN_CLOCK_SEL_SCLK2X BIT(0)
>> +#define OV1063X_SC_CMMN_MISC_CTRL OV1063X_REG_8BIT(0x3021)
>> +#define OV1063X_SC_CMMN_MISC_CTRL_PCLK_INV BIT(7)
>> +#define OV1063X_SC_CMMN_MISC_CTRL_SCLK_INV BIT(6)
>> +#define OV1063X_SC_CMMN_MISC_CTRL_SCLK2X_INV BIT(5)
>> +#define OV1063X_SC_CMMN_MISC_CTRL_CEN_GLOBAL_O BIT(0)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_1 OV1063X_REG_8BIT(0x3022)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_2 OV1063X_REG_8BIT(0x3023)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_BIST_EN BIT(5)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_CLK_SWITCH BIT(4)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_3 OV1063X_REG_8BIT(0x3024)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_RAW_LONG (0U << 4)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_RAW_SHORT (1U << 4)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_RAW_LONG_SHORT (2U << 4)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_RAW_COMBINED (0U << 4)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_YUV_LONG (1U << 1)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_YUV_SHORT (2U << 1)
>> +#define OV1063X_SC_CMMN_CORE_CTRL_PCLK_SYS (0U << 0) /* PCLK from system PLL */
>> +#define OV1063X_SC_CMMN_CORE_CTRL_PCLK_SEC (1U << 0) /* PCLK from secondary PLL */
>> +#define OV1063X_SC_CMMN_CORE_CTRL1 OV1063X_REG_8BIT(0x3025)
>> +#define OV1063X_SC_CMMN_PWDN_CTRL2 OV1063X_REG_8BIT(0x302d)
>> +#define OV1063X_SC_CMMN_PWDN_CTRL2_RST_DIG1 BIT(3)
>> +#define OV1063X_SC_CMMN_PWDN_CTRL2_RST_DIG2 BIT(2)
>> +#define OV1063X_SC_CMMN_PWDN_CTRL2_RST_ISP BIT(1)
>> +#define OV1063X_SC_CMMN_PWDN_CTRL2_SEQUENCE BIT(0)
>> +#define OV1063X_SC_CMMN_SCLK2X_SEL OV1063X_REG_8BIT(0x3033)
>> +#define OV1063X_SC_CMMN_SCLK2X_SEL_DIV2 (1U << 2)
>> +#define OV1063X_SC_CMMN_SCLK2X_SEL_DIV4 (2U << 2)
>> +#define OV1063X_SC_SOC_CLKRST7 OV1063X_REG_8BIT(0x3042)
>> +#define OV1063X_SC_SOC_CLKRST7_SCLK GENMASK(7, 4)
>> +#define OV1063X_SC_SOC_CLKRST7_RST GENMASK(3, 0)
>> +
>> +#define OV1063X_AEC_PK_MANUAL OV1063X_REG_8BIT(0x3503)
>> +#define OV1063X_AEC_PK_MANUAL_GAIN_DELAY BIT(5)
>> +#define OV1063X_AEC_PK_MANUAL_DELAY BIT(4)
>> +#define OV1063X_AEC_PK_MAN_DONE OV1063X_REG_8BIT(0x3504)
>> +#define OV1063X_AEC_PK_MAN_DONE_AEC_DONE BIT(0)
>> +
>> +#define OV1063X_ANA_ADC1 OV1063X_REG_8BIT(0x3600)
>> +#define OV1063X_ANA_ADC2 OV1063X_REG_8BIT(0x3601)
>> +#define OV1063X_ANA_ADC3 OV1063X_REG_8BIT(0x3602)
>> +#define OV1063X_ANA_ADC4 OV1063X_REG_8BIT(0x3603)
>> +#define OV1063X_ANA_ANALOG1 OV1063X_REG_8BIT(0x3610)
>> +#define OV1063X_ANA_ANALOG2 OV1063X_REG_8BIT(0x3611)
>> +#define OV1063X_ANA_ANALOG3 OV1063X_REG_8BIT(0x3612)
>> +#define OV1063X_ANA_ARRAY1 OV1063X_REG_8BIT(0x3621)
>> +#define OV1063X_ANA_ARRAY1_FULL (0 << 3)
>> +#define OV1063X_ANA_ARRAY1_CROP_768 (1 << 3)
>> +#define OV1063X_ANA_ARRAY1_CROP_656 (2 << 3)
>> +#define OV1063X_ANA_ARRAY1_DELAY(n) ((n) << 0)
>> +#define OV1063X_ANA_PWC1 OV1063X_REG_8BIT(0x3630)
>> +#define OV1063X_ANA_PWC2 OV1063X_REG_8BIT(0x3631)
>> +#define OV1063X_ANA_PWC3 OV1063X_REG_8BIT(0x3632)
>> +#define OV1063X_ANA_PWC4 OV1063X_REG_8BIT(0x3633)
>> +
>> +#define OV1063X_SENSOR_RSTGOLOW OV1063X_REG_8BIT(0x3702)
>> +#define OV1063X_SENSOR_HLDWIDTH OV1063X_REG_8BIT(0x3703)
>> +#define OV1063X_SENSOR_TXWIDTH OV1063X_REG_8BIT(0x3704)
>> +#define OV1063X_SENSOR_REG9 OV1063X_REG_8BIT(0x3709)
>> +#define OV1063X_SENSOR_REGD OV1063X_REG_8BIT(0x370d)
>> +#define OV1063X_SENSOR_RSTYZ_GOLOW OV1063X_REG_16BIT(0x3712)
>> +#define OV1063X_SENSOR_EQ_GOLOW OV1063X_REG_8BIT(0x3714)
>> +#define OV1063X_SENSOR_REG15 OV1063X_REG_8BIT(0x3715)
>> +#define OV1063X_SENSOR_BITSW_GO OV1063X_REG_16BIT(0x371c)
>> +
>> +#define OV1063X_TIMING_X_START_ADDR OV1063X_REG_16BIT(0x3800)
>> +#define OV1063X_TIMING_Y_START_ADDR OV1063X_REG_16BIT(0x3802)
>> +#define OV1063X_TIMING_X_END_ADDR OV1063X_REG_16BIT(0x3804)
>> +#define OV1063X_TIMING_Y_END_ADDR OV1063X_REG_16BIT(0x3806)
>> +#define OV1063X_TIMING_X_OUTPUT_SIZE OV1063X_REG_16BIT(0x3808)
>> +#define OV1063X_TIMING_Y_OUTPUT_SIZE OV1063X_REG_16BIT(0x380a)
>> +#define OV1063X_TIMING_HTS OV1063X_REG_16BIT(0x380c)
>> +#define OV1063X_TIMING_VTS OV1063X_REG_16BIT(0x380e)
>> +#define OV1063X_TIMING_ISP_X_WIN OV1063X_REG_16BIT(0x3810)
>> +#define OV1063X_TIMING_ISP_Y_WIN OV1063X_REG_16BIT(0x3812)
>> +#define OV1063X_TIMING_CTRL15 OV1063X_REG_8BIT(0x3815)
>> +#define OV1063X_TIMING_CTRL15_BLACK_LINE_HREF BIT(7)
>> +#define OV1063X_TIMING_CTRL15_RIP_SOF BIT(5)
>> +#define OV1063X_TIMING_CTRL15_BLACK_LINES(n) ((n) << 0)
>> +#define OV1063X_TIMING_CTRL1C OV1063X_REG_8BIT(0x381c)
>> +#define OV1063X_TIMING_CTRL1C_VFLIP_DIG BIT(7)
>> +#define OV1063X_TIMING_CTRL1C_VFLIP_ARRAY BIT(6)
>> +#define OV1063X_TIMING_CTRL1C_VSUB4 BIT(1)
>> +#define OV1063X_TIMING_CTRL1C_VSUB2 BIT(0)
>> +#define OV1063X_TIMING_CTRL1D OV1063X_REG_8BIT(0x381d)
>> +#define OV1063X_TIMING_CTRL1D_VFLIP_BLACK_LINE BIT(7)
>> +#define OV1063X_TIMING_CTRL1D_WDR BIT(6)
>> +#define OV1063X_TIMING_CTRL1D_HFLIP_DIG BIT(1)
>> +#define OV1063X_TIMING_CTRL1D_HFLIP_ARRAY BIT(0)
>> +#define OV1063X_TIMING_CTRL24 OV1063X_REG_8BIT(0x3824)
>> +#define OV1063X_VSTART_OFFSET OV1063X_REG_16BIT(0x381e)
>> +#define OV1063X_TIMING_TC_CS_RST OV1063X_REG_16BIT(0x3832)
>> +#define OV1063X_TIMING_TC_R_RST OV1063X_REG_16BIT(0x3834)
>> +
>> +#define OV1063X_START_LINE OV1063X_REG_8BIT(0x4001)
>> +#define OV1063X_LINE_NUM OV1063X_REG_8BIT(0x4004) /* Black lines */
>> +#define OV1063X_BLC_CTRL05 OV1063X_REG_8BIT(0x4005)
>> +#define OV1063X_BLC_CTRL05_ONE_LINE_MODE BIT(5)
>> +#define OV1063X_BLC_CTRL05_REMOVE_BLACK_LINE BIT(4)
>> +#define OV1063X_BLC_CTRL05_ONE_MAN_OFFSET_MODE BIT(3)
>> +#define OV1063X_BLC_CTRL05_BL_RBLUE_RVS BIT(2)
>> +#define OV1063X_BLC_CTRL05_BLC_ALWAYS_DO BIT(1)
>> +#define OV1063X_BLC_AVG_CTRL1 OV1063X_REG_8BIT(0x4050)
>> +#define OV1063X_BLC_AVG_CTRL2 OV1063X_REG_8BIT(0x4051)
>> +#define OV1063X_BLC_OFFSET_TOP_LIMIT OV1063X_REG_16BIT(0x4056)
>> +#define OV1063X_BLC_OFFSET_BOT_LIMIT OV1063X_REG_16BIT(0x4058)
>> +#define OV1063X_BLC_CTRL5A OV1063X_REG_8BIT(0x405a)
>> +
>> +#define OV1063X_FC_R2 OV1063X_REG_8BIT(0x4202)
>> +
>> +#define OV1063X_FORMAT_CTRL00 OV1063X_REG_8BIT(0x4300)
>> +#define OV1063X_FORMAT_YUYV 0x38
>> +#define OV1063X_FORMAT_YYYU 0x39
>> +#define OV1063X_FORMAT_UYVY 0x3a
>> +#define OV1063X_FORMAT_VYUY 0x3b
>> +#define OV1063X_FORMAT_YMAX OV1063X_REG_16BIT(0x4302)
>> +#define OV1063X_FORMAT_YMIN OV1063X_REG_16BIT(0x4304)
>> +#define OV1063X_FORMAT_UMAX OV1063X_REG_16BIT(0x4306)
>> +#define OV1063X_FORMAT_UMIN OV1063X_REG_16BIT(0x4308)
>> +
>> +#define OV1063X_VFIFO_LLEN_FIRS1_SEL OV1063X_REG_8BIT(0x4605)
>> +#define OV1063X_VFIFO_LLEN_FIRS1_SEL_8B_YUV BIT(3)
>> +#define OV1063X_VFIFO_LINE_LENGTH_MAN OV1063X_REG_16BIT(0x4606)
>> +#define OV1063X_VFIFO_READ_START OV1063X_REG_16BIT(0x4608)
>> +#define OV1063X_VFIFO_HSYNC_START_POSITION OV1063X_REG_16BIT(0x460a)
>> +#define OV1063X_VFIFO_HSYNC_CTRL OV1063X_REG_8BIT(0x460c)
>> +#define OV1063X_VFIFO_HSYNC_CTRL_HEADER_WIDTH(n) ((n) << 4)
>> +#define OV1063X_VFIFO_HSYNC_CTRL_TRAILER_WIDTH(n) ((n) << 0)
>> +#define OV1063X_VFIFO_EMBD_LINE_CTRL OV1063X_REG_8BIT(0x460e)
>> +#define OV1063X_VFIFO_EMBD_LINE_CTRL_SOF_CLR_RAM BIT(3)
>> +#define OV1063X_VFIFO_EMBD_LINE_CTRL_ST_MOD BIT(2)
>> +#define OV1063X_VFIFO_EMBD_LINE_CTRL_EMBD_ROM BIT(1)
>> +#define OV1063X_VFIFO_EMBD_LINE_CTRL_EMBD_EN BIT(0)
>> +#define OV1063X_VFIFO_EMBD_LINE_NUM OV1063X_REG_8BIT(0x460f)
>> +#define OV1063X_EMB_START_PCNT OV1063X_REG_16BIT(0x4610)
>> +#define OV1063X_EMB_START_LCNT OV1063X_REG_16BIT(0x4612)
>> +#define OV1063X_ROI_CTRL0 OV1063X_REG_8BIT(0x4620)
>> +#define OV1063X_ROI_CTRL0_SYNC_BYP BIT(7)
>> +#define OV1063X_ROI_CTRL0_FR_COMP BIT(6)
>> +#define OV1063X_ROI_CTRL0_FULL_DAT_MOD BIT(5)
>> +#define OV1063X_ROI_CTRL0_EN_3 BIT(3)
>> +#define OV1063X_ROI_CTRL0_EN_2 BIT(2)
>> +#define OV1063X_ROI_CTRL0_EN_1 BIT(1)
>> +#define OV1063X_ROI_CTRL0_FUNC_E BIT(0)
>> +
>> +#define OV1063X_DVP_MOD_SEL OV1063X_REG_8BIT(0x4700)
>> +#define OV1063X_DVP_MOD_SEL_CCIR_V BIT(3)
>> +#define OV1063X_DVP_MOD_SEL_CCIR_F BIT(2)
>> +#define OV1063X_DVP_MOD_SEL_CCIR_656 BIT(1)
>> +#define OV1063X_DVP_MOD_SEL_HSYNC BIT(0)
>> +#define OV1063X_DVP_VSYNC_WIDTH OV1063X_REG_8BIT(0x4701)
>> +#define OV1063X_DVP_HSYVSY_NEG_WIDTH OV1063X_REG_16BIT(0x4702)
>> +#define OV1063X_DVP_VSYNC_MODE OV1063X_REG_8BIT(0x4704)
>> +#define OV1063X_DVP_VSYNC_MODE_VSYNCOUT_SEL(n) ((n) << 2)
>> +#define OV1063X_DVP_VSYNC_MODE_VSYNC3_MOD BIT(1)
>> +#define OV1063X_DVP_VSYNC_MODE_VSYNC2_MOD BIT(0)
>> +#define OV1063X_DVP_EOF_VSYNC_DELAY OV1063X_REG_24BIT(0x4705)
>> +
>> +#define OV1063X_ISP_RW00 OV1063X_REG_8BIT(0x5000)
>> +#define OV1063X_ISP_RW00_COLOR_MATRIX_EN BIT(7)
>> +#define OV1063X_ISP_RW00_COLOR_INTERP_EN BIT(6)
>> +#define OV1063X_ISP_RW00_DENOISE_EN BIT(5)
>> +#define OV1063X_ISP_RW00_WHITE_DPC_EN BIT(4) /* White defect pixel correction enable */
>> +#define OV1063X_ISP_RW00_BLACK_DPC_EN BIT(3) /* Black defect pixel connection enable */
>> +#define OV1063X_ISP_RW00_AWB_STATS_EN BIT(2)
>> +#define OV1063X_ISP_RW00_AWB_GAIN_EN BIT(1)
>> +#define OV1063X_ISP_RW00_LSC_EN BIT(0)
>> +#define OV1063X_ISP_RW01 OV1063X_REG_8BIT(0x5001)
>> +#define OV1063X_ISP_RW01_DATA_WEIGHT_SYNC_EN BIT(7)
>> +#define OV1063X_ISP_RW01_BLACK_WHITE_MODE_EN BIT(6)
>> +#define OV1063X_ISP_RW01_DARK_LEVEL_FILTER_EN BIT(5)
>> +#define OV1063X_ISP_RW01_BUFFER_CONTROL_EN BIT(4)
>> +#define OV1063X_ISP_RW01_AEC_EN BIT(3)
>> +#define OV1063X_ISP_RW01_TONE_MAPPING_EN BIT(2)
>> +#define OV1063X_ISP_RW01_NORMALIZE_EN BIT(1)
>> +#define OV1063X_ISP_RW01_LONG_SHORT_COMB_EN BIT(0)
>> +#define OV1063X_ISP_RW02 OV1063X_REG_8BIT(0x5002)
>> +#define OV1063X_ISP_RW02_OTP_MANUAL_OFFSET_EN BIT(7)
>> +#define OV1063X_ISP_RW02_OTP_EN BIT(6)
>> +#define OV1063X_ISP_RW02_INTER_FRAME_CALC BIT(5)
>> +#define OV1063X_ISP_RW02_CT_AWB_EN BIT(4)
>> +#define OV1063X_ISP_RW02_DIGITAL_GAIN_EN BIT(3)
>> +#define OV1063X_ISP_RW02_WINDOW_BORDER_CUT_EN BIT(2)
>> +#define OV1063X_ISP_RW02_DITHERING_EN BIT(1)
>> +#define OV1063X_ISP_RW02_LSLS (0U << 0)
>> +#define OV1063X_ISP_RW02_SLSL (1U << 0)
>> +#define OV1063X_ISP_RW05 OV1063X_REG_8BIT(0x5005)
>> +#define OV1063X_ISP_RW05_VERT_SUB_EN BIT(7) /* Enable vertical subsampling */
>> +#define OV1063X_ISP_RW05_LSC_CENTER_AUTO BIT(6) /* Set LSC center automatically based on image window */
>> +#define OV1063X_ISP_RW05_SUB_OUT_ROW_2ND BIT(5) /* Output 2nd (1) or 1st (0) row when skipping */
>> +#define OV1063X_ISP_RW05_SUB_OUT_COL_2ND BIT(4) /* Output 2nd (1) or 1st (0) column when skipping */
>> +#define OV1063X_ISP_RW05_SUB_AVG BIT(3) /* Average (1) or sum (0) when binning */
>> +#define OV1063X_ISP_RW05_SUB_G_DROP BIT(2) /* Skip (1) or bin (0) Green / Y */
>> +#define OV1063X_ISP_RW05_SUB_RB_DROP BIT(1) /* Skip (1) or bin (0) Red Blue / UV */
>> +#define OV1063X_ISP_RW05_SUB_ENABLE BIT(0) /* Enable sub-sampling */
>> +#define OV1063X_ISP_RW06 OV1063X_REG_8BIT(0x5006)
>> +#define OV1063X_ISP_RW06_RAW_MODE_MAN(n) ((n) << 6)
>> +#define OV1063X_ISP_RW06_YUV_MODE_MAN(n) ((n) << 4)
>> +#define OV1063X_ISP_RW06_RAW_MODE_MAN_EN BIT(3)
>> +#define OV1063X_ISP_RW06_YUV_MODE_MAN_EN BIT(2)
>> +#define OV1063X_ISP_CTRL3D OV1063X_REG_8BIT(0x503d)
>> +#define OV1063X_ISP_CTRL3D_TEST_PATTERN_EN BIT(7)
>> +#define OV1063X_ISP_CTRL3D_COLOR_BAR(n) ((n) << 4)
>> +#define OV1063X_ISP_CTRL3D_ROLLING_BAR_EN BIT(2)
>> +#define OV1063X_ISP_CTRL3E OV1063X_REG_8BIT(0x503e)
>> +#define OV1063X_ISP_CTRL3E_SQUARE_BW BIT(3)
>> +#define OV1063X_ISP_CTRL3E_TRANSPARENT_EN BIT(2)
>> +#define OV1063X_ISP_CTRL3E_PATTERN_BARS (0U << 0)
>> +#define OV1063X_ISP_CTRL3E_PATTERN_RANDOM (1U << 0)
>> +#define OV1063X_ISP_CTRL3E_PATTERN_SQUARES (2U << 0)
>> +
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_B_LONG OV1063X_REG_16BIT(0x5100)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_GB_LONG OV1063X_REG_16BIT(0x5102)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_GR_LONG OV1063X_REG_16BIT(0x5104)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_R_LONG OV1063X_REG_16BIT(0x5106)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_B_LONG OV1063X_REG_16BIT(0x5108)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_GB_LONG OV1063X_REG_16BIT(0x510a)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_GR_LONG OV1063X_REG_16BIT(0x510c)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_R_LONG OV1063X_REG_16BIT(0x510e)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_B_SHORT OV1063X_REG_16BIT(0x5110)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_GB_SHORT OV1063X_REG_16BIT(0x5112)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_GR_SHORT OV1063X_REG_16BIT(0x5114)
>> +#define OV1063X_GAIN_AWB_MAN_GAIN_R_SHORT OV1063X_REG_16BIT(0x5116)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_B_SHORT OV1063X_REG_16BIT(0x5118)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_GB_SHORT OV1063X_REG_16BIT(0x511a)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_GR_SHORT OV1063X_REG_16BIT(0x511c)
>> +#define OV1063X_GAIN_AWB_MAN_OFFSET_R_SHORT OV1063X_REG_16BIT(0x511e)
>> +#define OV1063X_GAIN_AWB_CTRL32 OV1063X_REG_8BIT(0x5120)
>> +#define OV1063X_GAIN_AWB_CTRL32_MANUAL_EN BIT(0)
>> +
>> +#define OV1063X_DNS_NOISE_Y_LIST_LONG(n) OV1063X_REG_8BIT(0x521a + (n))
>> +#define OV1063X_DNS_NOISE_UV_LIST_LONG(n) OV1063X_REG_16BIT(0x5222 + (n) * 2)
>> +#define OV1063X_DNS_GBGR_EXTRA_SHORT OV1063X_REG_8BIT(0x5241)
>> +#define OV1063X_DNS_NOISE_Y_LIST_SHORT(n) OV1063X_REG_8BIT(0x5242 + (n))
>> +#define OV1063X_DNS_NOISE_UV_LIST_SHORT(n) OV1063X_REG_16BIT(0x5249 + (n) * 2)
>> +#define OV1063X_CIP_UNSHARPEN_MASK_LONG(n) OV1063X_REG_8BIT(0x5288 + (n))
>> +#define OV1063X_CIP_MAX_SHARPEN_LONG OV1063X_REG_8BIT(0x528d)
>> +#define OV1063X_CIP_SHARPEN_ALPHA_LONG OV1063X_REG_8BIT(0x5293)
>> +#define OV1063X_CIP_UNSHARPEN_MASK_SHORT(n) OV1063X_REG_8BIT(0x52c8 + (n))
>> +#define OV1063X_CIP_MAX_SHARPEN_SHORT OV1063X_REG_8BIT(0x52cd)
>> +#define OV1063X_CIP_SHARPEN_ALPHA_SHORT OV1063X_REG_8BIT(0x52d3)
>> +#define OV1063X_CIP_HFREQ_COEF_SHORT OV1063X_REG_8BIT(0x52d7)
>> +
>> +#define OV1063X_LLF_MAX_LOW_LEVEL OV1063X_REG_16BIT(0x5381)
>> +
>> +#define OV1063X_AWB_CT_CTRL1 OV1063X_REG_8BIT(0x5581)
>> +#define OV1063X_AWB_CT_CTRL1_GAIN_STEP_NORMAL(n) ((n) << 6)
>> +#define OV1063X_AWB_CT_CTRL1_GAIN_STEP_FAST(n) ((n) << 4)
>> +#define OV1063X_AWB_CT_CTRL1_SCALE_LONG_2X (0 << 2)
>> +#define OV1063X_AWB_CT_CTRL1_SCALE_LONG_4X (1 << 2)
>> +#define OV1063X_AWB_CT_CTRL1_SCALE_LONG_8X (2 << 2)
>> +#define OV1063X_AWB_M_RNG_LONG OV1063X_REG_8BIT(0x5586)
>> +#define OV1063X_AWB_L_XRNG_LONG OV1063X_REG_8BIT(0x5587)
>> +#define OV1063X_AWB_H_YRNG_LONG OV1063X_REG_8BIT(0x5588)
>> +#define OV1063X_AWB_M_X_LONG OV1063X_REG_8BIT(0x5589)
>> +#define OV1063X_AWB_M_Y_LONG OV1063X_REG_8BIT(0x558a)
>> +#define OV1063X_AWB_L_K_LONG OV1063X_REG_8BIT(0x558b)
>> +#define OV1063X_AWB_H_K_LONG OV1063X_REG_8BIT(0x558c)
>> +#define OV1063X_AWB_H_LMT_LONG OV1063X_REG_8BIT(0x558d)
>> +#define OV1063X_AWB_L_LMT_LONG OV1063X_REG_8BIT(0x558e)
>> +#define OV1063X_AWB_DATA_ULMT_LONG OV1063X_REG_8BIT(0x5591)
>> +#define OV1063X_AWB_DATA_LLMT_LONG OV1063X_REG_8BIT(0x5592)
>> +#define OV1063X_AWB_M_RNG_SHORT OV1063X_REG_8BIT(0x559f)
>> +#define OV1063X_AWB_L_XRNG_SHORT OV1063X_REG_8BIT(0x55a0)
>> +#define OV1063X_AWB_H_YRNG_SHORT OV1063X_REG_8BIT(0x55a1)
>> +#define OV1063X_AWB_M_X_SHORT OV1063X_REG_8BIT(0x55a2)
>> +#define OV1063X_AWB_M_Y_SHORT OV1063X_REG_8BIT(0x55a3)
>> +#define OV1063X_AWB_L_K_SHORT OV1063X_REG_8BIT(0x55a4)
>> +#define OV1063X_AWB_H_K_SHORT OV1063X_REG_8BIT(0x55a5)
>> +#define OV1063X_AWB_H_LMT_SHORT OV1063X_REG_8BIT(0x55a6)
>> +#define OV1063X_AWB_L_LMT_SHORT OV1063X_REG_8BIT(0x55a7)
>> +#define OV1063X_AWB_DATA_ULMT_SHORT OV1063X_REG_8BIT(0x55aa)
>> +#define OV1063X_AWB_DATA_LLMT_SHORT OV1063X_REG_8BIT(0x55ab)
>> +
>> +#define OV1063X_AEC_CTRL07 OV1063X_REG_16BIT(0x5607)
>> +#define OV1063X_AEC_WIN_LEFT_LONG OV1063X_REG_16BIT(0x5609)
>> +#define OV1063X_AEC_WIN_LEFT_SHORT OV1063X_REG_16BIT(0x560b)
>> +#define OV1063X_AEC_WIN_TOP_LONG OV1063X_REG_16BIT(0x560d)
>> +#define OV1063X_AEC_WIN_TOP_SHORT OV1063X_REG_16BIT(0x560f)
>> +#define OV1063X_AEC_WIN_WIDTH_LONG OV1063X_REG_16BIT(0x5611)
>> +#define OV1063X_AEC_WIN_WIDTH_SHORT OV1063X_REG_16BIT(0x5613)
>> +#define OV1063X_AEC_WIN_HEIGHT_LONG OV1063X_REG_16BIT(0x5615)
>> +#define OV1063X_AEC_WIN_HEIGHT_SHORT OV1063X_REG_16BIT(0x5617)
>> +#define OV1063X_AEC_WEIGHT_SHORT(n) OV1063X_REG_8BIT(0x563b + (n))
>> +#define OV1063X_AEC_FINAL_SATURATE_THRESH OV1063X_REG_16BIT(0x5651)
>> +#define OV1063X_AEC_CTRLD0 OV1063X_REG_8BIT(0x56d0)
>> +#define OV1063X_AEC_CTRLD0_R_MAN_EN(n) ((n) << 0)
>> +#define OV1063X_AEC_CTRLD5 OV1063X_REG_32BIT(0x56d5) /* r_exp_l_m */
>> +#define OV1063X_AEC_CTRLD9 OV1063X_REG_32BIT(0x56d9) /* r_exp_s_m */
>> +#define OV1063X_AEC_CTRLE8 OV1063X_REG_16BIT(0x56e8) /* r_snrgain_l_m */
>> +#define OV1063X_AEC_CTRLEA OV1063X_REG_16BIT(0x56ea) /* r_snrgain_s_m */
>> +
>> +#define OV1063X_TPM_SLOPE(n) OV1063X_REG_8BIT(0x6700 + (n))
>> +#define OV1063X_TPM_OFFSET(n) OV1063X_REG_8BIT(0x6702 + (n))
>> +#define OV1063X_TPM_CTRL6 OV1063X_REG_8BIT(0x6706)
>> +#define OV1063X_TPM_CTRL6_CLK_DIV(n) ((n) << 0)
>> +
>> +#define OV1063X_GROUP_WRITER_COMMAND OV1063X_REG_8BIT(0x6f00)
>> +#define OV1063X_GROUP_WRITER_COMMAND_OP(n) ((n) << 6)
>> +#define OV1063X_GROUP_WRITER_COMMAND_ID(n) ((n) << 4)
>> +#define OV1063X_GROUP_WRITER_COMMAND_EN (3U << 0)
>> +#define OV1063X_PARI_ADDR_MIN OV1063X_REG_16BIT(0x6f06)
>> +#define OV1063X_PARI_ADDR_MAX OV1063X_REG_16BIT(0x6f0a)
>> +
>> +#define OV1063X_EMB_LINE_EN OV1063X_REG_8BIT(0x6800)
>> +#define OV1063X_EMB_LINE_EN_ENABLE BIT(0)
>> +#define OV1063X_EMB_SIZE_MANU_EN OV1063X_REG_8BIT(0x6804)
>> +#define OV1063X_EMB_SIZE_EN_ENABLE BIT(0)
>> +#define OV1063X_EMB_SIZE_MANU OV1063X_REG_16BIT(0x6805)
>> +
>> +#define OV1063X_HORIZ_COLORCORRECT OV1063X_REG_8BIT(0x6900)
>> +#define OV1063X_HORIZ_COLORCORRECT_ON BIT(0)
>> +
>> +#define OV1063X_AEC_TARGET_NUM OV1063X_REG_8BIT(0xc450)
>> +#define OV1063X_AEC_TARGET_NUM_AA_MODE (1U << 0)
>> +#define OV1063X_AEC_TARGET_NUM_AB_MODE (2U << 0)
>> +#define OV1063X_AEC_TARGET_NUM_ABC_MODE (3U << 0)
>> +#define OV1063X_AEC_LS_SENS_RATIO OV1063X_REG_16BIT(0xc452)
>> +#define OV1063X_AEC_NONWDR_EN OV1063X_REG_8BIT(0xc454)
>> +#define OV1063X_AEC_NONWDR_SWITCH OV1063X_REG_8BIT(0xc455)
>> +#define OV1063X_AEC_FIXED_RATIO_EN OV1063X_REG_8BIT(0xc456)
>> +#define OV1063X_AEC_GP_MODE_EN OV1063X_REG_8BIT(0xc457)
>> +#define OV1063X_AEC_NIGHT_MODE_EN OV1063X_REG_8BIT(0xc458)
>> +#define OV1063X_AEC_NIGHT_MODE_CTRL OV1063X_REG_8BIT(0xc459)
>> +#define OV1063X_AEC_NIGHT_MODE_CTRL_INSERT BIT(0)
>> +#define OV1063X_AEC_FRACTAL_EXP_EN OV1063X_REG_8BIT(0xc45a)
>> +#define OV1063X_AEC_NONLINEAR_GAIN_EN OV1063X_REG_8BIT(0xc45b)
>> +#define OV1063X_AEC_MANU_GAMMA_EN OV1063X_REG_8BIT(0xc45c)
>> +#define OV1063X_AEC_HOLD_BAND_EN OV1063X_REG_8BIT(0xc45d)
>> +#define OV1063X_AEC_BAND_FILTER_FLAG OV1063X_REG_8BIT(0xc45e)
>> +#define OV1063X_AEC_BAND_FILTER_FLAG_0HZ (0U << 0)
>> +#define OV1063X_AEC_BAND_FILTER_FLAG_60HZ (1U << 0)
>> +#define OV1063X_AEC_BAND_FILTER_FLAG_50HZ (2U << 0)
>> +#define OV1063X_AEC_BAND_FILTER_EN OV1063X_REG_8BIT(0xc45f)
>> +#define OV1063X_AEC_BAND_FILTER_SHORT OV1063X_REG_8BIT(0xc460)
>> +#define OV1063X_AEC_LESS_1BAND_EN OV1063X_REG_8BIT(0xc461)
>> +#define OV1063X_AEC_LESS_1BAND_SHORT OV1063X_REG_8BIT(0xc462)
>> +#define OV1063X_AEC_WDR_GAIN_LIMIT_EN OV1063X_REG_8BIT(0xc463)
>> +#define OV1063X_AEC_LOG_TARGET(n) OV1063X_REG_16BIT(0xc464 + (n) * 2)
>> +#define OV1063X_AEC_TARGET_LONG(n) OV1063X_REG_8BIT(0xc46a + (n))
>> +#define OV1063X_AEC_TARGET_SHORT(n) OV1063X_REG_8BIT(0xc46d + (n))
>> +#define OV1063X_AEC_MAX_SHORT_LE OV1063X_REG_32BIT(0xc47c)
>> +#define OV1063X_AEC_MAX_GAIN_LONG OV1063X_REG_16BIT(0xc480)
>> +#define OV1063X_AEC_MAX_GAIN_SHORT OV1063X_REG_16BIT(0xc482)
>> +#define OV1063X_AEC_MIN_GAIN_LONG OV1063X_REG_16BIT(0xc484)
>> +#define OV1063X_AEC_MIN_GAIN_SHORT OV1063X_REG_16BIT(0xc486)
>> +#define OV1063X_AEC_MAX_EXP_LONG OV1063X_REG_16BIT(0xc488)
>> +#define OV1063X_AEC_MAX_EXP_SHORT OV1063X_REG_16BIT(0xc48a)
>> +#define OV1063X_AEC_MIN_EXP_LONG OV1063X_REG_16BIT(0xc48c)
>> +#define OV1063X_AEC_MIN_EXP_SHORT OV1063X_REG_16BIT(0xc48e)
>> +#define OV1063X_AEC_FIXED_RATIO OV1063X_REG_8BIT(0xc490)
>> +#define OV1063X_AEC_GP_MODE_RATIO_B2A OV1063X_REG_8BIT(0xc492)
>> +#define OV1063X_AEC_GP_MODE_RATIO_C2A OV1063X_REG_8BIT(0xc493)
>> +#define OV1063X_AEC_MIN_GAMMA_LIST(n) OV1063X_REG_16BIT(0xc498 + (n) * 2)
>> +#define OV1063X_AEC_MAX_GAMMA_LIST(n) OV1063X_REG_16BIT(0xc49e + (n) * 2)
>> +#define OV1063X_AEC_DR_LIST(n) OV1063X_REG_16BIT(0xc4a4 + (n) * 2)
>> +#define OV1063X_AEC_BAND_VALUE_60HZ OV1063X_REG_16BIT(0xc4aa)
>> +#define OV1063X_AEC_BAND_VALUE_50HZ OV1063X_REG_16BIT(0xc4ac)
>> +
>> +#define OV1063X_AWB_SIMPLE_MIN_NUM OV1063X_REG_16BIT(0xc4cc)
>> +#define OV1063X_AWB_CT_MIN_NUM OV1063X_REG_16BIT(0xc4ce)
>> +
>> +#define OV1063X_VTS_ADDR OV1063X_REG_16BIT(0xc518)
>> +#define OV1063X_HTS_ADDR OV1063X_REG_16BIT(0xc51a)
>> +
>> +#include "ov1063x_regs.h"
>> +
>> +/* IDs */
>> +#define OV10633_VERSION_REG 0xa630
>> +#define OV10635_VERSION_REG 0xa635
>> +
>> +enum ov1063x_model {
>> + SENSOR_OV10633,
>> + SENSOR_OV10635,
>> +};
>> +
>> +enum ov1063x_streaming_state {
>> + OV1063X_STREAM_OFF = 0,
>> + OV1063X_STREAM_STARTING,
>> + OV1063X_STREAM_ON,
>> +};
>> +
>> +#define OV1063X_SENSOR_WIDTH 1312
>> +#define OV1063X_SENSOR_HEIGHT 814
>> +
>> +struct ov1063x_priv {
>> + struct device *dev;
>> +
>> + struct regmap *regmap;
>> + struct clk *clk;
>> + struct gpio_desc *reset_gpio;
>> + struct gpio_desc *pwdn_gpio;
>> +
>> + int model;
>> + const char *name;
>> + unsigned long clk_rate;
>> +
>> + struct v4l2_subdev subdev;
>> + struct media_pad pad;
>> +
>> + struct v4l2_ctrl_handler hdl;
>> +
>> + /*
>> + * The streaming and format fields are protected by the control handler
>> + * lock.
>> + */
>> + enum ov1063x_streaming_state streaming;
>> + struct v4l2_rect analog_crop;
>> + struct v4l2_rect digital_crop;
>> + struct v4l2_mbus_framefmt format;
>> +
>> + unsigned int fps_numerator;
>> + unsigned int fps_denominator;
>> +};
>> +
>> +/*
>> + * TODO: Expose multiple subdevs to control cropping and subsampling separately
>> + * from userspace instead of hardcoding resolutions.
>> + *
>> + * TODO: Resolutions with an analog crop rectangle width equal to 768 or higher
>> + * don't work properly.
>> + */
>> +static const struct v4l2_area ov1063x_framesizes[] = {
>> + {
>> + .width = 1280,
>> + .height = 800,
>> + }, {
>> + .width = 1280,
>> + .height = 720,
>> + }, {
>> + .width = 752,
>> + .height = 480,
>> + }, {
>> + .width = 640,
>> + .height = 480,
>> + }, {
>> + .width = 600,
>> + .height = 400,
>> + }, {
>
> I have an issue when 600x400 is requested on the ov10635 from the TI tree VIP
> driver, on the am57xx-evm platform.
>
> With this resolution (any bus format), output is very dark, we only see very
> bright objects (light bulbs). It seems IPS doesn't drive exposure correctly
> or ISP doesn't have the right parameters.
>
> But while testing the colorbars, the output is also wrong:
>
> Command:
> # v4l2-ctl -d1 --set-ctrl test_pattern=1 --set-fmt-video=pixelformat=YUYV,width=600,height=400 --stream-to=out.raw --stream-count=10 --stream-poll --stream-mmap=20
>
> https://people.freedesktop.org/~narmstrong/ov1065x-600-400-YUYV-colorbar.png
>
> VIP log is:
> [12324.323181] vin3a: vip_init_port: g_mbus_fmt subdev mbus_code: 2006 fourcc:NV12 size: 600x400
> [12324.323211] vin3a: calc_format_size: fourcc:NV12 size: 600x400 bpl:608 img_size:364800
> [12324.323211] vin3a-0: init_stream fourcc:NV12 size: 600x400 bpl:608 img_size:364800
> [12324.323211] vin3a-0: init_stream vpdma data type: 0x02
> [12324.323242] vin3a-0: vip_init_stream: stream instance 0x00000000c267b000
> [12324.323455] vin3a-0: g_fmt fourcc:NV12 code: 2006 size: 600x400 bpl:608 img_size:364800
> [12324.323455] vin3a-0: g_fmt vpdma data type: 0x02
> [12324.323486] vin3a-0: enum_fmt index:0
> [12324.323486] vin3a-0: enum_fmt fourcc:NV12
> [12324.323486] vin3a-0: enum_fmt index:1
> [12324.323516] vin3a-0: enum_fmt fourcc:UYVY
> [12324.323516] vin3a-0: enum_fmt index:2
> [12324.323516] vin3a-0: enum_fmt fourcc:YUYV
> [12324.323547] vin3a-0: s_fmt input fourcc:YUYV size: 600x400 bpl:0 img_size:364800
> [12324.323547] vin3a-0: try_fmt fourcc:YUYV size: 600x400
> [12324.323547] vin3a-0: try_fmt loop:0 fourcc:YUYV size: 1280x800
> [12324.323577] vin3a-0: try_fmt loop:0 found new larger: 1280x800
> [12324.323577] vin3a-0: try_fmt loop:0 found at least larger: 1280x800
> [12324.323577] vin3a-0: try_fmt loop:0 found new best: 1280x800
> [12324.323577] vin3a-0: try_fmt loop:1 fourcc:YUYV size: 1280x720
> [12324.323608] vin3a-0: try_fmt loop:1 found at least larger: 1280x720
> [12324.323608] vin3a-0: try_fmt loop:1 found new best: 1280x720
> [12324.323608] vin3a-0: try_fmt loop:2 fourcc:YUYV size: 752x480
> [12324.323608] vin3a-0: try_fmt loop:2 found at least larger: 752x480
> [12324.323638] vin3a-0: try_fmt loop:2 found new best: 752x480
> [12324.323638] vin3a-0: try_fmt loop:3 fourcc:YUYV size: 640x480
> [12324.323638] vin3a-0: try_fmt loop:3 found at least larger: 640x480
> [12324.323638] vin3a-0: try_fmt loop:3 found new best: 640x480
> [12324.323669] vin3a-0: try_fmt loop:4 fourcc:YUYV size: 600x400
> [12324.323669] vin3a-0: try_fmt loop:4 found at least larger: 600x400
> [12324.323669] vin3a-0: try_fmt loop:4 found new best: 600x400
> [12324.323669] vin3a-0: try_fmt loop:4 found direct match: 600x400
> [12324.323699] vin3a: calc_format_size: fourcc:YUYV size: 600x400 bpl:1200 img_size:480000
> [12324.323699] vin3a-0: s_fmt try_fmt fourcc:YUYV size: 600x400 bpl:1200 img_size:480000
> [12324.323699] vin3a-0: s_fmt fourcc:YUYV size: 600x400 bpl:1200 img_size:480000
> [12324.323730] vin3a-0: s_fmt pix_to_mbus mbus_code: 2006 size: 600x400
> [12324.323730] vin3a-0: s_fmt subdev fmt mbus_code: 2006 size: 600x400
> [12324.323730] vin3a-0: s_fmt vpdma data type: 0x07
>
> ov10635 is correctly set with 600x400 and VIP is pass-throught.
>
> The image & colorbar is OK with any other framesizes requested to ov10635.
>
> Is this a known issue ?
>
> Neil
>
>> + .width = 352,
>> + .height = 288,
>> + }, {
>> + .width = 320,
>> + .height = 240,
>> + },
>> +};
>> +
>> +static const u32 ov1063x_mbus_formats[] = {
>> + MEDIA_BUS_FMT_YUYV8_2X8,
>> + MEDIA_BUS_FMT_UYVY8_2X8,
>> + MEDIA_BUS_FMT_VYUY8_2X8,
>> + MEDIA_BUS_FMT_YVYU8_2X8,
>> +};
>> +
>> +static inline struct ov1063x_priv *to_ov1063x(struct v4l2_subdev *sd)
>> +{
>> + return container_of(sd, struct ov1063x_priv, subdev);
>> +}
>> +
>> +/* -----------------------------------------------------------------------------
>> + * Read/Write Helpers
>> + */
>> +
>> +static int ov1063x_read(struct ov1063x_priv *priv, u32 reg, u32 *val)
>> +{
>> + unsigned int len = (reg >> OV1063X_REG_SIZE_SHIFT) & 3;
>> + u16 addr = reg & OV1063X_REG_ADDR_MASK;
>> + unsigned int i;
>> + int ret;
>> +
>> + *val = 0;
>> +
>> + for (i = 0; i < len; ++i) {
>> + u32 byte;
>> +
>> + ret = regmap_read(priv->regmap, addr, &byte);
>> + if (ret)
>> + return ret;
>> +
>> + *val = (*val << 8) | byte;
>> + addr++;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_write(struct ov1063x_priv *priv, u32 reg, u32 val, int *err)
>> +{
>> + unsigned int len = (reg >> OV1063X_REG_SIZE_SHIFT) & 7;
>> + u16 addr = reg & OV1063X_REG_ADDR_MASK;
>> + unsigned int shift = (len - 1) * 8;
>> + unsigned int i;
>> + int ret;
>> +
>> + if (err && *err)
>> + return *err;
>> +
>> + for (i = 0; i < len; ++i) {
>> + ret = regmap_write(priv->regmap, addr, (val >> shift) & 0xff);
>> + if (ret) {
>> + if (err)
>> + *err = ret;
>> + return ret;
>> + }
>> +
>> + shift -= 8;
>> + addr++;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_write_array(struct ov1063x_priv *priv,
>> + const struct ov1063x_reg *regs,
>> + unsigned int nr_regs)
>> +{
>> + unsigned int i;
>> + int ret;
>> +
>> + for (i = 0; i < nr_regs; i++) {
>> + ret = ov1063x_write(priv, regs[i].reg, regs[i].val, NULL);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_update(struct ov1063x_priv *priv, u32 reg, u32 mask, u32 val,
>> + int *err)
>> +{
>> + unsigned int len = (reg >> OV1063X_REG_SIZE_SHIFT) & 7;
>> + u16 addr = reg & OV1063X_REG_ADDR_MASK;
>> + unsigned int shift = (len - 1) * 8;
>> + unsigned int i;
>> + int ret;
>> +
>> + if (err && *err)
>> + return *err;
>> +
>> + for (i = 0; i < len; ++i) {
>> + ret = regmap_update_bits(priv->regmap, addr,
>> + (mask >> shift) & 0xff,
>> + (val >> shift) & 0xff);
>> + if (ret) {
>> + if (err)
>> + *err = ret;
>> + return ret;
>> + }
>> +
>> + shift -= 8;
>> + addr++;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/* -----------------------------------------------------------------------------
>> + * Hardware Configuration
>> + */
>> +
>> +struct ov1063x_pll_config {
>> + unsigned int pre_div;
>> + unsigned int mult;
>> + unsigned int div;
>> + unsigned int clk_out;
>> +};
>> +
>> +static int ov1063x_pll_setup(unsigned int clk_rate,
>> + unsigned int *htsmin, unsigned int vts,
>> + unsigned int fps_numerator,
>> + unsigned int fps_denominator,
>> + struct ov1063x_pll_config *cfg)
>> +{
>> + unsigned int best_pclk = UINT_MAX;
>> + unsigned int best_pre_div_x2;
>> + unsigned int best_mult;
>> + unsigned int best_div;
>> + unsigned int best_hts;
>> + unsigned int max_pre_div_x2;
>> + unsigned int pre_div_x2;
>> + unsigned int hts;
>> +
>> + /*
>> + * XVCLK --> pre-div -------> mult ----------> div --> output
>> + * 6-27 MHz 3-27 MHz 200-500 MHz Max 96 MHz
>> + *
>> + * Valid pre-divider values are 1, 1.5, 2, 3, 4, 5, 6 and 7, stored in
>> + * registers as the index in this list of values.
>> + *
>> + * Valid multiplier values are [1, 63], stored as-is in registers.
>> + *
>> + * Valid divider values are 2 to 16 with a step of 2, stored in
>> + * registers as (div / 2) - 1.
>> + */
>> +
>> + if (clk_rate < 6 * 1000 * 1000 || clk_rate > 27 * 1000 * 1000)
>> + return -EINVAL;
>> +
>> + /*
>> + * We try all valid combinations of settings for the 3 blocks to get
>> + * the pixel clock, and from that calculate the actual hts/vts to use.
>> + * The vts is extended so as to achieve the required frame rate.
>> + */
>> +
>> + /*
>> + * The pre_div_x2 variable stores the pre-div value multiplied by 2, to
>> + * support the fractional divider 1.5.
>> + */
>> + max_pre_div_x2 = min(clk_rate * 2 / (3 * 1000 * 1000), 14U);
>> +
>> + for (pre_div_x2 = 2; pre_div_x2 <= max_pre_div_x2;
>> + pre_div_x2 += (pre_div_x2 < 4 ? 1 : 2)) {
>> + unsigned int clk1 = clk_rate * 2 / pre_div_x2;
>> + unsigned int min_mult;
>> + unsigned int max_mult;
>> + unsigned int mult;
>> +
>> + if (clk1 < 3 * 1000 * 1000 || clk1 > 27 * 1000 * 1000)
>> + continue;
>> +
>> + min_mult = DIV_ROUND_UP(200 * 1000 * 1000, clk1);
>> + max_mult = min(500 * 1000 * 1000 / clk1, 63U);
>> +
>> + for (mult = min_mult; mult <= max_mult; mult++) {
>> + unsigned int clk2 = clk1 * mult;
>> + unsigned int min_div;
>> + unsigned int div;
>> +
>> + min_div = DIV_ROUND_UP(clk2, 96 * 1000 * 1000);
>> + min_div = round_up(min_div, 2);
>> +
>> + for (div = min_div; div <= 16; div += 2) {
>> + unsigned int pclk = clk2 / div;
>> + unsigned int min_pclk;
>> +
>> + /*
>> + * TODO: HTS calculation should ideally be split
>> + * from the PLL calculations. This requires
>> + * figuring out where the pclk / 300000 comes
>> + * from.
>> + */
>> + hts = *htsmin + pclk / (300*1000);
>> +
>> + /* 2 clock cycles for every YUV422 pixel. */
>> + min_pclk = hts * vts / fps_denominator
>> + * fps_numerator * 2;
>> + if (pclk < min_pclk)
>> + continue;
>> +
>> + if (pclk < best_pclk) {
>> + best_pclk = pclk;
>> + best_hts = hts;
>> + best_pre_div_x2 = pre_div_x2;
>> + best_mult = mult;
>> + best_div = div;
>> + }
>> + }
>> + }
>> + }
>> +
>> + if (best_pclk == UINT_MAX)
>> + return -EINVAL;
>> +
>> + /* Store the mult, pre_div and div as register values. */
>> + cfg->mult = best_mult;
>> + cfg->pre_div = best_pre_div_x2 < 4 ? best_pre_div_x2 - 2
>> + : best_pre_div_x2 / 2;
>> + cfg->div = (best_div / 2) - 1;
>> + cfg->clk_out = best_pclk;
>> +
>> + *htsmin = best_hts;
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_isp_reset(struct ov1063x_priv *priv, bool reset)
>> +{
>> + unsigned int i;
>> + int ret = 0;
>> +
>> + if (!reset) {
>> + /*
>> + * Enable ISP blocks. Why OV1063X_SC_SOC_CLKRST7 needs to be
>> + * written 26 times is unknown.
>> + */
>> + for (i = 0; i < 26; ++i)
>> + ov1063x_write(priv, OV1063X_SC_SOC_CLKRST7,
>> + OV1063X_SC_SOC_CLKRST7_SCLK, &ret);
>> +
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST1,
>> + OV1063X_SC_CMMN_CLKRST1_SCLK, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST2,
>> + OV1063X_SC_CMMN_CLKRST2_PCLK_DVP |
>> + OV1063X_SC_CMMN_CLKRST2_SCLK, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST0,
>> + OV1063X_SC_CMMN_CLKRST0_SCLK, &ret);
>> + } else {
>> + /* Reset the ISP. */
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST1,
>> + OV1063X_SC_CMMN_CLKRST1_SCLK |
>> + OV1063X_SC_CMMN_CLKRST1_RST, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST2,
>> + OV1063X_SC_CMMN_CLKRST2_PCLK_DVP |
>> + OV1063X_SC_CMMN_CLKRST2_SCLK |
>> + OV1063X_SC_CMMN_CLKRST2_RST_DVP |
>> + OV1063X_SC_CMMN_CLKRST2_RST, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST0,
>> + OV1063X_SC_CMMN_CLKRST0_SCLK |
>> + OV1063X_SC_CMMN_CLKRST0_RST, &ret);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static int ov1063x_configure(struct ov1063x_priv *priv)
>> +{
>> + struct ov1063x_pll_config pll_cfg;
>> + unsigned int width_pre_subsample;
>> + unsigned int nr_isp_pixels;
>> + unsigned int hts, vts;
>> + u32 val;
>> + int ret;
>> +
>> + /* Minimum values for HTS anv VTS. */
>> + hts = priv->analog_crop.width + 200;
>> + vts = priv->analog_crop.height + 50;
HTS calculation seems fishy, with the following change:
=====><========================================================================
--- a/drivers/media/i2c/ov1063x.c
+++ b/drivers/media/i2c/ov1063x.c
@@ -799,7 +799,7 @@ static int ov1063x_configure(struct ov1063x_priv *priv)
int ret;
/* Minimum values for HTS anv VTS. */
- hts = priv->analog_crop.width + 200;
+ hts = priv->analog_crop.width + 210;
=====><========================================================================
I get functional 600x400 framesize.
I got the change from [1], thus not related to the same frame size.
Neil
[1] https://github.com/slawr/linux-stable/commit/8509859572e0f333850f45dd0c1529bed09da051
>> +
>> + /*
>> + * Get the best PCLK and adjust HTS accordingly. Adjust VTS to get as
>> + * close to the desired frame rate as we can.
>> + */
>> + ret = ov1063x_pll_setup(priv->clk_rate, &hts, vts,
>> + priv->fps_numerator, priv->fps_denominator,
>> + &pll_cfg);
>> + if (ret < 0)
>> + return -EINVAL;
>> +
>> + vts = pll_cfg.clk_out
>> + / (hts * 2 * priv->fps_numerator / priv->fps_denominator);
>> +
>> + dev_dbg(priv->dev, "active %ux%u (total %ux%u) %u/%u fps, @%u MP/s\n",
>> + priv->format.width, priv->format.height,
>> + hts, vts, priv->fps_numerator, priv->fps_denominator,
>> + pll_cfg.clk_out);
>> + dev_dbg(priv->dev, "PLL pre-div %u mult %u div %u\n",
>> + pll_cfg.pre_div, pll_cfg.mult, pll_cfg.div);
>> +
>> + /* Reset the ISP and configure the PLL. */
>> + ret = ov1063x_isp_reset(priv, true);
>> +
>> + ov1063x_write(priv, OV1063X_SC_CMMN_PLL_CTRL0, pll_cfg.mult, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_PLL_CTRL1,
>> + (pll_cfg.pre_div << 4) | pll_cfg.div, &ret);
>> +
>> + /* Analog array configuration (including horizontal cropping) */
>> + switch (priv->analog_crop.width) {
>> + case OV1063X_SENSOR_WIDTH:
>> + default:
>> + val = 0x60 | OV1063X_ANA_ARRAY1_FULL
>> + | OV1063X_ANA_ARRAY1_DELAY(3);
>> + break;
>> + case 768:
>> + val = 0x60 | OV1063X_ANA_ARRAY1_CROP_768
>> + | OV1063X_ANA_ARRAY1_DELAY(3);
>> + break;
>> + case 656:
>> + val = 0x60 | OV1063X_ANA_ARRAY1_CROP_656
>> + | OV1063X_ANA_ARRAY1_DELAY(3);
>> + break;
>> + }
>> +
>> + ov1063x_write(priv, OV1063X_ANA_ARRAY1, val, &ret);
>> +
>> + /* Sensor configuration */
>> + ov1063x_write(priv, OV1063X_SENSOR_RSTGOLOW,
>> + (pll_cfg.clk_out + 1500000) / 3000000, &ret);
>> + ov1063x_write(priv, OV1063X_SENSOR_HLDWIDTH,
>> + (pll_cfg.clk_out + 666666) / 1333333, &ret);
>> + ov1063x_write(priv, OV1063X_SENSOR_TXWIDTH,
>> + (pll_cfg.clk_out + 961500) / 1923000, &ret);
>> +
>> + /*
>> + * Timings (including cropping)
>> + *
>> + * TODO: The vertical size is set to the height of the analog crop
>> + * rectangle plus 4 pixels. This margin is probably used by the ISP for
>> + * CFA interpolation, and should be moved to the crop rectangle height
>> + * after investigating how the ISP operates.
>> + */
>> + ov1063x_write(priv, OV1063X_TIMING_Y_START_ADDR,
>> + priv->analog_crop.top, &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_Y_END_ADDR,
>> + priv->analog_crop.top + priv->analog_crop.height + 3,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_ISP_X_WIN, priv->digital_crop.left,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_ISP_Y_WIN, priv->digital_crop.top,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_X_OUTPUT_SIZE, priv->format.width,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_Y_OUTPUT_SIZE, priv->format.height,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_HTS, hts, &ret);
>> + ov1063x_write(priv, OV1063X_TIMING_VTS, vts, &ret);
>> +
>> + /*
>> + * Sub-sampling. Horizontal sub-sampling is applied in the ISP, vertical
>> + * sub-sampling in the pixel array.
>> + */
>> + if (priv->format.width <= 640) {
>> + ov1063x_write(priv, OV1063X_ISP_RW05, OV1063X_ISP_RW05_SUB_AVG |
>> + OV1063X_ISP_RW05_SUB_ENABLE, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_PCLK_DIV_CTRL, 2, &ret);
>> + } else {
>> + ov1063x_write(priv, OV1063X_ISP_RW05, OV1063X_ISP_RW05_SUB_AVG,
>> + &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_PCLK_DIV_CTRL, 1, &ret);
>> + }
>> +
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (priv->format.height <= 400)
>> + ret = ov1063x_write_array(priv, ov1063x_regs_vert_sub2,
>> + ARRAY_SIZE(ov1063x_regs_vert_sub2));
>> + else
>> + ret = ov1063x_write_array(priv, ov1063x_regs_vert_no_sub,
>> + ARRAY_SIZE(ov1063x_regs_vert_no_sub));
>> +
>> + /*
>> + * AEC & AWB
>> + *
>> + * TODO: The number of pixels fed to the ISP is computed using the
>> + * analog crop width and the vertical output size, to account for the
>> + * fact that vertical sub-sampling is applied in the pixel array while
>> + * horizontal sub-sampling is applied in the ISP. The 4 pixels margin
>> + * seems incorrect when sub-sampling, as the vertical timing start and
>> + * stop registers are programmed with a 4 pixels margin before
>> + * sub-sampling, the ISP should thus receive a 2 pixels margin only.
>> + * This needs to be investigated.
>> + *
>> + * TODO: When applying vertical digital crop, the output height is
>> + * likely the wrong value to compute the total number of pixels fed to
>> + * the ISP.
>> + */
>> + val = (vts - 8) * 16;
>> + ov1063x_write(priv, OV1063X_AEC_MAX_EXP_LONG, val, &ret);
>> + ov1063x_write(priv, OV1063X_AEC_MAX_EXP_SHORT, val, &ret);
>> +
>> + nr_isp_pixels = priv->analog_crop.width * (priv->format.height + 4);
>> + ov1063x_write(priv, OV1063X_AWB_SIMPLE_MIN_NUM, nr_isp_pixels / 256, &ret);
>> + ov1063x_write(priv, OV1063X_AWB_CT_MIN_NUM, nr_isp_pixels / 256, &ret);
>> + ov1063x_write(priv, OV1063X_REG_16BIT(0xc512), nr_isp_pixels / 16,
>> + &ret);
>> +
>> + ov1063x_write(priv, OV1063X_VTS_ADDR, vts, &ret);
>> + ov1063x_write(priv, OV1063X_HTS_ADDR, hts, &ret);
>> +
>> + /* FIFO */
>> + ov1063x_write(priv, OV1063X_VFIFO_LLEN_FIRS1_SEL,
>> + OV1063X_VFIFO_LLEN_FIRS1_SEL_8B_YUV, &ret);
>> + width_pre_subsample = priv->format.width <= 640
>> + ? priv->format.width * 2 : priv->format.width;
>> + ov1063x_write(priv, OV1063X_VFIFO_LINE_LENGTH_MAN, 2 * hts, &ret);
>> + ov1063x_write(priv, OV1063X_VFIFO_HSYNC_START_POSITION,
>> + 2 * (hts - width_pre_subsample), &ret);
>> +
>> + /* Output interface (DVP). */
>> + switch (priv->format.code) {
>> + case MEDIA_BUS_FMT_UYVY8_2X8:
>> + val = OV1063X_FORMAT_UYVY;
>> + break;
>> + case MEDIA_BUS_FMT_VYUY8_2X8:
>> + val = OV1063X_FORMAT_VYUY;
>> + break;
>> + case MEDIA_BUS_FMT_YUYV8_2X8:
>> + val = OV1063X_FORMAT_YUYV;
>> + break;
>> + case MEDIA_BUS_FMT_YVYU8_2X8:
>> + val = OV1063X_FORMAT_YYYU;
>> + break;
>> + default:
>> + val = OV1063X_FORMAT_UYVY;
>> + break;
>> + }
>> +
>> + ov1063x_write(priv, OV1063X_FORMAT_CTRL00, val, &ret);
>> + ov1063x_write(priv, OV1063X_DVP_MOD_SEL, 0, &ret);
>> +
>> + if (ret)
>> + return ret;
>> +
>> + /* Take the ISP out of reset. */
>> + return ov1063x_isp_reset(priv, false);
>> +}
>> +
>> +/* -----------------------------------------------------------------------------
>> + * V4L2 Control Operations
>> + */
>> +
>> +static const char * const ov1063x_test_pattern_menu[] = {
>> + "Disabled",
>> + "Color Bars, Plain",
>> + "Color Bars, Vertical Gradient",
>> + "Color Bars, Horizontal Gradient",
>> + "Color Bars, Repeating",
>> + "Random Data",
>> + "Squares, Color",
>> + "Squares, Black & White",
>> +};
>> +
>> +struct ov1063x_tpg_config {
>> + u8 ctrl3d;
>> + u8 ctrl3e;
>> +};
>> +
>> +static const struct ov1063x_tpg_config
>> +ov1063x_tpg_configs[ARRAY_SIZE(ov1063x_test_pattern_menu) - 1] = {
>> + {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN
>> + | OV1063X_ISP_CTRL3D_COLOR_BAR(0),
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_BARS,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN
>> + | OV1063X_ISP_CTRL3D_COLOR_BAR(1),
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_BARS,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN
>> + | OV1063X_ISP_CTRL3D_COLOR_BAR(2),
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_BARS,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN
>> + | OV1063X_ISP_CTRL3D_COLOR_BAR(3),
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_BARS,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN,
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_RANDOM,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN,
>> + .ctrl3e = OV1063X_ISP_CTRL3E_PATTERN_SQUARES,
>> + }, {
>> + .ctrl3d = OV1063X_ISP_CTRL3D_TEST_PATTERN_EN,
>> + .ctrl3e = OV1063X_ISP_CTRL3E_SQUARE_BW
>> + | OV1063X_ISP_CTRL3E_PATTERN_SQUARES,
>> + },
>> +};
>> +
>> +static int ov1063x_tpg_setup(struct ov1063x_priv *priv, struct v4l2_ctrl *ctrl)
>> +{
>> + const struct ov1063x_tpg_config *cfg;
>> + int ret = 0;
>> +
>> + if (!ctrl->val)
>> + return ov1063x_write_array(priv, ov1063x_regs_colorbar_disable,
>> + ARRAY_SIZE(ov1063x_regs_colorbar_disable));
>> +
>> + if (!ctrl->cur.val || priv->streaming == OV1063X_STREAM_STARTING) {
>> + /*
>> + * Only write the full settings when the test pattern was
>> + * disabled or when we start streaming, not when we're just
>> + * changing the test pattern type.
>> + */
>> + ret = ov1063x_write_array(priv, ov1063x_regs_colorbar_enable,
>> + ARRAY_SIZE(ov1063x_regs_colorbar_enable));
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + cfg = &ov1063x_tpg_configs[ctrl->val - 1];
>> +
>> + /* TODO: Add support for the moving bar overlay. */
>> + ov1063x_write(priv, OV1063X_ISP_CTRL3D, cfg->ctrl3d, &ret);
>> + ov1063x_write(priv, OV1063X_ISP_CTRL3E, cfg->ctrl3e, &ret);
>> +
>> + return ret;
>> +}
>> +
>> +static int ov1063x_s_ctrl(struct v4l2_ctrl *ctrl)
>> +{
>> + struct ov1063x_priv *priv = container_of(ctrl->handler,
>> + struct ov1063x_priv, hdl);
>> + int ret = 0;
>> +
>> + if (priv->streaming == OV1063X_STREAM_OFF)
>> + return 0;
>> +
>> + switch (ctrl->id) {
>> + case V4L2_CID_VFLIP: {
>> + const u32 vflip = OV1063X_TIMING_CTRL1C_VFLIP_DIG
>> + | OV1063X_TIMING_CTRL1C_VFLIP_ARRAY;
>> +
>> + return ov1063x_update(priv, OV1063X_TIMING_CTRL1C, vflip,
>> + ctrl->val ? vflip : 0, NULL);
>> + }
>> +
>> + case V4L2_CID_HFLIP: {
>> + const u32 hflip = OV1063X_TIMING_CTRL1D_HFLIP_DIG
>> + | OV1063X_TIMING_CTRL1D_HFLIP_ARRAY;
>> +
>> + ov1063x_update(priv, OV1063X_HORIZ_COLORCORRECT,
>> + OV1063X_HORIZ_COLORCORRECT_ON,
>> + ctrl->val ? OV1063X_HORIZ_COLORCORRECT_ON : 0,
>> + &ret);
>> + ov1063x_update(priv, OV1063X_TIMING_CTRL1D, hflip,
>> + ctrl->val ? hflip : 0, &ret);
>> + return ret;
>> + }
>> +
>> + case V4L2_CID_TEST_PATTERN:
>> + return ov1063x_tpg_setup(priv, ctrl);
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +
>> +static const struct v4l2_ctrl_ops ov1063x_ctrl_ops = {
>> + .s_ctrl = ov1063x_s_ctrl,
>> +};
>> +
>> +/* -----------------------------------------------------------------------------
>> + * V4L2 Subdev Operations
>> + */
>> +
>> +static int ov1063x_s_stream(struct v4l2_subdev *sd, int enable)
>> +{
>> + struct ov1063x_priv *priv = to_ov1063x(sd);
>> + int ret = 0;
>> +
>> + if (!enable) {
>> + ov1063x_write(priv, OV1063X_STREAM_MODE, 0, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST2,
>> + OV1063X_SC_CMMN_CLKRST2_SCLK, &ret);
>> +
>> + pm_runtime_mark_last_busy(priv->dev);
>> + pm_runtime_put_autosuspend(priv->dev);
>> +
>> + mutex_lock(priv->hdl.lock);
>> + priv->streaming = OV1063X_STREAM_OFF;
>> + mutex_unlock(priv->hdl.lock);
>> +
>> + return ret;
>> + }
>> +
>> + mutex_lock(priv->hdl.lock);
>> +
>> + /* Streaming needs to be true for ov1063x_s_ctrl() to proceed. */
>> + priv->streaming = OV1063X_STREAM_STARTING;
>> +
>> + ret = pm_runtime_get_sync(priv->dev);
>> + if (ret < 0)
>> + goto done;
>> +
>> + ret = ov1063x_configure(priv);
>> + if (ret < 0)
>> + goto done;
>> +
>> + ret = __v4l2_ctrl_handler_setup(&priv->hdl);
>> + if (ret < 0)
>> + goto done;
>> +
>> + ret = 0;
>> + ov1063x_write(priv, OV1063X_STREAM_MODE, OV1063X_STREAM_MODE_ON, &ret);
>> + ov1063x_write(priv, OV1063X_SC_CMMN_CLKRST2,
>> + OV1063X_SC_CMMN_CLKRST2_PCLK_DVP |
>> + OV1063X_SC_CMMN_CLKRST2_SCLK, &ret);
>> +
>> + priv->streaming = OV1063X_STREAM_ON;
>> +
>> +done:
>> + if (ret < 0) {
>> + /*
>> + * In case of error, turn the power off synchronously as the
>> + * device likely has no other chance to recover.
>> + */
>> + pm_runtime_put_sync(priv->dev);
>> + priv->streaming = OV1063X_STREAM_OFF;
>> + }
>> +
>> + mutex_unlock(priv->hdl.lock);
>> +
>> + return ret;
>> +}
>> +
>> +static struct v4l2_mbus_framefmt *
>> +__ov1063x_get_pad_format(struct ov1063x_priv *priv,
>> + struct v4l2_subdev_state *state,
>> + unsigned int pad, u32 which)
>> +{
>> + switch (which) {
>> + case V4L2_SUBDEV_FORMAT_TRY:
>> + return v4l2_subdev_get_try_format(&priv->subdev, state, pad);
>> + case V4L2_SUBDEV_FORMAT_ACTIVE:
>> + return &priv->format;
>> + default:
>> + return NULL;
>> + }
>> +}
>> +
>> +static int ov1063x_init_cfg(struct v4l2_subdev *sd,
>> + struct v4l2_subdev_state *state)
>> +{
>> + u32 which = state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
>> + struct ov1063x_priv *priv = to_ov1063x(sd);
>> + struct v4l2_mbus_framefmt *format;
>> +
>> + format = __ov1063x_get_pad_format(priv, state, 0, which);
>> + format->code = ov1063x_mbus_formats[0];
>> + format->width = ov1063x_framesizes[0].width;
>> + format->height = ov1063x_framesizes[0].height;
>> + format->field = V4L2_FIELD_NONE;
>> + format->colorspace = V4L2_COLORSPACE_SMPTE170M;
>> +
>> + if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
>> + /*
>> + * This assumes that ov1063x_mbus_formats[0] doesn't
>> + * sub-sample.
>> + */
>> + priv->analog_crop.width = OV1063X_SENSOR_WIDTH;
>> + priv->analog_crop.height = format->height;
>> + priv->analog_crop.left = ((OV1063X_SENSOR_WIDTH -
>> + priv->analog_crop.width) / 2) & ~1;
>> + priv->analog_crop.top = ((OV1063X_SENSOR_HEIGHT -
>> + priv->analog_crop.height) / 2) & ~1;
>> +
>> + priv->digital_crop.width = format->width;
>> + priv->digital_crop.height = format->height;
>> + priv->digital_crop.left = ((priv->analog_crop.width -
>> + priv->digital_crop.width) / 2) & ~1;
>> + priv->digital_crop.top = 0;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_enum_mbus_code(struct v4l2_subdev *sd,
>> + struct v4l2_subdev_state *state,
>> + struct v4l2_subdev_mbus_code_enum *code)
>> +{
>> + if (code->index >= ARRAY_SIZE(ov1063x_mbus_formats))
>> + return -EINVAL;
>> +
>> + code->code = ov1063x_mbus_formats[code->index];
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_enum_frame_sizes(struct v4l2_subdev *sd,
>> + struct v4l2_subdev_state *state,
>> + struct v4l2_subdev_frame_size_enum *fse)
>> +{
>> + unsigned int i;
>> +
>> + for (i = 0; i < ARRAY_SIZE(ov1063x_mbus_formats); ++i) {
>> + if (ov1063x_mbus_formats[i] == fse->code)
>> + break;
>> + }
>> +
>> + if (i == ARRAY_SIZE(ov1063x_mbus_formats))
>> + return -EINVAL;
>> +
>> + if (fse->index >= ARRAY_SIZE(ov1063x_framesizes))
>> + return -EINVAL;
>> +
>> + fse->min_width = ov1063x_framesizes[fse->index].width;
>> + fse->max_width = fse->min_width;
>> + fse->max_height = ov1063x_framesizes[fse->index].height;
>> + fse->min_height = fse->max_height;
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_get_fmt(struct v4l2_subdev *sd,
>> + struct v4l2_subdev_state *state,
>> + struct v4l2_subdev_format *fmt)
>> +{
>> + struct ov1063x_priv *priv = to_ov1063x(sd);
>> +
>> + fmt->format = *__ov1063x_get_pad_format(priv, state, fmt->pad,
>> + fmt->which);
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_set_fmt(struct v4l2_subdev *sd,
>> + struct v4l2_subdev_state *state,
>> + struct v4l2_subdev_format *fmt)
>> +{
>> + struct ov1063x_priv *priv = to_ov1063x(sd);
>> + struct v4l2_mbus_framefmt *format;
>> + const struct v4l2_area *fsize;
>> + unsigned int i;
>> + u32 code;
>> + int ret = 0;
>> +
>> + /*
>> + * Validate the media bus code, defaulting to the first one if the
>> + * requested code isn't supported.
>> + */
>> + for (i = 0; i < ARRAY_SIZE(ov1063x_mbus_formats); ++i) {
>> + if (ov1063x_mbus_formats[i] == fmt->format.code) {
>> + code = fmt->format.code;
>> + break;
>> + }
>> + }
>> +
>> + if (i == ARRAY_SIZE(ov1063x_mbus_formats))
>> + code = ov1063x_mbus_formats[0];
>> +
>> + /* Find the nearest supported frame size. */
>> + fsize = v4l2_find_nearest_size(ov1063x_framesizes,
>> + ARRAY_SIZE(ov1063x_framesizes),
>> + width, height, fmt->format.width,
>> + fmt->format.height);
>> +
>> + /* Update the stored format and return it. */
>> + format = __ov1063x_get_pad_format(priv, state, fmt->pad, fmt->which);
>> +
>> + mutex_lock(priv->hdl.lock);
>> +
>> + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
>> + priv->streaming != OV1063X_STREAM_OFF) {
>> + ret = -EBUSY;
>> + goto done;
>> + }
>> +
>> + format->code = code;
>> + format->width = fsize->width;
>> + format->height = fsize->height;
>> +
>> + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
>> + unsigned int hsub;
>> + unsigned int vsub;
>> +
>> + /*
>> + * Enable horizontal or vertical sub-sampling automatically when
>> + * the width or height are smaller than half the maximum
>> + * resolution.
>> + */
>> + hsub = format->width <= 640 ? 2 : 1;
>> + vsub = format->height <= 400 ? 2 : 1;
>> +
>> + /*
>> + * The analog horizontal crop is restricted to the full sensor
>> + * width (1312 pixels), 768 or 656 pixels. Additional cropping
>> + * will be applied in the digital domain.
>> + */
>> + priv->analog_crop.width = format->width * hsub;
>> + priv->analog_crop.height = format->height * vsub;
>> +
>> + if (priv->analog_crop.width > 768)
>> + priv->analog_crop.width = OV1063X_SENSOR_WIDTH;
>> + else if (priv->analog_crop.width > 656)
>> + priv->analog_crop.width = 768;
>> + else
>> + priv->analog_crop.width = 656;
>> +
>> + /*
>> + * The digital crop is applied at the ISP input, before
>> + * horizontal sub-sampling but after vertical sub-sampling as
>> + * the latter is applied in the pixel array.
>> + */
>> + priv->digital_crop.width = format->width * hsub;
>> + priv->digital_crop.height = format->height;
>> +
>> + /*
>> + * Center the crop rectangles, rounding coordinates to a
>> + * multiple of 2 to avoid changing the Bayer pattern.
>> + */
>> + priv->analog_crop.left = ((OV1063X_SENSOR_WIDTH -
>> + priv->analog_crop.width) / 2) & ~1;
>> + priv->analog_crop.top = ((OV1063X_SENSOR_HEIGHT -
>> + priv->analog_crop.height) / 2) & ~1;
>> + priv->digital_crop.left = ((priv->analog_crop.width -
>> + priv->digital_crop.width) / 2) & ~1;
>> + priv->analog_crop.top = 0;
>> + }
>> +
>> + fmt->format = *format;
>> +
>> +done:
>> + mutex_unlock(priv->hdl.lock);
>> +
>> + return ret;
>> +}
>> +
>> +static const struct v4l2_subdev_core_ops ov1063x_subdev_core_ops = {
>> + .log_status = v4l2_ctrl_subdev_log_status,
>> + .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
>> + .unsubscribe_event = v4l2_event_subdev_unsubscribe,
>> +};
>> +
>> +static const struct v4l2_subdev_video_ops ov1063x_subdev_video_ops = {
>> + .s_stream = ov1063x_s_stream,
>> +};
>> +
>> +static const struct v4l2_subdev_pad_ops ov1063x_subdev_pad_ops = {
>> + .init_cfg = ov1063x_init_cfg,
>> + .enum_mbus_code = ov1063x_enum_mbus_code,
>> + .enum_frame_size = ov1063x_enum_frame_sizes,
>> + .get_fmt = ov1063x_get_fmt,
>> + .set_fmt = ov1063x_set_fmt,
>> +};
>> +
>> +static const struct v4l2_subdev_ops ov1063x_subdev_ops = {
>> + .core = &ov1063x_subdev_core_ops,
>> + .video = &ov1063x_subdev_video_ops,
>> + .pad = &ov1063x_subdev_pad_ops,
>> +};
>> +
>> +/* -----------------------------------------------------------------------------
>> + * Power Management
>> + */
>> +
>> +static int ov1063x_power_on_init(struct ov1063x_priv *priv)
>> +{
>> + struct i2c_client *client = to_i2c_client(priv->dev);
>> + unsigned int i;
>> + int ret;
>> +
>> + ret = ov1063x_write(priv, OV1063X_SOFTWARE_RESET, 0x01, NULL);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = ov1063x_isp_reset(priv, true);
>> + if (ret < 0)
>> + return ret;
>> +
>> + /*
>> + * Why the I2C address has to be written 23 times (or, actually, at
>> + * all) is unknown. This may not be required.
>> + */
>> + for (i = 0; i < 23; ++i) {
>> + ret = ov1063x_write(priv, OV1063X_SC_CMMN_SCCB_ID,
>> + OV1063X_SC_CMMN_SCCB_ID_ADDR(client->addr) |
>> + OV1063X_SC_CMMN_SCCB_ID_SEL, NULL);
>> + if (ret < 0)
>> + return ret;
>> + }
>> +
>> + ret = ov1063x_write_array(priv, ov1063x_regs_default,
>> + ARRAY_SIZE(ov1063x_regs_default));
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = ov1063x_isp_reset(priv, false);
>> + if (ret < 0)
>> + return ret;
>> +
>> + usleep_range(500, 510);
>> + return 0;
>> +}
>> +
>> +static int ov1063x_power_on(struct ov1063x_priv *priv)
>> +{
>> + int ret;
>> +
>> + ret = clk_prepare_enable(priv->clk);
>> + if (ret < 0)
>> + return ret;
>> +
>> + if (priv->pwdn_gpio) {
>> + gpiod_set_value_cansleep(priv->pwdn_gpio, 0);
>> + usleep_range(1000, 1200);
>> + }
>> +
>> + if (priv->reset_gpio) {
>> + gpiod_set_value_cansleep(priv->reset_gpio, 0);
>> + usleep_range(250000, 260000);
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void ov1063x_power_off(struct ov1063x_priv *priv)
>> +{
>> + gpiod_set_value_cansleep(priv->pwdn_gpio, 1);
>> + gpiod_set_value_cansleep(priv->reset_gpio, 1);
>> +
>> + clk_disable_unprepare(priv->clk);
>> +}
>> +
>> +static int ov1063x_runtime_resume(struct device *dev)
>> +{
>> + struct i2c_client *client = to_i2c_client(dev);
>> + struct v4l2_subdev *subdev = i2c_get_clientdata(client);
>> + struct ov1063x_priv *priv = to_ov1063x(subdev);
>> + int ret;
>> +
>> + ret = ov1063x_power_on(priv);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = ov1063x_power_on_init(priv);
>> + if (ret < 0) {
>> + ov1063x_power_off(priv);
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int ov1063x_runtime_suspend(struct device *dev)
>> +{
>> + struct i2c_client *client = to_i2c_client(dev);
>> + struct v4l2_subdev *subdev = i2c_get_clientdata(client);
>> + struct ov1063x_priv *priv = to_ov1063x(subdev);
>> +
>> + ov1063x_power_off(priv);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops ov1063x_pm_ops = {
>> + SET_RUNTIME_PM_OPS(ov1063x_runtime_suspend, ov1063x_runtime_resume, NULL)
>> +};
>> +
>> +/* -----------------------------------------------------------------------------
>> + * I2C Driver, Probe & Remove
>> + */
>> +
>> +static int ov1063x_detect(struct ov1063x_priv *priv)
>> +{
>> + u32 pid;
>> + int ret;
>> +
>> + /* Read and check the product ID. */
>> + ret = ov1063x_read(priv, OV1063X_PID, &pid);
>> + if (ret)
>> + return ret;
>> +
>> + switch (pid) {
>> + case OV10633_VERSION_REG:
>> + priv->model = SENSOR_OV10633;
>> + priv->name = "ov10633";
>> + break;
>> + case OV10635_VERSION_REG:
>> + priv->model = SENSOR_OV10635;
>> + priv->name = "ov10635";
>> + break;
>> + default:
>> + dev_err(priv->dev, "Unknown product ID %04x\n", pid);
>> + return -ENODEV;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static const struct regmap_config ov1063x_regmap_config = {
>> + .reg_bits = 16,
>> + .val_bits = 8,
>> +};
>> +
>> +static int ov1063x_probe(struct i2c_client *client)
>> +{
>> + struct ov1063x_priv *priv;
>> + struct v4l2_subdev *sd;
>> + int ret;
>> +
>> + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
>> + if (!priv)
>> + return -ENOMEM;
>> +
>> + priv->dev = &client->dev;
>> +
>> + /* Acquire resources: regmap, GPIOs and clock. The GPIOs are optional. */
>> + priv->regmap = devm_regmap_init_i2c(client, &ov1063x_regmap_config);
>> + if (IS_ERR(priv->regmap))
>> + return PTR_ERR(priv->regmap);
>> +
>> + priv->pwdn_gpio = devm_gpiod_get_optional(priv->dev, "powerdown",
>> + GPIOD_OUT_HIGH);
>> + if (IS_ERR(priv->pwdn_gpio))
>> + return PTR_ERR(priv->pwdn_gpio);
>> +
>> + priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset",
>> + GPIOD_OUT_HIGH);
>> + if (IS_ERR(priv->reset_gpio))
>> + return PTR_ERR(priv->reset_gpio);
>> + priv->clk = devm_clk_get(priv->dev, "xvclk");
>> + if (IS_ERR(priv->clk)) {
>> + ret = PTR_ERR(priv->clk);
>> + dev_err(priv->dev, "Failed to get xvclk clock: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + priv->clk_rate = clk_get_rate(priv->clk);
>> + dev_dbg(priv->dev, "xvclk rate: %lu Hz\n", priv->clk_rate);
>> +
>> + if (priv->clk_rate < 6000000 || priv->clk_rate > 27000000)
>> + return -EINVAL;
>> +
>> + /*
>> + * Enable power and detect the device.
>> + *
>> + * The driver supports runtime PM, but needs to work when runtime PM is
>> + * disabled in the kernel. To that end, power it on manually here.
>> + */
>> + ret = ov1063x_power_on(priv);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = ov1063x_detect(priv);
>> + if (ret)
>> + goto err_power;
>> +
>> + /* Initialize the subdev and its controls. */
>> + sd = &priv->subdev;
>> + v4l2_i2c_subdev_init(sd, client, &ov1063x_subdev_ops);
>> + v4l2_i2c_subdev_set_name(sd, client, priv->name, NULL);
>> +
>> + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
>> + V4L2_SUBDEV_FL_HAS_EVENTS;
>> +
>> + v4l2_ctrl_handler_init(&priv->hdl, 3);
>> + v4l2_ctrl_new_std(&priv->hdl, &ov1063x_ctrl_ops,
>> + V4L2_CID_VFLIP, 0, 1, 1, 0);
>> + v4l2_ctrl_new_std(&priv->hdl, &ov1063x_ctrl_ops,
>> + V4L2_CID_HFLIP, 0, 1, 1, 0);
>> + v4l2_ctrl_new_std_menu_items(&priv->hdl, &ov1063x_ctrl_ops,
>> + V4L2_CID_TEST_PATTERN,
>> + ARRAY_SIZE(ov1063x_test_pattern_menu) - 1,
>> + 0, 0, ov1063x_test_pattern_menu);
>> +
>> + if (priv->hdl.error) {
>> + ret = priv->hdl.error;
>> + goto err_power;
>> + }
>> +
>> + sd->ctrl_handler = &priv->hdl;
>> +
>> + /* Default framerate */
>> + priv->fps_numerator = 30;
>> + priv->fps_denominator = 1;
>> + ov1063x_init_cfg(&priv->subdev, NULL);
>> +
>> + /* Initialize the media entity. */
>> + priv->pad.flags = MEDIA_PAD_FL_SOURCE;
>> + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
>> + ret = media_entity_pads_init(&sd->entity, 1, &priv->pad);
>> + if (ret < 0)
>> + goto err_ctrls;
>> +
>> + /*
>> + * Enable runtime PM. As the device has been powered manually, mark it
>> + * as active, and increase the usage count without resuming the device.
>> + */
>> + pm_runtime_set_active(priv->dev);
>> + pm_runtime_get_noresume(priv->dev);
>> + pm_runtime_enable(priv->dev);
>> +
>> + /*
>> + * Enable autosuspend as it can help avoiding costly power transitions
>> + * when reconfiguring the sensor.
>> + */
>> + pm_runtime_set_autosuspend_delay(priv->dev, 1000);
>> + pm_runtime_use_autosuspend(priv->dev);
>> +
>> + /*
>> + * At this point the device is powered on and active from a runtime PM
>> + * point of view, but hasn't gone through the full initialization
>> + * performed by the runtime resume operation. Suspend it synchronously
>> + * to turn the power off, ensuring proper initialization will take
>> + * place before the first usage.
>> + */
>> + pm_runtime_put_sync(priv->dev);
>> +
>> + /*
>> + * In case runtime PM is disabled in the kernel, the device remains
>> + * active and needs to be fully initialized at this point.
>> + */
>> + if (!pm_runtime_status_suspended(priv->dev)) {
>> + ret = ov1063x_power_on_init(priv);
>> + if (ret < 0)
>> + goto err_pm;
>> + }
>> +
>> + /* Finally, register the subdev. */
>> + ret = v4l2_async_register_subdev(sd);
>> + if (ret < 0)
>> + goto err_pm;
>> +
>> + dev_info(priv->dev, "%s probed\n", priv->name);
>> +
>> + return 0;
>> +
>> +err_pm:
>> + pm_runtime_disable(priv->dev);
>> + media_entity_cleanup(&priv->subdev.entity);
>> +err_ctrls:
>> + v4l2_ctrl_handler_free(&priv->hdl);
>> +err_power:
>> + if (!pm_runtime_status_suspended(priv->dev))
>> + ov1063x_power_off(priv);
>> + return ret;
>> +}
>> +
>> +static int ov1063x_remove(struct i2c_client *client)
>> +{
>> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
>> + struct ov1063x_priv *priv = to_ov1063x(sd);
>> +
>> + v4l2_ctrl_handler_free(&priv->hdl);
>> + v4l2_async_unregister_subdev(&priv->subdev);
>> + media_entity_cleanup(&priv->subdev.entity);
>> +
>> + /*
>> + * Disable runtime PM. In case runtime PM is disabled in the kernel,
>> + * make sure to turn power off manually.
>> + */
>> + pm_runtime_disable(priv->dev);
>> + if (!pm_runtime_status_suspended(priv->dev))
>> + ov1063x_power_off(priv);
>> + pm_runtime_set_suspended(priv->dev);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct of_device_id ov1063x_dt_id[] = {
>> + { .compatible = "ovti,ov10635" },
>> + { .compatible = "ovti,ov10633" },
>> + { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(of, ov1063x_dt_id);
>> +
>> +static struct i2c_driver ov1063x_i2c_driver = {
>> + .driver = {
>> + .name = "ov1063x",
>> + .of_match_table = of_match_ptr(ov1063x_dt_id),
>> + .pm = &ov1063x_pm_ops,
>> + },
>> + .probe_new = ov1063x_probe,
>> + .remove = ov1063x_remove,
>> +};
>> +
>> +module_i2c_driver(ov1063x_i2c_driver);
>> +
>> +MODULE_DESCRIPTION("Camera Sensor Driver for OmniVision OV10633/OV10635");
>> +MODULE_AUTHOR("Texas Instruments Inc.");
>> +MODULE_LICENSE("GPL");
>> diff --git a/drivers/media/i2c/ov1063x_regs.h b/drivers/media/i2c/ov1063x_regs.h
>> new file mode 100644
>> index 000000000000..7622de5c9069
>> --- /dev/null
>> +++ b/drivers/media/i2c/ov1063x_regs.h
>> @@ -0,0 +1,627 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * OmniVision OV1063x Camera Driver
>> + *
>> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
>> + * Copyright (C) 2020 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>> + */
>> +
>> +struct ov1063x_reg {
>> + u32 reg;
>> + u32 val;
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_default[] = {
>> + /* Register configuration for full resolution : 1280x720 */
>> + { OV1063X_SC_CMMN_MISC_CTRL, 0x02 |
>> + OV1063X_SC_CMMN_MISC_CTRL_CEN_GLOBAL_O },
>> + { OV1063X_SC_CMMN_PAD, 0x02 },
>> + { OV1063X_HORIZ_COLORCORRECT, 0x0c },
>> + { OV1063X_REG_8BIT(0x6901), 0x01 },
>> + { OV1063X_SC_CMMN_SCLK2X_SEL, OV1063X_SC_CMMN_SCLK2X_SEL_DIV4 },
>> + { OV1063X_AEC_PK_MANUAL, OV1063X_AEC_PK_MANUAL_DELAY },
>> + { OV1063X_SC_CMMN_PWDN_CTRL2, 0x20 |
>> + OV1063X_SC_CMMN_PWDN_CTRL2_RST_DIG1 |
>> + OV1063X_SC_CMMN_PWDN_CTRL2_RST_DIG2 |
>> + OV1063X_SC_CMMN_PWDN_CTRL2_RST_ISP |
>> + OV1063X_SC_CMMN_PWDN_CTRL2_SEQUENCE },
>> + { OV1063X_SC_CMMN_CORE_CTRL1, 0x03 },
>> + /*
>> + * For 15fps
>> + *
>> + * XVCLK: 9MHz
>> + * Pre divider: 1
>> + * Multiplier: 32
>> + * Divider: 8
>> + * SCLK: 36MHz
>> + */
>> + { OV1063X_SC_CMMN_PLL_CTRL0, OV1063X_SC_CMMN_PLL_SCLK_CP(0) |
>> + OV1063X_SC_CMMN_PLL_SCLK_MULTI(32) },
>> + { OV1063X_SC_CMMN_PLL_CTRL1, OV1063X_SC_CMMN_PLL_SCLK_PRE_DIV(0) |
>> + OV1063X_SC_CMMN_PLL_SCLK_CP2(0) |
>> + OV1063X_SC_CMMN_PLL_SCLK_DIV(3) },
>> + { OV1063X_SC_CMMN_PLL_CTRL2, OV1063X_SC_CMMN_PLL_SCLK_CP(0) |
>> + OV1063X_SC_CMMN_PLL_SCLK_MULTI(32) },
>> + { OV1063X_SC_CMMN_PLL_CTRL3, OV1063X_SC_CMMN_PLL_PCLK_BYPASS |
>> + OV1063X_SC_CMMN_PLL_SCLK_PRE_DIV(1) |
>> + OV1063X_SC_CMMN_PLL_SCLK_CP2(0) |
>> + OV1063X_SC_CMMN_PLL_SCLK_DIV(1) },
>> + { OV1063X_ANA_ADC1, 0x74 },
>> + { OV1063X_ANA_ADC2, 0x2b },
>> + { OV1063X_ANA_ANALOG3, 0x00 },
>> + { OV1063X_ANA_ANALOG2, 0x67 },
>> + { OV1063X_ANA_PWC4, 0xba },
>> + { OV1063X_ANA_ADC3, 0x2f },
>> + { OV1063X_ANA_ADC4, 0x00 },
>> + { OV1063X_ANA_PWC1, 0xa8 },
>> + { OV1063X_ANA_PWC2, 0x16 },
>> + { OV1063X_SENSOR_EQ_GOLOW, 0x10 },
>> + { OV1063X_SENSOR_BITSW_GO, 0x0001 },
>> + { OV1063X_FORMAT_CTRL00, OV1063X_FORMAT_UYVY },
>> + { OV1063X_SC_CMMN_PCLK_DIV_CTRL, 1 },
>> + { OV1063X_SC_CMMN_CORE_CTRL_3, OV1063X_SC_CMMN_CORE_CTRL_PCLK_SEC },
>> + { OV1063X_SC_CMMN_CLOCK_SEL, 0x0a | OV1063X_SC_CMMN_CLOCK_SEL_SCLK2X },
>> + { OV1063X_SENSOR_RSTGOLOW, 0x0d },
>> + { OV1063X_SENSOR_HLDWIDTH, 0x20 },
>> + { OV1063X_SENSOR_TXWIDTH, 0x15 },
>> + { OV1063X_SENSOR_REG9, 0x28 },
>> + { OV1063X_SENSOR_REGD, 0x00 },
>> + { OV1063X_SENSOR_RSTYZ_GOLOW, 32 },
>> + { OV1063X_SENSOR_REG15, 0x04 },
>> + { OV1063X_TIMING_CTRL1D, OV1063X_TIMING_CTRL1D_WDR },
>> + { OV1063X_TIMING_CTRL1C, 0 },
>> + { OV1063X_TIMING_CTRL24, 0x10 },
>> + { OV1063X_TIMING_CTRL15, OV1063X_TIMING_CTRL15_BLACK_LINE_HREF |
>> + OV1063X_TIMING_CTRL15_BLACK_LINES(12) },
>> + { OV1063X_TIMING_X_END_ADDR, 1311 },
>> + { OV1063X_TIMING_X_START_ADDR, 0 },
>> + { OV1063X_TIMING_Y_END_ADDR, 769 },
>> + { OV1063X_TIMING_Y_START_ADDR, 46 },
>> + { OV1063X_TIMING_X_OUTPUT_SIZE, 1280 },
>> + { OV1063X_TIMING_Y_OUTPUT_SIZE, 720 },
>> + { OV1063X_TIMING_HTS, 1782 },
>> + { OV1063X_TIMING_VTS, 748 },
>> + { OV1063X_TIMING_ISP_X_WIN, 8 },
>> + { OV1063X_VSTART_OFFSET, 12 },
>> + { OV1063X_ANA_ARRAY1, 0x60 |
>> + OV1063X_ANA_ARRAY1_FULL |
>> + OV1063X_ANA_ARRAY1_DELAY(3) },
>> + { OV1063X_ISP_RW05, OV1063X_ISP_RW05_SUB_AVG },
>> + { OV1063X_AEC_CTRLD5, 8 * 1024 * 1024 },
>> + { OV1063X_AEC_CTRLD9, 8 * 1024 * 1024 },
>> + { OV1063X_AEC_CTRLE8, 127 },
>> + { OV1063X_AEC_CTRLEA, 127 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_B_LONG, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_GB_LONG, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_GR_LONG, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_R_LONG, 128 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_B_LONG, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_GB_LONG, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_GR_LONG, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_R_LONG, 0 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_B_SHORT, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_GB_SHORT, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_GR_SHORT, 128 },
>> + { OV1063X_GAIN_AWB_MAN_GAIN_R_SHORT, 128 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_B_SHORT, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_GB_SHORT, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_GR_SHORT, 0 },
>> + { OV1063X_GAIN_AWB_MAN_OFFSET_R_SHORT, 0 },
>> + { OV1063X_AEC_CTRLD0, OV1063X_AEC_CTRLD0_R_MAN_EN(0) },
>> + { OV1063X_ISP_RW06, OV1063X_ISP_RW06_YUV_MODE_MAN(2) |
>> + OV1063X_ISP_RW06_YUV_MODE_MAN_EN },
>> + { OV1063X_AEC_CTRL07, 0 },
>> + { OV1063X_CIP_HFREQ_COEF_SHORT, 0x06 },
>> + { OV1063X_CIP_MAX_SHARPEN_LONG, 0x08 },
>> + { OV1063X_CIP_SHARPEN_ALPHA_LONG, 0x12 },
>> + { OV1063X_CIP_SHARPEN_ALPHA_SHORT, 0x12 },
>> + { OV1063X_CIP_UNSHARPEN_MASK_LONG(0), 0x06 },
>> + { OV1063X_CIP_UNSHARPEN_MASK_LONG(1), 0x20 },
>> + { OV1063X_CIP_UNSHARPEN_MASK_SHORT(0), 0x06 },
>> + { OV1063X_CIP_UNSHARPEN_MASK_SHORT(1), 0x20 },
>> + { OV1063X_CIP_MAX_SHARPEN_SHORT, 0x04 },
>> + { OV1063X_LLF_MAX_LOW_LEVEL, 255 },
>> + { OV1063X_AWB_M_X_LONG, 0x76 },
>> + { OV1063X_AWB_M_Y_LONG, 0x47 },
>> + { OV1063X_AWB_L_K_LONG, 0xef },
>> + { OV1063X_AWB_H_K_LONG, 0xc9 },
>> + { OV1063X_AWB_H_LMT_LONG, 0x49 },
>> + { OV1063X_AWB_L_LMT_LONG, 0x30 },
>> + { OV1063X_REG_8BIT(0x558f), 0x67 },
>> + { OV1063X_REG_8BIT(0x5590), 0x3f },
>> + { OV1063X_AWB_DATA_ULMT_LONG, 0xf0 },
>> + { OV1063X_AWB_DATA_LLMT_LONG, 0x10 },
>> + { OV1063X_AWB_M_X_SHORT, 0x6d },
>> + { OV1063X_AWB_M_Y_SHORT, 0x55 },
>> + { OV1063X_AWB_L_K_SHORT, 0xc3 },
>> + { OV1063X_AWB_H_K_SHORT, 0xb5 },
>> + { OV1063X_AWB_H_LMT_SHORT, 0x43 },
>> + { OV1063X_AWB_L_LMT_SHORT, 0x38 },
>> + { OV1063X_REG_8BIT(0x55a8), 0x5f },
>> + { OV1063X_REG_8BIT(0x55a9), 0x4b },
>> + { OV1063X_AWB_DATA_ULMT_SHORT, 0xf0 },
>> + { OV1063X_AWB_DATA_LLMT_SHORT, 0x10 },
>> + { OV1063X_AWB_CT_CTRL1, OV1063X_AWB_CT_CTRL1_GAIN_STEP_NORMAL(1) |
>> + OV1063X_AWB_CT_CTRL1_GAIN_STEP_FAST(1) |
>> + OV1063X_AWB_CT_CTRL1_SCALE_LONG_2X |
>> + 0x02 },
>> + { OV1063X_REG_8BIT(0x5300), 0x01 },
>> + { OV1063X_REG_8BIT(0x5301), 0x00 },
>> + { OV1063X_REG_8BIT(0x5302), 0x00 },
>> + { OV1063X_REG_8BIT(0x5303), 0x0e },
>> + { OV1063X_REG_8BIT(0x5304), 0x00 },
>> + { OV1063X_REG_8BIT(0x5305), 0x0e },
>> + { OV1063X_REG_8BIT(0x5306), 0x00 },
>> + { OV1063X_REG_8BIT(0x5307), 0x36 },
>> + { OV1063X_REG_8BIT(0x5308), 0x00 },
>> + { OV1063X_REG_8BIT(0x5309), 0xd9 },
>> + { OV1063X_REG_8BIT(0x530a), 0x00 },
>> + { OV1063X_REG_8BIT(0x530b), 0x0f },
>> + { OV1063X_REG_8BIT(0x530c), 0x00 },
>> + { OV1063X_REG_8BIT(0x530d), 0x2c },
>> + { OV1063X_REG_8BIT(0x530e), 0x00 },
>> + { OV1063X_REG_8BIT(0x530f), 0x59 },
>> + { OV1063X_REG_8BIT(0x5310), 0x00 },
>> + { OV1063X_REG_8BIT(0x5311), 0x7b },
>> + { OV1063X_REG_8BIT(0x5312), 0x00 },
>> + { OV1063X_REG_8BIT(0x5313), 0x22 },
>> + { OV1063X_REG_8BIT(0x5314), 0x00 },
>> + { OV1063X_REG_8BIT(0x5315), 0xd5 },
>> + { OV1063X_REG_8BIT(0x5316), 0x00 },
>> + { OV1063X_REG_8BIT(0x5317), 0x13 },
>> + { OV1063X_REG_8BIT(0x5318), 0x00 },
>> + { OV1063X_REG_8BIT(0x5319), 0x18 },
>> + { OV1063X_REG_8BIT(0x531a), 0x00 },
>> + { OV1063X_REG_8BIT(0x531b), 0x26 },
>> + { OV1063X_REG_8BIT(0x531c), 0x00 },
>> + { OV1063X_REG_8BIT(0x531d), 0xdc },
>> + { OV1063X_REG_8BIT(0x531e), 0x00 },
>> + { OV1063X_REG_8BIT(0x531f), 0x02 },
>> + { OV1063X_REG_8BIT(0x5320), 0x00 },
>> + { OV1063X_REG_8BIT(0x5321), 0x24 },
>> + { OV1063X_REG_8BIT(0x5322), 0x00 },
>> + { OV1063X_REG_8BIT(0x5323), 0x56 },
>> + { OV1063X_REG_8BIT(0x5324), 0x00 },
>> + { OV1063X_REG_8BIT(0x5325), 0x85 },
>> + { OV1063X_REG_8BIT(0x5326), 0x00 },
>> + { OV1063X_REG_8BIT(0x5327), 0x20 },
>> + { OV1063X_AEC_WIN_LEFT_LONG, 320 },
>> + { OV1063X_AEC_WIN_LEFT_SHORT, 320 },
>> + { OV1063X_AEC_WIN_TOP_LONG, 250 },
>> + { OV1063X_AEC_WIN_TOP_SHORT, 250 },
>> + { OV1063X_AEC_WIN_WIDTH_LONG, 640 },
>> + { OV1063X_AEC_WIN_WIDTH_SHORT, 640 },
>> + { OV1063X_AEC_WIN_HEIGHT_LONG, 300 },
>> + { OV1063X_AEC_WIN_HEIGHT_SHORT, 300 },
>> + { OV1063X_AEC_WEIGHT_SHORT(0), 1 },
>> + { OV1063X_AEC_WEIGHT_SHORT(1), 1 },
>> + { OV1063X_AEC_WEIGHT_SHORT(2), 1 },
>> + { OV1063X_AEC_WEIGHT_SHORT(3), 1 },
>> + { OV1063X_AEC_WEIGHT_SHORT(4), 3 },
>> + { OV1063X_AEC_WEIGHT_SHORT(5), 3 },
>> + { OV1063X_AEC_WEIGHT_SHORT(6), 3 },
>> + { OV1063X_AEC_WEIGHT_SHORT(7), 5 },
>> + { OV1063X_AEC_WEIGHT_SHORT(8), 9 },
>> + { OV1063X_AEC_WEIGHT_SHORT(9), 5 },
>> + { OV1063X_AEC_WEIGHT_SHORT(10), 5 },
>> + { OV1063X_AEC_WEIGHT_SHORT(11), 5 },
>> + { OV1063X_AEC_WEIGHT_SHORT(12), 5 },
>> + { OV1063X_AEC_FINAL_SATURATE_THRESH, 128 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(0), 1 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(1), 3 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(2), 6 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(3), 10 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(4), 14 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(5), 18 },
>> + { OV1063X_DNS_NOISE_Y_LIST_LONG(6), 22 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(0), 2 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(1), 4 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(2), 8 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(3), 12 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(4), 18 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(5), 24 },
>> + { OV1063X_DNS_NOISE_UV_LIST_LONG(6), 30 },
>> + { OV1063X_DNS_GBGR_EXTRA_SHORT, 4 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(0), 1 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(1), 3 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(2), 6 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(3), 10 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(4), 14 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(5), 18 },
>> + { OV1063X_DNS_NOISE_Y_LIST_SHORT(6), 22 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(0), 3 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(1), 4 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(2), 8 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(3), 12 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(4), 18 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(5), 24 },
>> + { OV1063X_DNS_NOISE_UV_LIST_SHORT(6), 30 },
>> + { OV1063X_VFIFO_LLEN_FIRS1_SEL, 0x00 }, /* 8-bit YUV mode */
>> + { OV1063X_VFIFO_LINE_LENGTH_MAN, 1905 },
>> + { OV1063X_VFIFO_HSYNC_START_POSITION, 624 },
>> + { OV1063X_VFIFO_HSYNC_CTRL, OV1063X_VFIFO_HSYNC_CTRL_HEADER_WIDTH(0) |
>> + OV1063X_VFIFO_HSYNC_CTRL_TRAILER_WIDTH(0) },
>> + { OV1063X_ROI_CTRL0, OV1063X_ROI_CTRL0_EN_3 |
>> + OV1063X_ROI_CTRL0_EN_2 |
>> + OV1063X_ROI_CTRL0_EN_1 },
>> + { OV1063X_DVP_MOD_SEL, OV1063X_DVP_MOD_SEL_CCIR_F },
>> + { OV1063X_DVP_VSYNC_WIDTH, 1 },
>> + { OV1063X_DVP_HSYVSY_NEG_WIDTH, 0 },
>> + { OV1063X_DVP_VSYNC_MODE, OV1063X_DVP_VSYNC_MODE_VSYNCOUT_SEL(0) },
>> + /*
>> + * Non-overlapping HSYNC-VSYNC.
>> + * Therefore do not set the VSYNC delay registers.
>> + */
>> + { OV1063X_DVP_EOF_VSYNC_DELAY, 0 },
>> + { OV1063X_LINE_NUM, 8 },
>> + { OV1063X_BLC_CTRL05, OV1063X_BLC_CTRL05_REMOVE_BLACK_LINE |
>> + OV1063X_BLC_CTRL05_ONE_MAN_OFFSET_MODE },
>> + { OV1063X_START_LINE, 4 },
>> + { OV1063X_BLC_AVG_CTRL1, 0x20 },
>> + { OV1063X_BLC_AVG_CTRL2, 0x22 },
>> + { OV1063X_BLC_OFFSET_TOP_LIMIT, 1948 },
>> + { OV1063X_BLC_CTRL5A, 0x00 },
>> + { OV1063X_FC_R2, 2 },
>> + { OV1063X_SC_CMMN_CORE_CTRL_2, OV1063X_SC_CMMN_CORE_CTRL_CLK_SWITCH },
>> + { OV1063X_STREAM_MODE, OV1063X_STREAM_MODE_ON },
>> + { OV1063X_STREAM_MODE, OV1063X_STREAM_MODE_ON },
>> + { OV1063X_REG_8BIT(0x6f0e), 0x00 },
>> + { OV1063X_REG_8BIT(0x6f0f), 0x00 },
>> + { OV1063X_VFIFO_EMBD_LINE_CTRL, OV1063X_VFIFO_EMBD_LINE_CTRL_SOF_CLR_RAM },
>> + { OV1063X_VFIFO_EMBD_LINE_NUM, 1 },
>> + { OV1063X_EMB_START_PCNT, 1 },
>> + { OV1063X_EMB_START_LCNT, 1 },
>> + { OV1063X_VFIFO_LLEN_FIRS1_SEL, 0x00 },
>> + { OV1063X_VFIFO_READ_START, 8 },
>> + { OV1063X_EMB_SIZE_MANU_EN, 0 },
>> + { OV1063X_EMB_SIZE_MANU, 1536 },
>> + { OV1063X_GAIN_AWB_CTRL32, 0 },
>> + { OV1063X_REG_8BIT(0x3510), 0x00 },
>> + { OV1063X_AEC_PK_MAN_DONE, 0 },
>> + { OV1063X_EMB_LINE_EN, 0 },
>> + { OV1063X_REG_8BIT(0x6f0d), 0x00 },
>> + { OV1063X_ISP_RW00, OV1063X_ISP_RW00_COLOR_MATRIX_EN |
>> + OV1063X_ISP_RW00_COLOR_INTERP_EN |
>> + OV1063X_ISP_RW00_DENOISE_EN |
>> + OV1063X_ISP_RW00_WHITE_DPC_EN |
>> + OV1063X_ISP_RW00_BLACK_DPC_EN |
>> + OV1063X_ISP_RW00_AWB_STATS_EN |
>> + OV1063X_ISP_RW00_AWB_GAIN_EN |
>> + OV1063X_ISP_RW00_LSC_EN },
>> + { OV1063X_ISP_RW01, OV1063X_ISP_RW01_DATA_WEIGHT_SYNC_EN |
>> + OV1063X_ISP_RW01_DARK_LEVEL_FILTER_EN |
>> + OV1063X_ISP_RW01_BUFFER_CONTROL_EN |
>> + OV1063X_ISP_RW01_AEC_EN |
>> + OV1063X_ISP_RW01_TONE_MAPPING_EN |
>> + OV1063X_ISP_RW01_NORMALIZE_EN |
>> + OV1063X_ISP_RW01_LONG_SHORT_COMB_EN },
>> + { OV1063X_ISP_RW02, OV1063X_ISP_RW02_OTP_MANUAL_OFFSET_EN |
>> + OV1063X_ISP_RW02_OTP_EN |
>> + OV1063X_ISP_RW02_INTER_FRAME_CALC |
>> + OV1063X_ISP_RW02_CT_AWB_EN |
>> + OV1063X_ISP_RW02_DIGITAL_GAIN_EN |
>> + OV1063X_ISP_RW02_WINDOW_BORDER_CUT_EN |
>> + OV1063X_ISP_RW02_DITHERING_EN },
>> + { OV1063X_ISP_CTRL3D, 0 },
>> + { OV1063X_AEC_TARGET_NUM, OV1063X_AEC_TARGET_NUM_AA_MODE },
>> + { OV1063X_AEC_LS_SENS_RATIO, 1024 },
>> + { OV1063X_AEC_NONWDR_EN, 0 },
>> + { OV1063X_AEC_NONWDR_SWITCH, 0 },
>> + { OV1063X_AEC_FIXED_RATIO_EN, 0 },
>> + { OV1063X_AEC_GP_MODE_EN, 0 },
>> + { OV1063X_AEC_NIGHT_MODE_EN, 0 },
>> + { OV1063X_AEC_NIGHT_MODE_CTRL, 0 },
>> + { OV1063X_AEC_NONLINEAR_GAIN_EN, 0 },
>> + { OV1063X_AEC_MANU_GAMMA_EN, 0 },
>> + { OV1063X_AEC_HOLD_BAND_EN, 0 },
>> + { OV1063X_AEC_BAND_FILTER_FLAG, OV1063X_AEC_BAND_FILTER_FLAG_0HZ },
>> + { OV1063X_AEC_BAND_FILTER_EN, 0 },
>> + { OV1063X_AEC_BAND_FILTER_SHORT, 0 },
>> + { OV1063X_AEC_LESS_1BAND_EN, 1 },
>> + { OV1063X_AEC_LESS_1BAND_SHORT, 1 },
>> + { OV1063X_AEC_LOG_TARGET(0), 0x8800 },
>> + { OV1063X_AEC_LOG_TARGET(1), 0x8a00 },
>> + { OV1063X_AEC_LOG_TARGET(2), 0x8600 },
>> + { OV1063X_AEC_TARGET_LONG(0), 0x40 },
>> + { OV1063X_AEC_TARGET_LONG(1), 0x50 },
>> + { OV1063X_AEC_TARGET_LONG(2), 0x30 },
>> + { OV1063X_AEC_TARGET_SHORT(0), 0x28 },
>> + { OV1063X_AEC_TARGET_SHORT(1), 0x60 },
>> + { OV1063X_AEC_TARGET_SHORT(2), 0x40 },
>> + { OV1063X_AEC_MAX_SHORT_LE, 0x01380000 },
>> + { OV1063X_AEC_MAX_GAIN_LONG, 255 },
>> + { OV1063X_AEC_MAX_GAIN_SHORT, 64 },
>> + { OV1063X_AEC_MIN_GAIN_LONG, 24 },
>> + { OV1063X_AEC_MIN_GAIN_SHORT, 24 },
>> + { OV1063X_AEC_MAX_EXP_LONG, 11904 },
>> + { OV1063X_AEC_MAX_EXP_SHORT, 11904 },
>> + { OV1063X_AEC_MIN_EXP_LONG, 4 },
>> + { OV1063X_AEC_MIN_EXP_SHORT, 4 },
>> + { OV1063X_AEC_FIXED_RATIO, 0x07 },
>> + { OV1063X_AEC_GP_MODE_RATIO_B2A, 0x20 },
>> + { OV1063X_AEC_GP_MODE_RATIO_C2A, 0x08 },
>> + { OV1063X_AEC_MIN_GAMMA_LIST(0), 512 },
>> + { OV1063X_AEC_MIN_GAMMA_LIST(1), 512 },
>> + { OV1063X_AEC_MIN_GAMMA_LIST(2), 512 },
>> + { OV1063X_AEC_MAX_GAMMA_LIST(0), 308 },
>> + { OV1063X_AEC_MAX_GAMMA_LIST(1), 1024 },
>> + { OV1063X_AEC_MAX_GAMMA_LIST(2), 1536 },
>> + { OV1063X_AEC_DR_LIST(0), 16 },
>> + { OV1063X_AEC_DR_LIST(1), 64 },
>> + { OV1063X_AEC_DR_LIST(2), 128 },
>> + { OV1063X_AEC_BAND_VALUE_60HZ, 3328 },
>> + { OV1063X_AEC_BAND_VALUE_50HZ, 4032 },
>> + { OV1063X_REG_8BIT(0xc4b4), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4b5), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4b6), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4b7), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4b8), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4b9), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4ba), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4bb), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4be), 0x02 },
>> + { OV1063X_REG_8BIT(0xc4bf), 0x33 },
>> + { OV1063X_REG_8BIT(0xc4c8), 0x03 },
>> + { OV1063X_REG_8BIT(0xc4c9), 0xd0 },
>> + { OV1063X_REG_8BIT(0xc4ca), 0x0e },
>> + { OV1063X_REG_8BIT(0xc4cb), 0x00 },
>> + { OV1063X_AWB_SIMPLE_MIN_NUM, 3665 },
>> + { OV1063X_AWB_CT_MIN_NUM, 3665 },
>> + { OV1063X_REG_8BIT(0xc4d0), 0x04 },
>> + { OV1063X_REG_8BIT(0xc4d1), 0x80 },
>> + { OV1063X_REG_8BIT(0xc4e0), 0x04 },
>> + { OV1063X_REG_8BIT(0xc4e1), 0x02 },
>> + { OV1063X_REG_8BIT(0xc4e2), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4e4), 0x10 },
>> + { OV1063X_REG_8BIT(0xc4e5), 0x20 },
>> + { OV1063X_REG_8BIT(0xc4e6), 0x30 },
>> + { OV1063X_REG_8BIT(0xc4e7), 0x40 },
>> + { OV1063X_REG_8BIT(0xc4e8), 0x50 },
>> + { OV1063X_REG_8BIT(0xc4e9), 0x60 },
>> + { OV1063X_REG_8BIT(0xc4ea), 0x70 },
>> + { OV1063X_REG_8BIT(0xc4eb), 0x80 },
>> + { OV1063X_REG_8BIT(0xc4ec), 0x90 },
>> + { OV1063X_REG_8BIT(0xc4ed), 0xa0 },
>> + { OV1063X_REG_8BIT(0xc4ee), 0xb0 },
>> + { OV1063X_REG_8BIT(0xc4ef), 0xc0 },
>> + { OV1063X_REG_8BIT(0xc4f0), 0xd0 },
>> + { OV1063X_REG_8BIT(0xc4f1), 0xe0 },
>> + { OV1063X_REG_8BIT(0xc4f2), 0xf0 },
>> + { OV1063X_REG_8BIT(0xc4f3), 0x80 },
>> + { OV1063X_REG_8BIT(0xc4f4), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4f5), 0x20 },
>> + { OV1063X_REG_8BIT(0xc4f6), 0x02 },
>> + { OV1063X_REG_8BIT(0xc4f7), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4f8), 0x04 },
>> + { OV1063X_REG_8BIT(0xc4f9), 0x0b },
>> + { OV1063X_REG_8BIT(0xc4fa), 0x00 },
>> + { OV1063X_REG_8BIT(0xc4fb), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4fc), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4fd), 0x01 },
>> + { OV1063X_REG_8BIT(0xc4fe), 0x04 },
>> + { OV1063X_REG_8BIT(0xc4ff), 0x02 },
>> + { OV1063X_REG_8BIT(0xc500), 0x68 },
>> + { OV1063X_REG_8BIT(0xc501), 0x74 },
>> + { OV1063X_REG_8BIT(0xc502), 0x70 },
>> + { OV1063X_REG_8BIT(0xc503), 0x80 },
>> + { OV1063X_REG_8BIT(0xc504), 0x05 },
>> + { OV1063X_REG_8BIT(0xc505), 0x80 },
>> + { OV1063X_REG_8BIT(0xc506), 0x03 },
>> + { OV1063X_REG_8BIT(0xc507), 0x80 },
>> + { OV1063X_REG_8BIT(0xc508), 0x01 },
>> + { OV1063X_REG_8BIT(0xc509), 0xc0 },
>> + { OV1063X_REG_8BIT(0xc50a), 0x01 },
>> + { OV1063X_REG_8BIT(0xc50b), 0xa0 },
>> + { OV1063X_REG_8BIT(0xc50c), 0x01 },
>> + { OV1063X_REG_8BIT(0xc50d), 0x2c },
>> + { OV1063X_REG_8BIT(0xc50e), 0x01 },
>> + { OV1063X_REG_8BIT(0xc50f), 0x0a },
>> + { OV1063X_REG_8BIT(0xc510), 0x00 },
>> + { OV1063X_REG_8BIT(0xc511), 0x00 },
>> + { OV1063X_REG_8BIT(0xc512), 0xe5 },
>> + { OV1063X_REG_8BIT(0xc513), 0x14 },
>> + { OV1063X_REG_8BIT(0xc514), 0x04 },
>> + { OV1063X_REG_8BIT(0xc515), 0x00 },
>> + { OV1063X_VTS_ADDR, 840 },
>> + { OV1063X_HTS_ADDR, 1904 },
>> + { OV1063X_REG_8BIT(0xc2e0), 0x00 },
>> + { OV1063X_REG_8BIT(0xc2e1), 0x51 },
>> + { OV1063X_REG_8BIT(0xc2e2), 0x00 },
>> + { OV1063X_REG_8BIT(0xc2e3), 0xd6 },
>> + { OV1063X_REG_8BIT(0xc2e4), 0x01 },
>> + { OV1063X_REG_8BIT(0xc2e5), 0x5e },
>> + { OV1063X_REG_8BIT(0xc2e9), 0x01 },
>> + { OV1063X_REG_8BIT(0xc2ea), 0x7a },
>> + { OV1063X_REG_8BIT(0xc2eb), 0x90 },
>> + { OV1063X_REG_8BIT(0xc2ed), 0x01 },
>> + { OV1063X_REG_8BIT(0xc2ee), 0x7a },
>> + { OV1063X_REG_8BIT(0xc2ef), 0x64 },
>> + { OV1063X_REG_8BIT(0xc308), 0x00 },
>> + { OV1063X_REG_8BIT(0xc309), 0x00 },
>> + { OV1063X_REG_8BIT(0xc30a), 0x00 },
>> + { OV1063X_REG_8BIT(0xc30c), 0x00 },
>> + { OV1063X_REG_8BIT(0xc30d), 0x01 },
>> + { OV1063X_REG_8BIT(0xc30e), 0x00 },
>> + { OV1063X_REG_8BIT(0xc30f), 0x00 },
>> + { OV1063X_REG_8BIT(0xc310), 0x01 },
>> + { OV1063X_REG_8BIT(0xc311), 0x60 },
>> + { OV1063X_REG_8BIT(0xc312), 0xff },
>> + { OV1063X_REG_8BIT(0xc313), 0x08 },
>> + { OV1063X_REG_8BIT(0xc314), 0x01 },
>> + { OV1063X_REG_8BIT(0xc315), 0x7f },
>> + { OV1063X_REG_8BIT(0xc316), 0xff },
>> + { OV1063X_REG_8BIT(0xc317), 0x0b },
>> + { OV1063X_REG_8BIT(0xc318), 0x00 },
>> + { OV1063X_REG_8BIT(0xc319), 0x0c },
>> + { OV1063X_REG_8BIT(0xc31a), 0x00 },
>> + { OV1063X_REG_8BIT(0xc31b), 0xe0 },
>> + { OV1063X_REG_8BIT(0xc31c), 0x00 },
>> + { OV1063X_REG_8BIT(0xc31d), 0x14 },
>> + { OV1063X_REG_8BIT(0xc31e), 0x00 },
>> + { OV1063X_REG_8BIT(0xc31f), 0xc5 },
>> + { OV1063X_REG_8BIT(0xc320), 0xff },
>> + { OV1063X_REG_8BIT(0xc321), 0x4b },
>> + { OV1063X_REG_8BIT(0xc322), 0xff },
>> + { OV1063X_REG_8BIT(0xc323), 0xf0 },
>> + { OV1063X_REG_8BIT(0xc324), 0xff },
>> + { OV1063X_REG_8BIT(0xc325), 0xe8 },
>> + { OV1063X_REG_8BIT(0xc326), 0x00 },
>> + { OV1063X_REG_8BIT(0xc327), 0x46 },
>> + { OV1063X_REG_8BIT(0xc328), 0xff },
>> + { OV1063X_REG_8BIT(0xc329), 0xd2 },
>> + { OV1063X_REG_8BIT(0xc32a), 0xff },
>> + { OV1063X_REG_8BIT(0xc32b), 0xe4 },
>> + { OV1063X_REG_8BIT(0xc32c), 0xff },
>> + { OV1063X_REG_8BIT(0xc32d), 0xbb },
>> + { OV1063X_REG_8BIT(0xc32e), 0x00 },
>> + { OV1063X_REG_8BIT(0xc32f), 0x61 },
>> + { OV1063X_REG_8BIT(0xc330), 0xff },
>> + { OV1063X_REG_8BIT(0xc331), 0xf9 },
>> + { OV1063X_REG_8BIT(0xc332), 0x00 },
>> + { OV1063X_REG_8BIT(0xc333), 0xd9 },
>> + { OV1063X_REG_8BIT(0xc334), 0x00 },
>> + { OV1063X_REG_8BIT(0xc335), 0x2e },
>> + { OV1063X_REG_8BIT(0xc336), 0x00 },
>> + { OV1063X_REG_8BIT(0xc337), 0xb1 },
>> + { OV1063X_REG_8BIT(0xc338), 0xff },
>> + { OV1063X_REG_8BIT(0xc339), 0x64 },
>> + { OV1063X_REG_8BIT(0xc33a), 0xff },
>> + { OV1063X_REG_8BIT(0xc33b), 0xeb },
>> + { OV1063X_REG_8BIT(0xc33c), 0xff },
>> + { OV1063X_REG_8BIT(0xc33d), 0xe8 },
>> + { OV1063X_REG_8BIT(0xc33e), 0x00 },
>> + { OV1063X_REG_8BIT(0xc33f), 0x48 },
>> + { OV1063X_REG_8BIT(0xc340), 0xff },
>> + { OV1063X_REG_8BIT(0xc341), 0xd0 },
>> + { OV1063X_REG_8BIT(0xc342), 0xff },
>> + { OV1063X_REG_8BIT(0xc343), 0xed },
>> + { OV1063X_REG_8BIT(0xc344), 0xff },
>> + { OV1063X_REG_8BIT(0xc345), 0xad },
>> + { OV1063X_REG_8BIT(0xc346), 0x00 },
>> + { OV1063X_REG_8BIT(0xc347), 0x66 },
>> + { OV1063X_REG_8BIT(0xc348), 0x01 },
>> + { OV1063X_REG_8BIT(0xc349), 0x00 },
>> + { OV1063X_TPM_SLOPE(0), 4 },
>> + { OV1063X_TPM_SLOPE(1), 123 },
>> + { OV1063X_TPM_OFFSET(0), 253 },
>> + { OV1063X_TPM_OFFSET(1), 249 },
>> + { OV1063X_TPM_OFFSET(2), 61 },
>> + { OV1063X_TPM_OFFSET(3), 113 },
>> + { OV1063X_TPM_CTRL6, 0x70 | OV1063X_TPM_CTRL6_CLK_DIV(1) },
>> + { OV1063X_REG_8BIT(0x6708), 0x05 },
>> + { OV1063X_REG_8BIT(0x3822), 0x50 },
>> + { OV1063X_PARI_ADDR_MIN, 0x6f00 },
>> + { OV1063X_PARI_ADDR_MAX, 0x6f00 },
>> + { OV1063X_GROUP_WRITER_COMMAND, OV1063X_GROUP_WRITER_COMMAND_EN },
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_bt656[] = {
>> + { OV1063X_DVP_MOD_SEL, OV1063X_DVP_MOD_SEL_CCIR_656 },
>> + { OV1063X_FORMAT_YMAX, 1016 },
>> + { OV1063X_FORMAT_YMIN, 8 },
>> + { OV1063X_FORMAT_UMAX, 1016 },
>> + { OV1063X_FORMAT_UMIN, 8 },
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_bt656_10bit[] = {
>> + { OV1063X_DVP_MOD_SEL, OV1063X_DVP_MOD_SEL_CCIR_656 },
>> + { OV1063X_FORMAT_YMAX, 1022 },
>> + { OV1063X_FORMAT_YMIN, 2 },
>> + { OV1063X_FORMAT_UMAX, 1022 },
>> + { OV1063X_FORMAT_UMIN, 2 },
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_vert_no_sub[] = {
>> + { OV1063X_TIMING_CTRL1C, 0 },
>> + { OV1063X_VSTART_OFFSET, 12 },
>> + { OV1063X_START_LINE, 4 },
>> + { OV1063X_LINE_NUM, 8 },
>> + { OV1063X_BLC_AVG_CTRL1, 0x20 },
>> + { OV1063X_BLC_AVG_CTRL2, 0x22 },
>> + { OV1063X_REG_8BIT(0x6e47), 0x0c },
>> + { OV1063X_EMB_START_PCNT, 1281 },
>> + { OV1063X_EMB_START_LCNT, 16 },
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_vert_sub2[] = {
>> + { OV1063X_TIMING_CTRL1C, OV1063X_TIMING_CTRL1C_VSUB2 },
>> + { OV1063X_VSTART_OFFSET, 6 },
>> + { OV1063X_START_LINE, 2 },
>> + { OV1063X_LINE_NUM, 2 },
>> + { OV1063X_BLC_AVG_CTRL1, 0x10 },
>> + { OV1063X_BLC_AVG_CTRL2, 0x11 },
>> + { OV1063X_REG_8BIT(0x6e47), 0x06 },
>> + { OV1063X_EMB_START_PCNT, 769 },
>> + { OV1063X_EMB_START_LCNT, 10 },
>> +};
>> +
>> +/*
>> + * Datasheet highlight the following sequence to enable and disable
>> + * Test Pattern mode i.e. colobar
>> + */
>> +static const struct ov1063x_reg ov1063x_regs_colorbar_enable[] = {
>> + { OV1063X_GAIN_AWB_CTRL32, OV1063X_GAIN_AWB_CTRL32_MANUAL_EN },
>> + { OV1063X_AEC_CTRLD0, OV1063X_AEC_CTRLD0_R_MAN_EN(1) },
>> + { OV1063X_REG_8BIT(0x5300), 0x01 }, { OV1063X_REG_8BIT(0x5301), 0x00 },
>> + { OV1063X_REG_8BIT(0x5302), 0x00 }, { OV1063X_REG_8BIT(0x5303), 0x00 },
>> + { OV1063X_REG_8BIT(0x5304), 0x00 }, { OV1063X_REG_8BIT(0x5305), 0x00 },
>> + { OV1063X_REG_8BIT(0x5306), 0x00 }, { OV1063X_REG_8BIT(0x5307), 0x00 },
>> + { OV1063X_REG_8BIT(0x5308), 0x01 }, { OV1063X_REG_8BIT(0x5309), 0x00 },
>> + { OV1063X_REG_8BIT(0x530a), 0x00 }, { OV1063X_REG_8BIT(0x530b), 0x00 },
>> + { OV1063X_REG_8BIT(0x530c), 0x00 }, { OV1063X_REG_8BIT(0x530d), 0x00 },
>> + { OV1063X_REG_8BIT(0x530e), 0x00 }, { OV1063X_REG_8BIT(0x530f), 0x00 },
>> + { OV1063X_REG_8BIT(0x5310), 0x01 }, { OV1063X_REG_8BIT(0x5311), 0x00 },
>> + { OV1063X_REG_8BIT(0x5312), 0x00 }, { OV1063X_REG_8BIT(0x5313), 0x00 },
>> + { OV1063X_REG_8BIT(0x5314), 0x01 }, { OV1063X_REG_8BIT(0x5315), 0x00 },
>> + { OV1063X_REG_8BIT(0x5316), 0x00 }, { OV1063X_REG_8BIT(0x5317), 0x00 },
>> + { OV1063X_REG_8BIT(0x5318), 0x00 }, { OV1063X_REG_8BIT(0x5319), 0x00 },
>> + { OV1063X_REG_8BIT(0x531a), 0x00 }, { OV1063X_REG_8BIT(0x531b), 0x00 },
>> + { OV1063X_REG_8BIT(0x531c), 0x01 }, { OV1063X_REG_8BIT(0x531d), 0x00 },
>> + { OV1063X_REG_8BIT(0x531e), 0x00 }, { OV1063X_REG_8BIT(0x531f), 0x00 },
>> + { OV1063X_REG_8BIT(0x5320), 0x00 }, { OV1063X_REG_8BIT(0x5321), 0x00 },
>> + { OV1063X_REG_8BIT(0x5322), 0x00 }, { OV1063X_REG_8BIT(0x5323), 0x00 },
>> + { OV1063X_REG_8BIT(0x5324), 0x01 }, { OV1063X_REG_8BIT(0x5325), 0x00 },
>> + { OV1063X_REG_8BIT(0x5326), 0x00 }, { OV1063X_REG_8BIT(0x5327), 0x00 },
>> + { OV1063X_REG_8BIT(0xc2ea), 0x80 }, { OV1063X_REG_8BIT(0xc2eb), 0x80 },
>> + { OV1063X_ISP_RW00, OV1063X_ISP_RW00_COLOR_INTERP_EN |
>> + OV1063X_ISP_RW00_DENOISE_EN |
>> + OV1063X_ISP_RW00_WHITE_DPC_EN |
>> + OV1063X_ISP_RW00_BLACK_DPC_EN |
>> + OV1063X_ISP_RW00_LSC_EN },
>> +};
>> +
>> +static const struct ov1063x_reg ov1063x_regs_colorbar_disable[] = {
>> + { OV1063X_ISP_CTRL3D, 0 },
>> + { OV1063X_ISP_CTRL3E, 0 },
>> + { OV1063X_GAIN_AWB_CTRL32, 0 },
>> + { OV1063X_AEC_CTRLD0, OV1063X_AEC_CTRLD0_R_MAN_EN(0) },
>> + { OV1063X_REG_8BIT(0x5300), 0x01 }, { OV1063X_REG_8BIT(0x5301), 0x00 },
>> + { OV1063X_REG_8BIT(0x5302), 0x00 }, { OV1063X_REG_8BIT(0x5303), 0x0e },
>> + { OV1063X_REG_8BIT(0x5304), 0x00 }, { OV1063X_REG_8BIT(0x5305), 0x0e },
>> + { OV1063X_REG_8BIT(0x5306), 0x00 }, { OV1063X_REG_8BIT(0x5307), 0x36 },
>> + { OV1063X_REG_8BIT(0x5308), 0x00 }, { OV1063X_REG_8BIT(0x5309), 0xd9 },
>> + { OV1063X_REG_8BIT(0x530a), 0x00 }, { OV1063X_REG_8BIT(0x530b), 0x0f },
>> + { OV1063X_REG_8BIT(0x530c), 0x00 }, { OV1063X_REG_8BIT(0x530d), 0x2c },
>> + { OV1063X_REG_8BIT(0x530e), 0x00 }, { OV1063X_REG_8BIT(0x530f), 0x59 },
>> + { OV1063X_REG_8BIT(0x5310), 0x00 }, { OV1063X_REG_8BIT(0x5311), 0x7b },
>> + { OV1063X_REG_8BIT(0x5312), 0x00 }, { OV1063X_REG_8BIT(0x5313), 0x22 },
>> + { OV1063X_REG_8BIT(0x5314), 0x00 }, { OV1063X_REG_8BIT(0x5315), 0xd5 },
>> + { OV1063X_REG_8BIT(0x5316), 0x00 }, { OV1063X_REG_8BIT(0x5317), 0x13 },
>> + { OV1063X_REG_8BIT(0x5318), 0x00 }, { OV1063X_REG_8BIT(0x5319), 0x18 },
>> + { OV1063X_REG_8BIT(0x531a), 0x00 }, { OV1063X_REG_8BIT(0x531b), 0x26 },
>> + { OV1063X_REG_8BIT(0x531c), 0x00 }, { OV1063X_REG_8BIT(0x531d), 0xdc },
>> + { OV1063X_REG_8BIT(0x531e), 0x00 }, { OV1063X_REG_8BIT(0x531f), 0x02 },
>> + { OV1063X_REG_8BIT(0x5320), 0x00 }, { OV1063X_REG_8BIT(0x5321), 0x24 },
>> + { OV1063X_REG_8BIT(0x5322), 0x00 }, { OV1063X_REG_8BIT(0x5323), 0x56 },
>> + { OV1063X_REG_8BIT(0x5324), 0x00 }, { OV1063X_REG_8BIT(0x5325), 0x85 },
>> + { OV1063X_REG_8BIT(0x5326), 0x00 }, { OV1063X_REG_8BIT(0x5327), 0x20 },
>> + { OV1063X_REG_8BIT(0xc2ea), 0x7a }, { OV1063X_REG_8BIT(0xc2eb), 0x90 },
>> + { OV1063X_ISP_RW00, OV1063X_ISP_RW00_COLOR_MATRIX_EN |
>> + OV1063X_ISP_RW00_COLOR_INTERP_EN |
>> + OV1063X_ISP_RW00_DENOISE_EN |
>> + OV1063X_ISP_RW00_WHITE_DPC_EN |
>> + OV1063X_ISP_RW00_BLACK_DPC_EN |
>> + OV1063X_ISP_RW00_AWB_STATS_EN |
>> + OV1063X_ISP_RW00_AWB_GAIN_EN |
>> + OV1063X_ISP_RW00_LSC_EN },
>> +};
>
next prev parent reply other threads:[~2022-03-23 16:12 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-06 23:07 [PATCH v2 0/2] media: Driver for OV1063x camera sensor Laurent Pinchart
2021-12-06 23:07 ` [PATCH v2 1/2] dt-bindings: media: Add bindings for OmniVision OV1063x sensors Laurent Pinchart
2021-12-06 23:07 ` [PATCH v2 2/2] media: i2c: Add OV1063x sensor driver Laurent Pinchart
2022-01-03 9:38 ` Tomi Valkeinen
2022-01-03 11:46 ` Laurent Pinchart
2022-03-23 14:01 ` Neil Armstrong
2022-03-23 16:12 ` Neil Armstrong [this message]
2022-03-24 8:48 ` Tomi Valkeinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5a2b6171-e784-e40c-7142-b69d4b99fd77@baylibre.com \
--to=narmstrong@baylibre.com \
--cc=bparrot@ti.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=sakari.ailus@linux.intel.com \
--cc=tomi.valkeinen@ideasonboard.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox