// 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 OV8856_REG_VALUE_08BIT 1
#define OV8856_REG_VALUE_16BIT 2
#define OV8856_REG_VALUE_24BIT 3
#define OV8856_LINK_FREQ_360MHZ 360000000ULL
#define OV8856_LINK_FREQ_180MHZ 180000000ULL
#define OV8856_SCLK 144000000ULL
#define OV8856_MCLK 19200000
#define OV8856_DATA_LANES 4
#define OV8856_RGB_DEPTH 10
#define OV8856_REG_CHIP_ID 0x300a
#define OV8856_CHIP_ID 0x00885a
#define OV8856_REG_MODE_SELECT 0x0100
#define OV8856_MODE_STANDBY 0x00
#define OV8856_MODE_STREAMING 0x01
/* vertical-timings from sensor */
#define OV8856_REG_VTS 0x380e
#define OV8856_VTS_MAX 0x7fff
/* horizontal-timings from sensor */
#define OV8856_REG_HTS 0x380c
/* Exposure controls from sensor */
#define OV8856_REG_EXPOSURE 0x3500
#define OV8856_EXPOSURE_MIN 6
#define OV8856_EXPOSURE_MAX_MARGIN 6
#define OV8856_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
#define OV8856_REG_ANALOG_GAIN 0x3508
#define OV8856_ANAL_GAIN_MIN 128
#define OV8856_ANAL_GAIN_MAX 2047
#define OV8856_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
#define OV8856_REG_MWB_R_GAIN 0x5019
#define OV8856_REG_MWB_G_GAIN 0x501b
#define OV8856_REG_MWB_B_GAIN 0x501d
#define OV8856_DGTL_GAIN_MIN 0
#define OV8856_DGTL_GAIN_MAX 4095
#define OV8856_DGTL_GAIN_STEP 1
#define OV8856_DGTL_GAIN_DEFAULT 1024
/* Test Pattern Control */
#define OV8856_REG_TEST_PATTERN 0x5e00
#define OV8856_TEST_PATTERN_ENABLE BIT(7)
#define OV8856_TEST_PATTERN_BAR_SHIFT 2
#define to_ov8856(_sd) container_of(_sd, struct ov8856, sd)
enum {
OV8856_LINK_FREQ_720MBPS,
OV8856_LINK_FREQ_360MBPS,
};
struct ov8856_reg {
u16 address;
u8 val;
};
struct ov8856_reg_list {
u32 num_of_regs;
const struct ov8856_reg *regs;
};
struct ov8856_link_freq_config {
const struct ov8856_reg_list reg_list;
};
struct ov8856_mode {
/* Frame width in pixels */
u32 width;
/* Frame height in pixels */
u32 height;
/* Horizontal timining size */
u32 hts;
/* Default vertical timining size */
u32 vts_def;
/* Min vertical timining size */
u32 vts_min;
/* Link frequency needed for this resolution */
u32 link_freq_index;
/* Sensor register settings for this resolution */
const struct ov8856_reg_list reg_list;
};
static const struct ov8856_reg mipi_data_rate_720mbps[] = {
{0x0103, 0x01},
{0x0100, 0x00},
{0x0302, 0x4b},
{0x0303, 0x01},
{0x030b, 0x02},
{0x030d, 0x4b},
{0x031e, 0x0c},
};
static const struct ov8856_reg mipi_data_rate_360mbps[] = {
{0x0103, 0x01},
{0x0100, 0x00},
{0x0302, 0x4b},
{0x0303, 0x03},
{0x030b, 0x02},
{0x030d, 0x4b},
{0x031e, 0x0c},
};
static const struct ov8856_reg mode_3280x2464_regs[] = {
{0x3000, 0x20},
{0x3003, 0x08},
{0x300e, 0x20},
{0x3010, 0x00},
{0x3015, 0x84},
{0x3018, 0x72},
{0x3021, 0x23},
{0x3033, 0x24},
{0x3500, 0x00},
{0x3501,