// SPDX-License-Identifier: GPL-2.0
/*
* A V4L2 driver for Sony IMX219 cameras.
* Copyright (C) 2019, Raspberry Pi (Trading) Ltd
*
* Based on Sony imx258 camera driver
* Copyright (C) 2018 Intel Corporation
*
* DT / fwnode changes, and regulator / GPIO control taken from imx214 driver
* Copyright 2018 Qtechnology A/S
*
* Flip handling taken from the Sony IMX319 driver.
* Copyright (C) 2018 Intel Corporation
*
*/
#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/regulator/consumer.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <asm/unaligned.h>
#define IMX219_REG_VALUE_08BIT 1
#define IMX219_REG_VALUE_16BIT 2
#define IMX219_REG_MODE_SELECT 0x0100
#define IMX219_MODE_STANDBY 0x00
#define IMX219_MODE_STREAMING 0x01
/* Chip ID */
#define IMX219_REG_CHIP_ID 0x0000
#define IMX219_CHIP_ID 0x0219
/* External clock frequency is 24.0M */
#define IMX219_XCLK_FREQ 24000000
/* Pixel rate is fixed at 182.4M for all the modes */
#define IMX219_PIXEL_RATE 182400000
#define IMX219_DEFAULT_LINK_FREQ 456000000
/* V_TIMING internal */
#define IMX219_REG_VTS 0x0160
#define IMX219_VTS_15FPS 0x0dc6
#define IMX219_VTS_30FPS_1080P 0x06e3
#define IMX219_VTS_30FPS_BINNED 0x06e3
#define IMX219_VTS_30FPS_640x480 0x06e3
#define IMX219_VTS_MAX 0xffff
#define IMX219_VBLANK_MIN 4
/*Frame Length Line*/
#define IMX219_FLL_MIN 0x08a6
#define IMX219_FLL_MAX 0xffff
#define IMX219_FLL_STEP 1
#define IMX219_FLL_DEFAULT 0x0c98
/* HBLANK control - read only */
#define IMX219_PPL_DEFAULT 3448
/* Exposure control */
#define IMX219_REG_EXPOSURE 0x015a
#define IMX219_EXPOSURE_MIN 4
#define IMX219_EXPOSURE_STEP 1
#define IMX219_EXPOSURE_DEFAULT 0x640
#define IMX219_EXPOSURE_MAX 65535
/* Analog gain control */
#define IMX219_REG_ANALOG_GAIN 0x0157
#define IMX219_ANA_GAIN_MIN 0
#define IMX219_ANA_GAIN_MAX 232
#define IMX219_ANA_GAIN_STEP 1
#define IMX219_ANA_GAIN_DEFAULT 0x0
/* Digital gain control */
#define IMX219_REG_DIGITAL_GAIN 0x0158
#define IMX219_DGTL_GAIN_MIN 0x0100
#define IMX219_DGTL_GAIN_MAX 0x0fff
#define IMX219_DGTL_GAIN_DEFAULT 0x0100
#define IMX219_DGTL_GAIN_STEP 1
#define IMX219_REG_ORIENTATION 0x0172
/* Test Pattern Control */
#define IMX219_REG_TEST_PATTERN 0x0600
#define IMX219_TEST_PATTERN_DISABLE 0
#define IMX219_TEST_PATTERN_SOLID_COLOR 1
#define IMX219_TEST_PATTERN_COLOR_BARS 2
#define IMX219_TEST_PATTERN_GREY_COLOR 3
#define IMX219_TEST_PATTERN_PN9 4
/* Test pattern colour components */
#define IMX219_REG_TESTP_RED 0x0602
#define IMX219_REG_TESTP_GREENR 0x0604
#define IMX219_REG_TESTP_BLUE 0x0606
#define IMX219_REG_TESTP_GREENB 0x0608
#define IMX219_TESTP_COLOUR_MIN 0
#define IMX219_TESTP_COLOUR_MAX 0x03ff
#define IMX219_TESTP_COLOUR_STEP 1
#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX
#define IMX219_TESTP_GREENR_DEFAULT 0
#define IMX219_TESTP_BLUE_DEFAULT 0
#define IMX219_TESTP_GREENB_DEFAULT 0
/* IMX219 native and active pixel array size. */
#define IMX219_NATIVE_WIDTH 3296U
#define IMX219_NATIVE_HEIGHT 2480U
#define IMX219_PIXEL_ARRAY_LEFT 8U
#define IMX219_PIXEL_ARRAY_TOP 8U
#define IMX219_PIXEL_ARRAY_WIDTH 3280U
#define IMX219_PIXEL_ARRAY_HEIGHT 2464U
struct imx219_reg {
u16 address;
u8 val;
};
struct imx219_reg_list {
unsigned int num_of_regs;
const struct imx219_reg *regs;
};
/* Mode : resolution and related config&values */
struct imx219_mode {
/* Frame width */
unsigned int width;
/* Frame height */
unsigned int height;
/* Analog crop rectangle. */
struct v4l2_rect crop;
/* V-timing */
unsigned int vts_def;
/* Default register values */
struct imx219_reg_list reg_list;
};
/*
* Register sets lifted off the i2C interface from the Raspberry Pi firmware
* driver.
* 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7.
*/
static const struct imx219_reg mode_3280x2464_regs[] = {
{0x0100, 0x00},
{0x30eb, 0x0c},
{0x30eb, 0x05},
{0x300a, 0xff},
{0x300b, 0xff},
{0x30eb, 0x05},
{0x30eb, 0x09},
{0x0114, 0x01},
{0x0128, 0x00},
{0x012a, 0x18},
{0x012b, 0x00},
{0x0164, 0x00},
{0x0165, 0x00},
{0x0166, 0x0c},
{0x0167, 0xcf},
{0x0168, 0x00},
{0x0169, 0x00},
{0x016a, 0x09},
{0x016b, 0x9f},
{0x016c, 0x0c},
{0x016d, 0xd0},
{0x016e, 0x09},
{0x016f, 0xa0},
{0x0170, 0x01},
{0x0171, 0x01},
{0x0174, 0x00},
{0x0175, 0x00},
{0x0301, 0x05},
{0x0303, 0x01},
{0x0304, 0x03},
{0x0305, 0x03},
{0x0306, 0x00},
{0x0307, 0x39},
{0x030b, 0x01},
{0x030c, 0x00},
{0x030d, 0x72},
{0x0624, 0x0c},
{0x0625, 0xd0},
{0x0626, 0x09},
{0x0627, 0xa0},
{0x455e, 0x00},
{0x471e, 0x4b},
{0x4767, 0x0f},
{0x4750, 0x14},
{0x4540, 0x00},
{0x47b4, 0x14},
{0x4713, 0x30},
{0x478b, 0x10},
{0x478f, 0x10},
{0x4793, 0x10},
{0x4797, 0x0e},
{0x479b, 0x0e},
{0x0162, 0x0d},
{0x0163, 0x78},
};
static const struct imx219_reg mode_1920_1080_regs[] = {
{0x0100, 0x00},
{0x30eb, 0x05},
{0x30eb, 0x0c},
{0x300a, 0xff},
{0x300b, 0xff},
{0x30eb, 0x05},
{0x30eb, 0x09},
{0x0114, 0x01},
{0x0128, 0x00},
{0x012a, 0x18},
{0x012b, 0x00},
{0x0162, 0x0d},
{0x0163, 0x78},
{0x0164, 0x02},
{0x0165, 0xa8},
{0x0166, 0x0a},
{0x0167, 0x27},
{0x0168, 0x02},
{0x0169, 0xb4},
{0x016a, 0x06},
{0x016b, 0xeb},
{0x016c, 0x07},
{0x016d, 0x80},
{0x016e, 0x04},
{0x016f, 0x38},
{0x0170, 0x01},
{0x0171, 0x01},
{0x0174, 0x00},
{0x0175, 0x00},
{0x0301, 0x05
|