// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Intel Corporation.
#include <asm/unaligned.h>
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#define HI556_REG_VALUE_08BIT 1
#define HI556_REG_VALUE_16BIT 2
#define HI556_REG_VALUE_24BIT 3
#define HI556_LINK_FREQ_437MHZ 437000000ULL
#define HI556_MCLK 19200000
#define HI556_DATA_LANES 2
#define HI556_RGB_DEPTH 10
#define HI556_REG_CHIP_ID 0x0f16
#define HI556_CHIP_ID 0x0556
#define HI556_REG_MODE_SELECT 0x0a00
#define HI556_MODE_STANDBY 0x0000
#define HI556_MODE_STREAMING 0x0100
/* vertical-timings from sensor */
#define HI556_REG_FLL 0x0006
#define HI556_FLL_30FPS 0x0814
#define HI556_FLL_30FPS_MIN 0x0814
#define HI556_FLL_MAX 0x7fff
/* horizontal-timings from sensor */
#define HI556_REG_LLP 0x0008
/* Exposure controls from sensor */
#define HI556_REG_EXPOSURE 0x0074
#define HI556_EXPOSURE_MIN 6
#define HI556_EXPOSURE_MAX_MARGIN 2
#define HI556_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
#define HI556_REG_ANALOG_GAIN 0x0077
#define HI556_ANAL_GAIN_MIN 0
#define HI556_ANAL_GAIN_MAX 240
#define HI556_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
#define HI556_REG_MWB_GR_GAIN 0x0078
#define HI556_REG_MWB_GB_GAIN 0x007a
#define HI556_REG_MWB_R_GAIN 0x007c
#define HI556_REG_MWB_B_GAIN 0x007e
#define HI556_DGTL_GAIN_MIN 0
#define HI556_DGTL_GAIN_MAX 2048
#define HI556_DGTL_GAIN_STEP 1
#define HI556_DGTL_GAIN_DEFAULT 256
/* Test Pattern Control */
#define HI556_REG_ISP 0X0a05
#define HI556_REG_ISP_TPG_EN 0x01
#define HI556_REG_TEST_PATTERN 0x0201
/* HI556 native and active pixel array size. */
#define HI556_NATIVE_WIDTH 2592U
#define HI556_NATIVE_HEIGHT 1944U
#define HI556_PIXEL_ARRAY_LEFT 0U
#define HI556_PIXEL_ARRAY_TOP 0U
#define HI556_PIXEL_ARRAY_WIDTH 2592U
#define HI556_PIXEL_ARRAY_HEIGHT 1944U
enum {
HI556_LINK_FREQ_437MHZ_INDEX,
};
struct hi556_reg {
u16 address;
u16 val;
};
struct hi556_reg_list {
u32 num_of_regs;
const struct hi556_reg *regs;
};
struct hi556_link_freq_config {
const struct hi556_reg_list reg_list;
};
struct hi556_mode {
/* Frame width in pixels */
u32 width;
/* Frame height in pixels */
u32 height;
/* Analog crop rectangle. */
struct v4l2_rect crop;
/* Horizontal timining size */
u32 llp;
/* Default vertical timining size */
u32 fll_def;
/* Min vertical timining size */
u32 fll_min;
/* Link frequency needed for this resolution */
u32 link_freq_index;
/* Sensor register settings for this resolution */
const struct hi556_reg_list reg_list;
};
#define to_hi556(_sd) container_of(_sd, struct hi556, sd)
//SENSOR_INITIALIZATION
static const struct hi556_reg mipi_data_rate_874mbps[] = {
{0x0e00, 0x0102},
{0x0e02, 0x0102},
{0x0e0c, 0x0100},
{0x2000, 0x7400},
{0x2002, 0x001c},
{0x2004, 0x0242},
{0x2006, 0x0942},
{0x2008, 0x7007},
{0x200a, 0x0fd9},
{0x200c, 0x0259},
{0x200e, 0x7008},
{0x2010, 0x160e},
{0x2012, 0x0047},
{0x2014, 0x2118},
{0x2016, 0x0041},
{0x2018,