// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2019 Intel Corporation.
#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.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_XVCLK_19_2 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_DIGITAL_GAIN 0x350a
#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 1024
#define OV5675_DGTL_GAIN_MAX 4095
#define OV5675_DGTL_GAIN_STEP 1
#define OV5675_DGTL_GAIN_DEFAULT 1024
/* Group Access */
#define OV5675_REG_GROUP_ACCESS 0x3208
#define OV5675_GROUP_HOLD_START 0x0
#define OV5675_GROUP_HOLD_END 0x10
#define OV5675_GROUP_HOLD_LAUNCH 0xa0
/* Test Pattern Control */
#define OV5675_REG_TEST_PATTERN 0x4503
#define OV5675_TEST_PATTERN_ENABLE BIT(7)
#define OV5675_TEST_PATTERN_BAR_SHIFT 2
/* Flip Mirror Controls from sensor */
#define OV5675_REG_FORMAT1 0x3820
#define OV5675_REG_FORMAT2 0x373d
#define to_ov5675(_sd) container_of(_sd, struct ov5675, sd)
static const char * const ov5675_supply_names[] = {
"avdd", /* Analog power */
"dovdd", /* Digital I/O power */
"dvdd", /* Digital core power */
};
#define OV5675_NUM_SUPPLIES ARRAY_SIZE(ov5675_supply_names)
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