// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2023 Intel Corporation.
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#define OV02E10_LINK_FREQ_360MHZ 360000000ULL
#define OV02E10_SCLK 36000000LL
#define OV02E10_MCLK 19200000
#define OV02E10_DATA_LANES 2
#define OV02E10_RGB_DEPTH 10
#define OV02E10_REG_PAGE_FLAG CCI_REG8(0xfd)
#define OV02E10_PAGE_0 0x0
#define OV02E10_PAGE_1 0x1
#define OV02E10_PAGE_2 0x2
#define OV02E10_PAGE_3 0x3
#define OV02E10_PAGE_5 0x4
#define OV02E10_PAGE_7 0x5
#define OV02E10_PAGE_8 0x6
#define OV02E10_PAGE_9 0xF
#define OV02E10_PAGE_D 0x8
#define OV02E10_PAGE_E 0x9
#define OV02E10_PAGE_F 0xA
#define OV02E10_REG_CHIP_ID CCI_REG32(0x00)
#define OV02E10_CHIP_ID 0x45025610
/* Horizontal and vertical flip */
#define OV02E10_REG_ORIENTATION CCI_REG8(0x32)
/* vertical-timings from sensor */
#define OV02E10_REG_VTS CCI_REG16(0x35)
#define OV02E10_VTS_DEF 2244
#define OV02E10_VTS_MIN 2244
#define OV02E10_VTS_MAX 0x7fff
/* horizontal-timings from sensor */
#define OV02E10_REG_HTS CCI_REG16(0x37)
/* Exposure controls from sensor */
#define OV02E10_REG_EXPOSURE CCI_REG16(0x03)
#define OV02E10_EXPOSURE_MIN 1
#define OV02E10_EXPOSURE_MAX_MARGIN 2
#define OV02E10_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
#define OV02E10_REG_ANALOG_GAIN CCI_REG8(0x24)
#define OV02E10_ANAL_GAIN_MIN 0x10
#define OV02E10_ANAL_GAIN_MAX 0xf8
#define OV02E10_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
#define OV02E10_REG_DIGITAL_GAIN CCI_REG16(0x21)
#define OV02E10_DGTL_GAIN_MIN 256
#define OV02E10_DGTL_GAIN_MAX 1020
#define OV02E10_DGTL_GAIN_STEP 1
#define OV02E10_DGTL_GAIN_DEFAULT 256
/* Register update control */
#define OV02E10_REG_COMMAND_UPDATE CCI_REG8(0xE7)
#define OV02E10_COMMAND_UPDATE 0x00
#define OV02E10_COMMAND_HOLD 0x01
/* Test Pattern Control */
#define OV02E10_REG_TEST_PATTERN CCI_REG8(0x12)
#define OV02E10_TEST_PATTERN_ENABLE BIT(0)
#define OV02E10_TEST_PATTERN_BAR_SHIFT 1
struct reg_sequence_list {
u32 num_regs;
const struct reg_sequence *regs;
};
struct ov02e10_mode {
/* Frame width in pixels */
u32 width;
/* Frame height in pixels */
u32 height;
/* Horizontal timining size */
u32 hts;
/* Default vertical timing */
u32 vts_def;
/* Min vertical timining size */
u32 vts_min;
/* Sensor register settings for this resolution */
const struct reg_sequence_list reg_list;
};
static const struct reg_sequence mode_1928x1088_30fps_2lane[] = {
{ 0xfd, 0x00 },
{ 0x20, 0x00 },
{ 0x20, 0x0b },
{ 0x21, 0x02 },
{ 0x10, 0x23 },
{ 0xc5, 0x04 },
{ 0x21, 0x00 },
{ 0x14, 0x96 },
{ 0x17, 0x01 },
{ 0xfd, 0x01 },
{ 0x03, 0x00 },
{ 0x04, 0x04 },
{ 0x05, 0x04 },
{ 0x06, 0x62 },
{ 0x07, 0x01 },
{ 0x22, 0x80 },
{ 0x24, 0xff },
{ 0x40, 0xc6 },
{ 0x41, 0x18 },
{ 0x45, 0x3f },
{ 0x48, 0x0c },
{ 0x4c, 0x08 },
{ 0x51, 0x12 },
{ 0x52, 0x10 },
{ 0x57, 0x98 },
{ 0x59, 0x06 },
{ 0x5a, 0x04 },
{ 0x5c, 0x38 },
{ 0x5e, 0x10 },
{ 0x67, 0x11 },
{ 0x7b, 0x04 },
{ 0x81, 0x12 },
{ 0x90, 0x51 },
{ 0x91, 0x09 },
{ 0x92, 0x21 },
{ 0x93, 0x28 },
{ 0x95, 0x54 },
{ 0x9d, 0x20 },
{ 0x9e, 0x04 },
{ 0xb1, 0x9a },
{ 0xb2, 0x86 },
{ 0xb6, 0x3f },
{ 0xb9, 0x30 },
{ 0xc1, 0x01 },
{ 0xc5, 0xa0 },
{ 0xc6, 0x73 },
{ 0xc7, 0x04 },
{ 0xc8, 0x25 },
{ 0xc9, 0x05 },
{ 0xca, 0x28 },
{ 0xcb, 0x00 },
{ 0xcf, 0x16 },
{ 0xd2, 0xd0 },
{ 0xd7, 0x3f },
{ 0xd8, 0x40 },
{ 0xd9, 0x40 },
{ 0xda, 0x44 },
{ 0xdb, 0x3d },
{ 0xdc, 0x3d },
{ 0xdd, 0x3d },
{ 0xde, 0x3d },
{ 0xdf, 0xf0 },
{ 0xea, 0x0f },
{ 0xeb, 0x04 },
{ 0xec, 0x29 },
{ 0xee, 0x47 },
{ 0xfd, 0x01 },
{ 0x31, 0x01 },
{ 0x27, 0x00 },
{ 0x2f, 0x41 },
{ 0xfd, 0x02 },
{ 0xa1, 0x01 },
{ 0xfd, 0x02 },
{ 0x9a, 0x03 },
{