// 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 OV5675_REG_VALUE_08BIT 1
#define OV5675_REG_VALUE_16BIT 2
#define OV5675_REG_VALUE_24BIT 3
#define OV5675_LINK_FREQ_450MHZ 450000000ULL
#define OV5675_SCLK 90000000LL
#define OV5675_MCLK 19200000
#define OV5675_DATA_LANES 2
#define OV5675_RGB_DEPTH 10
#define OV5675_REG_CHIP_ID 0x300a
#define OV5675_CHIP_ID 0x5675
#define OV5675_REG_MODE_SELECT 0x0100
#define OV5675_MODE_STANDBY 0x00
#define OV5675_MODE_STREAMING 0x01
/* vertical-timings from sensor */
#define OV5675_REG_VTS 0x380e
#define OV5675_VTS_30FPS 0x07e4
#define OV5675_VTS_30FPS_MIN 0x07e4
#define OV5675_VTS_MAX 0x7fff
/* horizontal-timings from sensor */
#define OV5675_REG_HTS 0x380c
/* Exposure controls from sensor */
#define OV5675_REG_EXPOSURE 0x3500
#define OV5675_EXPOSURE_MIN 4
#define OV5675_EXPOSURE_MAX_MARGIN 4
#define OV5675_EXPOSURE_STEP 1
/* Analog gain controls from sensor */
#define OV5675_REG_ANALOG_GAIN 0x3508
#define OV5675_ANAL_GAIN_MIN 128
#define OV5675_ANAL_GAIN_MAX 2047
#define OV5675_ANAL_GAIN_STEP 1
/* Digital gain controls from sensor */
#define OV5675_REG_MWB_R_GAIN 0x5019
#define OV5675_REG_MWB_G_GAIN 0x501b
#define OV5675_REG_MWB_B_GAIN 0x501d
#define OV5675_DGTL_GAIN_MIN 0
#define OV5675_DGTL_GAIN_MAX 4095
#define OV5675_DGTL_GAIN_STEP 1
#define OV5675_DGTL_GAIN_DEFAULT 1024
/* Test Pattern Control */
#define OV5675_REG_TEST_PATTERN 0x4503
#define OV5675_TEST_PATTERN_ENABLE BIT(7)
#define OV5675_TEST_PATTERN_BAR_SHIFT 2
#define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)
enum {
OV5675_LINK_FREQ_900MBPS,
};
struct ov5675_reg {
u16 address;
u8 val;
};
struct ov5675_reg_list {
u32 num_of_regs;
const struct ov5675_reg *regs;
};
struct ov5675_link_freq_config {
const struct ov5675_reg_list reg_list;
};
struct ov5675_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 ov5675_reg_list reg_list;
};
static const struct ov5675_reg mipi_data_rate_900mbps[] = {
{0x0103, 0x01},
{0x0100, 0x00},
{0x0300, 0x04},
{0x0302, 0x8d},
{0x0303, 0x00},
{0x030d, 0x26},
};
static const struct ov5675_reg mode_2592x1944_regs[] = {
{0x3002, 0x21},
{0x3107, 0x23},
{0x3501, 0x20},
{0x3503, 0x0c},
{0x3508, 0x03},
{0x3509, 0x00},
{0x3600, 0x66},
{0x3602, 0x30},
{0x3610, 0xa5},
{0x3612, 0x93},
{0x3620, 0x80},
{0x3642, 0x0e},
{0x3661, 0x00},
{0x3662, 0x10},
{0x3664, 0xf3},
{0x3665, 0x9e},
{0x3667, 0xa5},
{0x366e, 0x55},
{0x366f, 0x55},
{0x3670, 0x11},
{0x3671, 0x11},
{0x3672, 0x11},
{0x3673, 0x11},
{0x3714, 0x24},
{0x371a, 0x3e},
{0x3733, 0x10},
{0x3734, 0x00},
{0x373d, 0x24},
{0x3764, 0x20},
{0x3765, 0x20},
{0x3766, 0x12},
{0x37a1, 0x14},
{0x37a8, 0x1c},
{0x37ab, 0x0f},
{0x37c2, 0x04},
{0x37cb, 0x00},
{0x37cc, 0x00},
{0x37cd, 0x00},
{0x37ce, 0x00},
{0x37d8, 0x02},
{