查看imx307芯片手册
修改,3007地址的bit0为1
修改imx307驱动代码加入这一句代码,直接写死,这样拍出来的照片就使垂直翻转180度的了
// SPDX-License-Identifier: GPL-2.0
/*
* imx307 driver
*
* Copyright (C) 2020 Rockchip Electronics Co., Ltd.
* v1.0x01.0x01 support lvds interface,include linear and hdr transmission via vipcap
* support mipi linear mode
* v1.0x01.0x02
* 1.fixed lvds output data offset, because lvds regards ob line as valid data output
* 2.support test pattern
* v1.0x01.0x03 update frame rate from 25fps to 30fps
* v1.0x01.0x04 update max exposure and formula
* shs1 = vts - (line + 1)
* V0.0X01.0X05 add quick stream on/off
* V0.0X01.0X06 support lvds 2lane
*/
#include <linux/clk.h>
#include <linux/device.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 <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/rk-camera-module.h>
#include <linux/of_graph.h>
#include <media/media-entity.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-mediabus.h>
#include <linux/pinctrl/consumer.h>
#include <linux/rk-preisp.h>
#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06)
#ifndef V4L2_CID_DIGITAL_GAIN
#define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
#endif
#define IMX307_LINK_FREQ_111M 111370000
#define IMX307_LINK_FREQ_222M 222750000
#define IMX307_2LANES 2
#define IMX307_4LANES 4
#define IMX307_BITS_PER_SAMPLE 10
/* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
#define IMX307_PIXEL_RATE_NORMAL (IMX307_LINK_FREQ_111M * 2 / 10 * IMX307_4LANES)
#define IMX307_PIXEL_RATE_HDR (IMX307_LINK_FREQ_222M * 2 / 10 * IMX307_4LANES)
#define IMX307_XVCLK_FREQ 37125000
#define CHIP_ID 0xb2
#define IMX307_REG_CHIP_ID 0x301e
#define IMX307_REG_CTRL_MODE 0x3000
#define IMX307_MODE_SW_STANDBY 0x1
#define IMX307_MODE_STREAMING 0x0
#define IMX307_REG_SHS1_H 0x3022
#define IMX307_REG_SHS1_M 0x3021
#define IMX307_REG_SHS1_L 0x3020
#define IMX307_REG_SHS2_H 0x3026
#define IMX307_REG_SHS2_M 0x3025
#define IMX307_REG_SHS2_L 0x3024
#define IMX307_REG_RHS1_H 0x3032
#define IMX307_REG_RHS1_M 0x3031
#define IMX307_REG_RHS1_L 0x3030
#define IMX307_FETCH_HIGH_BYTE_EXP(VAL) (((VAL) >> 16) & 0x0F)
#define IMX307_FETCH_MID_BYTE_EXP(VAL) (((VAL) >> 8) & 0xFF)
#define IMX307_FETCH_LOW_BYTE_EXP(VAL) ((VAL) & 0xFF)
#define IMX307_EXPOSURE_MIN 2
#define IMX307_EXPOSURE_STEP 1
#define IMX307_VTS_MAX 0x7fff
#define IMX307_GAIN_SWITCH_REG 0x3009
#define IMX307_REG_LF_GAIN 0x3014
#define IMX307_REG_SF_GAIN 0x30f2
#define IMX307_GAIN_MIN 0x00
#define IMX307_GAIN_MAX 0xee
#define IMX307_GAIN_STEP 1
#define IMX307_GAIN_DEFAULT 0x00
#define IMX307_GROUP_HOLD_REG 0x3001
#define IMX307_GROUP_HOLD_START 0x01
#define IMX307_GROUP_HOLD_END 0x00
#define USED_TEST_PATTERN
#ifdef USED_TEST_PATTERN
#define IMX307_REG_TEST_PATTERN 0x308c
#define IMX307_TEST_PATTERN_ENABLE BIT(0)
#endif
#define IMX307_REG_VTS_H 0x301a
#define IMX307_REG_VTS_M 0x3019
#define IMX307_REG_VTS_L 0x3018
#define IMX307_FETCH_HIGH_BYTE_VTS(VAL) (((VAL) >> 16) & 0x03)
#define IMX307_FETCH_MID_BYTE_VTS(VAL) (((VAL) >> 8) & 0xFF)
#define IMX307_FETCH_LOW_BYTE_VTS(VAL) ((VAL) & 0xFF)
#define REG_NULL 0xFFFF
#define REG_DELAY 0xFFFE
#define IMX307_REG_VALUE_08BIT 1
#define IMX307_REG_VALUE_16BIT 2
#define IMX307_REG_VALUE_24BIT 3
static bool g_isHCG;
#define IMX307_NAME "imx307"
#define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
#define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
#define IMX307_FLIP_REG 0x3007
#define MIRROR_BIT_MASK BIT(1)
#define FLIP_BIT_MASK BIT(0)
#define RHS1 0X0B
static const char * const imx307_supply_names[] = {
"avdd", /* Analog power */
"dovdd", /* Digital I/O power */
"dvdd", /* Digital core power */
};
#define IMX307_NUM_SUPPLIES ARRAY_SIZE(imx307_supply_names)
struct regval {
u16 addr;
u8 val;
};
struct imx307_mode {
u32 bus_fmt;
u32 width;
u32 height;
struct v4l2_fract max_fps;
u32 hts_def;
u32 vts_def;
u32 exp_def;
const struct regval *reg_list;
u32 hdr_mode;
struct rkmodule_lvds_cfg lvds_cfg;
u32 freq_idx;
u32 lanes;
u32 bpp;
};
struct imx307 {
struct i2c_client *client;
struct clk *xvclk;
struct gpio_desc *reset_gpio;
struct gpio_desc *pwdn_gpio;
struct regulator_bulk_data supplies[IMX307_NUM_SUPPLIES];
struct pinctrl *pinctrl;
struct pinctrl_state *pins_default;
struct pinctrl_state *pins_sleep;
struct v4l2_subdev subdev;
struct media_pad pad;
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *exposure;
struct v4l2_ctrl *anal_gain;
struct v4l2_ctrl *digi_gain;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *h_flip;
struct v4l2_ctrl *v_flip;
#ifdef USED_TEST_PATTERN
struct v4l2_ctrl *test_pattern;
#endif
struct mutex mutex;
bool streaming;
bool power_on;
const struct imx307_mode *support_modes;
u32 support_modes_num;
const struct imx307_mode *cur_mode;
u32 module_index;
const char *module_facing;
const char *module_name;
const char *len_name;
u32 cur_vts;
bool has_init_exp;
struct preisp_hdrae_exp_s init_hdrae_exp;
struct v4l2_fwnode_endpoint bus_cfg;
u8 flip;
};
#define to_imx307(sd) container_of(sd, struct imx307, subdev)
/*
* Xclk 37.125Mhz
*/
static const struct regval imx307_global_regs[] = {
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 30fps
* lvds_datarate per lane 111Mbps 2 lane
*/
static const struct regval imx307_linear_1920x1080_30fps_lvds_2lane_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x00},
//{0x3007, 0x01},
{0x3009, 0x02},
{0x300a, 0x3c},
{0x3010, 0x21},
{0x3011, 0x0a},
{0x3018, 0x65},
{0x3019, 0x04},
{0x301c, 0x30},
{0x301d, 0x11},
{0x3046, 0xD0},
{0x304b, 0x0a},
{0x305c, 0x18},
{0x305d, 0x00},
{0x305e, 0x20},
{0x305f, 0x01},
{0x309e, 0x4a},
{0x309f, 0x4a},
{0x311c, 0x0e},
{0x3128, 0x04},
{0x3129, 0x1d},
{0x313b, 0x41},
{0x315e, 0x1a},
{0x3164, 0x1a},
{0x317c, 0x12},
{0x31ec, 0x37},
{0x3480, 0x49},
{0x3002, 0x00},
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 15fps
* lvds_datarate per lane 222Mbps 2 lane
*/
static const struct regval imx307_hdr2_1920x1080_lvds_2lane_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x00},
//{0x3007, 0x01},
{0x3009, 0x02},
{0x300a, 0x3c},
{0x300c, 0x11},
{0x3010, 0x21},
{0x3011, 0x0a},
{0x3014, 0x0f},
{0x3018, 0x65},/* VMAX L */
{0x3019, 0x04},/* VMAX M */
{0x301c, 0x30},/* HMAX L */
{0x301d, 0x11},/* HMAX H */
{0x3020, 0x02},//hdr+ shs1 l short
{0x3021, 0x00},//hdr+ shs1 m
{0x3024, 0x49},//hdr+ shs2 l
{0x3025, 0x04},//hdr+ shs2 m
{0x3030, RHS1},//hdr+ IMX327_RHS1
{0x3031, 0x00},//hdr+IMX327_RHS1
{0x3045, 0x03},//hdr+
{0x3046, 0xd0},
{0x305c, 0x18},
{0x305d, 0x00},
{0x305e, 0x20},
{0x305f, 0x01},
{0x309e, 0x4a},
{0x309f, 0x4a},
{0x30d2, 0x19},
{0x30d7, 0x03},
{0x3106, 0x10},
{0x311c, 0x0e},
{0x3128, 0x04},
{0x3129, 0x1d},
{0x313b, 0x41},
{0x315e, 0x1a},
{0x3164, 0x1a},
{0x317c, 0x12},
{0x31ec, 0x37},
{0x3480, 0x49},
{0x31a0, 0xb4},
{0x31a1, 0x02},
{0x303c, 0x04},//Y offset
{0x303d, 0x00},
{0x303e, 0x41},
{0x303f, 0x04},//height
{0x303A, 0x08},//hdr+
{0x3010, 0x61},//hdr+ gain 1frame FPGC
{0x3014, 0x00},//hdr+ gain 1frame long
{0x30F0, 0x64},//hdr+ gain 2frame FPGC
{0x30f2, 0x00},//hdr+ gain 2frame short
{0x3002, 0x00},
{0x304B, 0x0a},
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 30fps
* lvds_datarate per lane 222.75Mbps 4 lane
*/
static const struct regval imx307_linear_1920x1080_30fps_lvds_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x00},
//{0x3007, 0x01},
{0x3009, 0x02},
{0x300a, 0x3c},
{0x3010, 0x21},
{0x3011, 0x0a},
{0x3018, 0x65},
{0x3019, 0x04},
{0x301c, 0x30},
{0x301d, 0x11},
{0x3046, 0xe0},
{0x304b, 0x0a},
{0x305c, 0x18},
{0x305d, 0x00},
{0x305e, 0x20},
{0x305f, 0x01},
{0x309e, 0x4a},
{0x309f, 0x4a},
{0x311c, 0x0e},
{0x3128, 0x04},
{0x3129, 0x1d},
{0x313b, 0x41},
{0x315e, 0x1a},
{0x3164, 0x1a},
{0x317c, 0x12},
{0x31ec, 0x37},
{0x3480, 0x49},
{0x3002, 0x00},
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 60fps
* lvds_datarate per lane 445.5Mbps 4 lane
*/
static const struct regval imx307_linear_1920x1080_60fps_lvds_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x00},
//{0x3007, 0x01},
{0x3009, 0x01},
{0x300a, 0x3c},
{0x3010, 0x21},
{0x3011, 0x0a},
{0x3018, 0x65},
{0x3019, 0x04},
{0x301c, 0x98},
{0x301d, 0x08},
{0x3046, 0xe0},
{0x304b, 0x0a},
{0x305c, 0x18},
{0x305d, 0x00},
{0x305e, 0x20},
{0x305f, 0x01},
{0x309e, 0x4a},
{0x309f, 0x4a},
{0x311c, 0x0e},
{0x3128, 0x04},
{0x3129, 0x1d},
{0x313b, 0x41},
{0x315e, 0x1a},
{0x3164, 0x1a},
{0x317c, 0x12},
{0x31ec, 0x37},
{0x3480, 0x49},
{0x3002, 0x00},
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 30fps
* lvds_datarate per lane 445.5Mbps 4 lane
*/
static const struct regval imx307_hdr2_1920x1080_lvds_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x40},
//{0x3007, 0x41},
{0x3009, 0x01},
{0x300a, 0x3c},
{0x300c, 0x11},
{0x3011, 0x02},
{0x3018, 0xc4},/* VMAX L */
{0x3019, 0x04},/* VMAX M */
{0x301c, 0xec},/* HMAX L */
{0x301d, 0x07},/* HMAX H */
{0x3020, 0x02},//hdr+ shs1 l short
{0x3021, 0x00},//hdr+ shs1 m
{0x3024, 0xc9},//hdr+ shs2 l
{0x3025, 0x07},//hdr+ shs2 m
{0x3030, 0xe1},//hdr+ IMX327_RHS1
{0x3031, 0x00},//hdr+IMX327_RHS1
{0x3045, 0x03},//hdr+
{0x3046, 0xe0},
{0x304b, 0x0a},
{0x305c, 0x18},
{0x305d, 0x03},
{0x305e, 0x20},
{0x305f, 0x01},
{0x309e, 0x4a},
{0x309f, 0x4a},
{0x30d2, 0x19},
{0x30d7, 0x03},
{0x3106, 0x11},
{0x3129, 0x1d},
{0x313b, 0x61},
{0x315e, 0x1a},
{0x3164, 0x1a},
{0x317c, 0x12},
{0x31ec, 0x37},
{0x3414, 0x00},
{0x3415, 0x00},
{0x3480, 0x49},
{0x31a0, 0xb4},
{0x31a1, 0x02},
{0x303c, 0x04},//Y offset
{0x303d, 0x00},
{0x303e, 0x41},
{0x303f, 0x04},//height
{0x303A, 0x08},//hdr+
{0x3010, 0x61},//hdr+ gain 1frame FPGC
{0x3014, 0x00},//hdr+ gain 1frame long
{0x30F0, 0x64},//hdr+ gain 2frame FPGC
{0x30f2, 0x00},//hdr+ gain 2frame short
{0x3002, 0x00},
{REG_NULL, 0x00},
};
/*
* Xclk 37.125Mhz
* max_framerate 30fps
* mipi_datarate per lane 222.75Mbps 4 lane
*/
static const struct regval imx307_linear_1920x1080_mipi_regs[] = {
{0x3003, 0x01},
{REG_DELAY, 0x10},
{0x3000, 0x01},
{0x3001, 0x00},
{0x3002, 0x01},
{0x3005, 0x00},
{0x3007, 0x00},
//{0x3007, 0x01},
{0x3009, 0x02},
{0x300A, 0x3c},
{0x3010, 0x21},
{0x3011, 0x0a},
{0x3018, 0x65},
{0x3019, 0x04},
{0x301C, 0x30},
{0x301D, 0x11},
{0x3046, 0x00},
{0x304B, 0x0A},
{0x305C, 0x18},
{0x305D, 0x03},
{0x305E, 0x20},
{0x305F, 0x01},
{0x309E, 0x4A},
{0x309F, 0x4A},
{0x311c, 0x0e},
{0x3128, 0x04},
{0x3129, 0x1d},
{0x313B, 0x41},
{0x315E, 0x1A},
{0x3164, 0x1A},
{0x317C, 0x12},
{0x31EC, 0x37},
{0x3405, 0x20},
{0x3407, 0x03},
{0x3414, 0x0A},
{0x3418, 0x49},
{0x3419, 0x04