当前位置: 首页 > news >正文

瑞芯微RK3588驱动设计之DVP并口摄像头2

dts配置看瑞芯微RK3588驱动配置之DVP并口摄像头1_rockchip 调试dvp设备 直接显示摄像头数据-CSDN博客

这里看看驱动的具体实现,以gc2145为例。

gc2145的驱动源码如下:

// SPDX-License-Identifier: GPL-2.0
/** GC2145 CMOS Image Sensor driver*** Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd.** V0.0X01.0X01 add poweron function.* V0.0X01.0X02 fix mclk issue when probe multiple camera.* V0.0X01.0X03 fix gc2145 exposure issues.* V0.0X01.0X04 add enum_frame_interval function.* V0.0X01.0X05 reduce rkisp1: CIF_ISP_PIC_SIZE_ERROR 0x00000001.* V0.0X01.0X06 add quick stream on/off*/#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/media.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/videodev2.h>
#include <linux/version.h>
#include <linux/rk-camera-module.h>
#include <media/media-entity.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-subdev.h>#define DRIVER_VERSION			KERNEL_VERSION(0, 0x01, 0x6)
#define DRIVER_NAME "gc2145"
#define GC2145_PIXEL_RATE		(120 * 1000 * 1000)#define GC2145_EXPOSURE_CONTROL/** GC2145 register definitions*/
#define REG_SC_CHIP_ID_H		0xf0
#define REG_SC_CHIP_ID_L		0xf1#define REG_NULL			0xFFFF	/* Array end token */#define SENSOR_ID(_msb, _lsb)		((_msb) << 8 | (_lsb))
#define GC2145_ID			0x2145struct sensor_register {u16 addr;u8 value;
};struct gc2145_framesize {u16 width;u16 height;struct v4l2_fract max_fps;u16 max_exp_lines;const struct sensor_register *regs;
};struct gc2145_pll_ctrl {u8 ctrl1;u8 ctrl2;u8 ctrl3;
};struct gc2145_pixfmt {u32 code;/* Output format Register Value (REG_FORMAT_CTRL00) */struct sensor_register *format_ctrl_regs;
};struct pll_ctrl_reg {unsigned int div;unsigned char reg;
};static const char * const gc2145_supply_names[] = {"dovdd",	/* Digital I/O power */"avdd",		/* Analog power */"dvdd",		/* Digital core power */
};#define GC2145_NUM_SUPPLIES ARRAY_SIZE(gc2145_supply_names)struct gc2145 {struct v4l2_subdev sd;struct media_pad pad;struct v4l2_mbus_framefmt format;unsigned int fps;unsigned int xvclk_frequency;struct clk *xvclk;struct gpio_desc *power_gpio;struct gpio_desc *pwdn_gpio;struct gpio_desc *reset_gpio;struct regulator_bulk_data supplies[GC2145_NUM_SUPPLIES];struct mutex lock;struct i2c_client *client;struct v4l2_ctrl_handler ctrls;struct v4l2_ctrl *link_frequency;struct v4l2_fwnode_endpoint bus_cfg;const struct gc2145_framesize *frame_size;const struct gc2145_framesize *framesize_cfg;unsigned int cfg_num;int streaming;bool			power_on;u32 module_index;const char *module_facing;const char *module_name;const char *len_name;
};static const struct sensor_register gc2145_dvp_init_regs[] = {{0xfe, 0xf0},{0xfe, 0xf0},{0xfe, 0xf0},{0xfc, 0x06},{0xf6, 0x00},{0xf7, 0x1d},{0xf8, 0x84},{0xfa, 0x00},{0xf9, 0xfe},{0xf2, 0x00},/*ISP reg*/{0xfe, 0x00},{0x03, 0x04},{0x04, 0xe2},{0x09, 0x00},{0x0a, 0x00},{0x0b, 0x00},{0x0c, 0x00},{0x0d, 0x04},{0x0e, 0xc0},{0x0f, 0x06},{0x10, 0x52},{0x12, 0x2e},{0x17, 0x14},{0x18, 0x22},{0x19, 0x0e},{0x1a, 0x01},{0x1b, 0x4b},{0x1c, 0x07},{0x1d, 0x10},{0x1e, 0x88},{0x1f, 0x78},{0x20, 0x03},{0x21, 0x40},{0x22, 0xa0},{0x24, 0x3f},{0x25, 0x01},{0x26, 0x10},{0x2d, 0x60},{0x30, 0x01},{0x31, 0x90},{0x33, 0x06},{0x34, 0x01},{0xfe, 0x00},{0x80, 0x7f},{0x81, 0x26},{0x82, 0xfa},{0x83, 0x00},{0x84, 0x00},{0x86, 0x02},{0x88, 0x03},{0x89, 0x03},{0x85, 0x08},{0x8a, 0x00},{0x8b, 0x00},{0xb0, 0x55},{0xc3, 0x00},{0xc4, 0x80},{0xc5, 0x90},{0xc6, 0x3b},{0xc7, 0x46},{0xec, 0x06},{0xed, 0x04},{0xee, 0x60},{0xef, 0x90},{0xb6, 0x01},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x04},{0x96, 0xb0},{0x97, 0x06},{0x98, 0x40},/*BLK*/{0xfe, 0x00},{0x40, 0x42},{0x41, 0x00},{0x43, 0x5b},{0x5e, 0x00},{0x5f, 0x00},{0x60, 0x00},{0x61, 0x00},{0x62, 0x00},{0x63, 0x00},{0x64, 0x00},{0x65, 0x00},{0x66, 0x20},{0x67, 0x20},{0x68, 0x20},{0x69, 0x20},{0x76, 0x00},{0x6a, 0x08},{0x6b, 0x08},{0x6c, 0x08},{0x6d, 0x08},{0x6e, 0x08},{0x6f, 0x08},{0x70, 0x08},{0x71, 0x08},{0x76, 0x00},{0x72, 0xf0},{0x7e, 0x3c},{0x7f, 0x00},{0xfe, 0x02},{0x48, 0x15},{0x49, 0x00},{0x4b, 0x0b},{0xfe, 0x00},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0xc0},{0x03, 0x04},{0x04, 0x90},{0x05, 0x30},{0x06, 0x90},{0x07, 0x30},{0x08, 0x80},{0x09, 0x00},{0x0a, 0x82},{0x0b, 0x11},{0x0c, 0x10},{0x11, 0x10},{0x13, 0x7b},{0x17, 0x00},{0x1c, 0x11},{0x1e, 0x61},{0x1f, 0x35},{0x20, 0x40},{0x22, 0x40},{0x23, 0x20},{0xfe, 0x02},{0x0f, 0x04},{0xfe, 0x01},{0x12, 0x35},{0x15, 0xb0},{0x10, 0x31},{0x3e, 0x28},{0x3f, 0xb0},{0x40, 0x90},{0x41, 0x0f},/*INTPEE*/{0xfe, 0x02},{0x90, 0x6c},{0x91, 0x03},{0x92, 0xcb},{0x94, 0x33},{0x95, 0x84},{0x97, 0x45},{0xa2, 0x11},{0xfe, 0x00},/*DNDD*/{0xfe, 0x02},{0x80, 0xc1},{0x81, 0x08},{0x82, 0x1f},{0x83, 0x10},{0x84, 0x0a},{0x86, 0xf0},{0x87, 0x50},{0x88, 0x15},{0x89, 0xb0},{0x8a, 0x30},{0x8b, 0x10},/*ASDE*/{0xfe, 0x01},{0x21, 0x04},{0xfe, 0x02},{0xa3, 0x50},{0xa4, 0x20},{0xa5, 0x40},{0xa6, 0x80},{0xab, 0x40},{0xae, 0x0c},{0xb3, 0x46},{0xb4, 0x64},{0xb6, 0x38},{0xb7, 0x01},{0xb9, 0x2b},{0x3c, 0x04},{0x3d, 0x15},{0x4b, 0x06},{0x4c, 0x20},{0xfe, 0x00},/*GAMMA*//*gamma1*/
#if 1{0xfe, 0x02},{0x10, 0x09},{0x11, 0x0d},{0x12, 0x13},{0x13, 0x19},{0x14, 0x27},{0x15, 0x37},{0x16, 0x45},{0x17, 0x53},{0x18, 0x69},{0x19, 0x7d},{0x1a, 0x8f},{0x1b, 0x9d},{0x1c, 0xa9},{0x1d, 0xbd},{0x1e, 0xcd},{0x1f, 0xd9},{0x20, 0xe3},{0x21, 0xea},{0x22, 0xef},{0x23, 0xf5},{0x24, 0xf9},{0x25, 0xff},
#else{0xfe, 0x02},{0x10, 0x0a},{0x11, 0x12},{0x12, 0x19},{0x13, 0x1f},{0x14, 0x2c},{0x15, 0x38},{0x16, 0x42},{0x17, 0x4e},{0x18, 0x63},{0x19, 0x76},{0x1a, 0x87},{0x1b, 0x96},{0x1c, 0xa2},{0x1d, 0xb8},{0x1e, 0xcb},{0x1f, 0xd8},{0x20, 0xe2},{0x21, 0xe9},{0x22, 0xf0},{0x23, 0xf8},{0x24, 0xfd},{0x25, 0xff},{0xfe, 0x00},
#endif{0xfe, 0x00},{0xc6, 0x20},{0xc7, 0x2b},/*gamma2*/
#if 1{0xfe, 0x02},{0x26, 0x0f},{0x27, 0x14},{0x28, 0x19},{0x29, 0x1e},{0x2a, 0x27},{0x2b, 0x33},{0x2c, 0x3b},{0x2d, 0x45},{0x2e, 0x59},{0x2f, 0x69},{0x30, 0x7c},{0x31, 0x89},{0x32, 0x98},{0x33, 0xae},{0x34, 0xc0},{0x35, 0xcf},{0x36, 0xda},{0x37, 0xe2},{0x38, 0xe9},{0x39, 0xf3},{0x3a, 0xf9},{0x3b, 0xff},
#else/*Gamma outdoor*/{0xfe, 0x02},{0x26, 0x17},{0x27, 0x18},{0x28, 0x1c},{0x29, 0x20},{0x2a, 0x28},{0x2b, 0x34},{0x2c, 0x40},{0x2d, 0x49},{0x2e, 0x5b},{0x2f, 0x6d},{0x30, 0x7d},{0x31, 0x89},{0x32, 0x97},{0x33, 0xac},{0x34, 0xc0},{0x35, 0xcf},{0x36, 0xda},{0x37, 0xe5},{0x38, 0xec},{0x39, 0xf8},{0x3a, 0xfd},{0x3b, 0xff},
#endif/*YCP*/{0xfe, 0x02},{0xd1, 0x40},{0xd2, 0x40},{0xd3, 0x48},{0xd6, 0xf0},{0xd7, 0x10},{0xd8, 0xda},{0xdd, 0x14},{0xde, 0x86},{0xed, 0x80},{0xee, 0x00},{0xef, 0x3f},{0xd8, 0xd8},/*abs*/{0xfe, 0x01},{0x9f, 0x40},/*LSC*/{0xfe, 0x01},{0xc2, 0x14},{0xc3, 0x0d},{0xc4, 0x0c},{0xc8, 0x15},{0xc9, 0x0d},{0xca, 0x0a},{0xbc, 0x24},{0xbd, 0x10},{0xbe, 0x0b},{0xb6, 0x25},{0xb7, 0x16},{0xb8, 0x15},{0xc5, 0x00},{0xc6, 0x00},{0xc7, 0x00},{0xcb, 0x00},{0xcc, 0x00},{0xcd, 0x00},{0xbf, 0x07},{0xc0, 0x00},{0xc1, 0x00},{0xb9, 0x00},{0xba, 0x00},{0xbb, 0x00},{0xaa, 0x01},{0xab, 0x01},{0xac, 0x00},{0xad, 0x05},{0xae, 0x06},{0xaf, 0x0e},{0xb0, 0x0b},{0xb1, 0x07},{0xb2, 0x06},{0xb3, 0x17},{0xb4, 0x0e},{0xb5, 0x0e},{0xd0, 0x09},{0xd1, 0x00},{0xd2, 0x00},{0xd6, 0x08},{0xd7, 0x00},{0xd8, 0x00},{0xd9, 0x00},{0xda, 0x00},{0xdb, 0x00},{0xd3, 0x0a},{0xd4, 0x00},{0xd5, 0x00},{0xa4, 0x00},{0xa5, 0x00},{0xa6, 0x77},{0xa7, 0x77},{0xa8, 0x77},{0xa9, 0x77},{0xa1, 0x80},{0xa2, 0x80},{0xfe, 0x01},{0xdf, 0x0d},{0xdc, 0x25},{0xdd, 0x30},{0xe0, 0x77},{0xe1, 0x80},{0xe2, 0x77},{0xe3, 0x90},{0xe6, 0x90},{0xe7, 0xa0},{0xe8, 0x90},{0xe9, 0xa0},{0xfe, 0x00},/*AWB*/{0xfe, 0x01},{0x4f, 0x00},{0x4f, 0x00},{0x4b, 0x01},{0x4f, 0x00},{0x4c, 0x01},{0x4d, 0x71},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x91},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x70},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x90},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xb0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x8f},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x6f},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xaf},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xd0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xf0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xcf},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xef},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x6e},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8e},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xae},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xce},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xad},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcd},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xac},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcc},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcb},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xab},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8a},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xaa},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xca},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xca},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xc9},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0x8a},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0x89},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xa9},{0x4e, 0x04},{0x4c, 0x02},{0x4d, 0x0b},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x0a},{0x4e, 0x05},{0x4c, 0x01},{0x4d, 0xeb},{0x4e, 0x05},{0x4c, 0x01},{0x4d, 0xea},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x09},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x29},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x2a},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x4a},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x8a},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x49},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x69},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x89},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0xa9},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x48},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x68},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x69},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0xca},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc9},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe9},{0x4e, 0x07},{0x4c, 0x03},{0x4d, 0x09},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc8},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe8},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xa7},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc7},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe7},{0x4e, 0x07},{0x4c, 0x03},{0x4d, 0x07},{0x4e, 0x07},{0x4f, 0x01},{0x50, 0x80},{0x51, 0xa8},{0x52, 0x47},{0x53, 0x38},{0x54, 0xc7},{0x56, 0x0e},{0x58, 0x08},{0x5b, 0x00},{0x5c, 0x74},{0x5d, 0x8b},{0x61, 0xdb},{0x62, 0xb8},{0x63, 0x86},{0x64, 0xc0},{0x65, 0x04},{0x67, 0xa8},{0x68, 0xb0},{0x69, 0x00},{0x6a, 0xa8},{0x6b, 0xb0},{0x6c, 0xaf},{0x6d, 0x8b},{0x6e, 0x50},{0x6f, 0x18},{0x73, 0xf0},{0x70, 0x0d},{0x71, 0x60},{0x72, 0x80},{0x74, 0x01},{0x75, 0x01},{0x7f, 0x0c},{0x76, 0x70},{0x77, 0x58},{0x78, 0xa0},{0x79, 0x5e},{0x7a, 0x54},{0x7b, 0x58},{0xfe, 0x00},/*CC*/{0xfe, 0x02},{0xc0, 0x01},{0xc1, 0x44},{0xc2, 0xfd},{0xc3, 0x04},{0xc4, 0xF0},{0xc5, 0x48},{0xc6, 0xfd},{0xc7, 0x46},{0xc8, 0xfd},{0xc9, 0x02},{0xca, 0xe0},{0xcb, 0x45},{0xcc, 0xec},{0xcd, 0x48},{0xce, 0xf0},{0xcf, 0xf0},{0xe3, 0x0c},{0xe4, 0x4b},{0xe5, 0xe0},/*ABS*/{0xfe, 0x01},{0x9f, 0x40},{0xfe, 0x00},/*OUTPUT*/{0xfe, 0x00},{0xf2, 0x0f},/*dark sun*/{0xfe, 0x02},{0x40, 0xbf},{0x46, 0xcf},{0xfe, 0x00},/*frame rate 50Hz*/{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0x32},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xfe, 0x00},{0xfd, 0x01},{0xfa, 0x00},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x02},{0x96, 0x58},{0x97, 0x03},{0x98, 0x20},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x02},{0xed, 0x02},{0xee, 0x30},{0xef, 0x48},{0xfe, 0x02},{0x9d, 0x08},{0xfe, 0x01},{0x74, 0x00},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0x60},{0x03, 0x02},{0x04, 0x48},{0x05, 0x18},{0x06, 0x50},{0x07, 0x10},{0x08, 0x38},{0x0a, 0x80},{0x21, 0x04},{0xfe, 0x00},{0x20, 0x03},{0xfe, 0x00},{REG_NULL, 0x00},
};/* Senor full resolution setting */
static const struct sensor_register gc2145_dvp_full[] = {//SENSORDB("GC2145_Sensor_2M"},{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0x50},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xfd, 0x00},{0xfa, 0x11},{0x18, 0x22},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x04},{0x96, 0xb0},{0x97, 0x06},{0x98, 0x40},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x06},{0xed, 0x04},{0xee, 0x60},{0xef, 0x90},{0xfe, 0x01},{0x74, 0x01},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0xc0},{0x03, 0x04},{0x04, 0x90},{0x05, 0x30},{0x06, 0x90},{0x07, 0x30},{0x08, 0x80},{0x0a, 0x82},{0xfe, 0x01},{0x21, 0x15}, //if 0xfa=11,then 0x21=15;{0xfe, 0x00}, //else if 0xfa=00,then 0x21=04{0x20, 0x15},{0xfe, 0x00},{REG_NULL, 0x00},
};/* Preview resolution setting*/
static const struct sensor_register gc2145_dvp_svga_30fps[] = {/*frame rate 50Hz*/{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0xb8},{0xfe, 0x01},{0x13, 0x7b},{0x18, 0x95},{0x25, 0x01},{0x26, 0xac},{0x27, 0x05},{0x28, 0x04},{0x29, 0x05},{0x2a, 0x04},{0x2b, 0x05},{0x2c, 0x04},{0x2d, 0x05},{0x2e, 0x04},{0x3c, 0x00},{0x3d, 0x15},{0xfe, 0x00},{0xfe, 0x00},{0xfa, 0x00},{0x18, 0x42},{0xfd, 0x03},{0xb6, 0x01},/* crop window */{0xfe, 0x00},{0x99, 0x11},{0x9a, 0x06},{0x9b, 0x00},{0x9c, 0x00},{0x9d, 0x00},{0x9e, 0x00},{0x9f, 0x00},{0xa0, 0x00},{0xa1, 0x00},{0xa2, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x02},{0x96, 0x58},{0x97, 0x03},{0x98, 0x20},/* AWB */{0xfe, 0x00},{0xec, 0x01},{0xed, 0x02},{0xee, 0x30},{0xef, 0x48},{0xfe, 0x01},{0x74, 0x00},/* AEC */{0xfe, 0x01},{0x01, 0x04},{0x02, 0x60},{0x03, 0x02},{0x04, 0x48},{0x05, 0x18},{0x06, 0x4c},{0x07, 0x14},{0x08, 0x36},{0x0a, 0xc0},{0x21, 0x14},{0xfe, 0x00},{REG_NULL, 0x00},
};/* Preview resolution setting*/
static const struct sensor_register gc2145_dvp_svga_20fps[] = {//SENSORDB("GC2145_Sensor_SVGA"},{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0x50},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xb6, 0x01},{0xfd, 0x01},{0xfa, 0x00},{0x18, 0x22},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x02},{0x96, 0x58},{0x97, 0x03},{0x98, 0x20},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x02},{0xed, 0x02},{0xee, 0x30},{0xef, 0x48},{0xfe, 0x02},{0x9d, 0x08},{0xfe, 0x01},{0x74, 0x00},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0x60},{0x03, 0x02},{0x04, 0x48},{0x05, 0x18},{0x06, 0x50},{0x07, 0x10},{0x08, 0x38},{0x0a, 0x80},{0x21, 0x04},{0xfe, 0x00},{0x20, 0x03},{0xfe, 0x00},{REG_NULL, 0x00},
};static const struct sensor_register gc2145_mipi_init_regs[] = {{0xfe, 0xf0},{0xfe, 0xf0},{0xfe, 0xf0},{0xfc, 0x06},{0xf6, 0x00},{0xf7, 0x1d},{0xf8, 0x84},{0xfa, 0x00},{0xf9, 0x8e},{0xf2, 0x00},/*ISP reg*/{0xfe, 0x00},{0x03, 0x04},{0x04, 0xe2},{0x09, 0x00},{0x0a, 0x00},{0x0b, 0x00},{0x0c, 0x00},{0x0d, 0x04},{0x0e, 0xc0},{0x0f, 0x06},{0x10, 0x52},{0x12, 0x2e},{0x17, 0x14},{0x18, 0x22},{0x19, 0x0e},{0x1a, 0x01},{0x1b, 0x4b},{0x1c, 0x07},{0x1d, 0x10},{0x1e, 0x88},{0x1f, 0x78},{0x20, 0x03},{0x21, 0x40},{0x22, 0xa0},{0x24, 0x16},{0x25, 0x01},{0x26, 0x10},{0x2d, 0x60},{0x30, 0x01},{0x31, 0x90},{0x33, 0x06},{0x34, 0x01},{0xfe, 0x00},{0x80, 0x7f},{0x81, 0x26},{0x82, 0xfa},{0x83, 0x00},{0x84, 0x00},{0x86, 0x02},{0x88, 0x03},{0x89, 0x03},{0x85, 0x08},{0x8a, 0x00},{0x8b, 0x00},{0xb0, 0x55},{0xc3, 0x00},{0xc4, 0x80},{0xc5, 0x90},{0xc6, 0x3b},{0xc7, 0x46},{0xec, 0x06},{0xed, 0x04},{0xee, 0x60},{0xef, 0x90},{0xb6, 0x01},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x04},{0x96, 0xb0},{0x97, 0x06},{0x98, 0x40},/*BLK*/{0xfe, 0x00},{0x40, 0x42},{0x41, 0x00},{0x43, 0x5b},{0x5e, 0x00},{0x5f, 0x00},{0x60, 0x00},{0x61, 0x00},{0x62, 0x00},{0x63, 0x00},{0x64, 0x00},{0x65, 0x00},{0x66, 0x20},{0x67, 0x20},{0x68, 0x20},{0x69, 0x20},{0x76, 0x00},{0x6a, 0x08},{0x6b, 0x08},{0x6c, 0x08},{0x6d, 0x08},{0x6e, 0x08},{0x6f, 0x08},{0x70, 0x08},{0x71, 0x08},{0x76, 0x00},{0x72, 0xf0},{0x7e, 0x3c},{0x7f, 0x00},{0xfe, 0x02},{0x48, 0x15},{0x49, 0x00},{0x4b, 0x0b},{0xfe, 0x00},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0xc0},{0x03, 0x04},{0x04, 0x90},{0x05, 0x30},{0x06, 0x90},{0x07, 0x30},{0x08, 0x80},{0x09, 0x00},{0x0a, 0x82},{0x0b, 0x11},{0x0c, 0x10},{0x11, 0x10},{0x13, 0x7b},{0x17, 0x00},{0x1c, 0x11},{0x1e, 0x61},{0x1f, 0x35},{0x20, 0x40},{0x22, 0x40},{0x23, 0x20},{0xfe, 0x02},{0x0f, 0x04},{0xfe, 0x01},{0x12, 0x35},{0x15, 0xb0},{0x10, 0x31},{0x3e, 0x28},{0x3f, 0xb0},{0x40, 0x90},{0x41, 0x0f},/*INTPEE*/{0xfe, 0x02},{0x90, 0x6c},{0x91, 0x03},{0x92, 0xcb},{0x94, 0x33},{0x95, 0x84},{0x97, 0x65},{0xa2, 0x11},{0xfe, 0x00},/*DNDD*/{0xfe, 0x02},{0x80, 0xc1},{0x81, 0x08},{0x82, 0x05},{0x83, 0x08},{0x84, 0x0a},{0x86, 0xf0},{0x87, 0x50},{0x88, 0x15},{0x89, 0xb0},{0x8a, 0x30},{0x8b, 0x10},/*ASDE*/{0xfe, 0x01},{0x21, 0x04},{0xfe, 0x02},{0xa3, 0x50},{0xa4, 0x20},{0xa5, 0x40},{0xa6, 0x80},{0xab, 0x40},{0xae, 0x0c},{0xb3, 0x46},{0xb4, 0x64},{0xb6, 0x38},{0xb7, 0x01},{0xb9, 0x2b},{0x3c, 0x04},{0x3d, 0x15},{0x4b, 0x06},{0x4c, 0x20},{0xfe, 0x00},/*GAMMA*//*gamma1*/{0xfe, 0x02},{0x10, 0x09},{0x11, 0x0d},{0x12, 0x13},{0x13, 0x19},{0x14, 0x27},{0x15, 0x37},{0x16, 0x45},{0x17, 0x53},{0x18, 0x69},{0x19, 0x7d},{0x1a, 0x8f},{0x1b, 0x9d},{0x1c, 0xa9},{0x1d, 0xbd},{0x1e, 0xcd},{0x1f, 0xd9},{0x20, 0xe3},{0x21, 0xea},{0x22, 0xef},{0x23, 0xf5},{0x24, 0xf9},{0x25, 0xff},{0xfe, 0x00},{0xc6, 0x20},{0xc7, 0x2b},/*gamma2*/{0xfe, 0x02},{0x26, 0x0f},{0x27, 0x14},{0x28, 0x19},{0x29, 0x1e},{0x2a, 0x27},{0x2b, 0x33},{0x2c, 0x3b},{0x2d, 0x45},{0x2e, 0x59},{0x2f, 0x69},{0x30, 0x7c},{0x31, 0x89},{0x32, 0x98},{0x33, 0xae},{0x34, 0xc0},{0x35, 0xcf},{0x36, 0xda},{0x37, 0xe2},{0x38, 0xe9},{0x39, 0xf3},{0x3a, 0xf9},{0x3b, 0xff},/*YCP*/{0xfe, 0x02},{0xd1, 0x32},{0xd2, 0x32},{0xd3, 0x40},{0xd6, 0xf0},{0xd7, 0x10},{0xd8, 0xda},{0xdd, 0x14},{0xde, 0x86},{0xed, 0x80},{0xee, 0x00},{0xef, 0x3f},{0xd8, 0xd8},/*abs*/{0xfe, 0x01},{0x9f, 0x40},/*LSC*/{0xfe, 0x01},{0xc2, 0x14},{0xc3, 0x0d},{0xc4, 0x0c},{0xc8, 0x15},{0xc9, 0x0d},{0xca, 0x0a},{0xbc, 0x24},{0xbd, 0x10},{0xbe, 0x0b},{0xb6, 0x25},{0xb7, 0x16},{0xb8, 0x15},{0xc5, 0x00},{0xc6, 0x00},{0xc7, 0x00},{0xcb, 0x00},{0xcc, 0x00},{0xcd, 0x00},{0xbf, 0x07},{0xc0, 0x00},{0xc1, 0x00},{0xb9, 0x00},{0xba, 0x00},{0xbb, 0x00},{0xaa, 0x01},{0xab, 0x01},{0xac, 0x00},{0xad, 0x05},{0xae, 0x06},{0xaf, 0x0e},{0xb0, 0x0b},{0xb1, 0x07},{0xb2, 0x06},{0xb3, 0x17},{0xb4, 0x0e},{0xb5, 0x0e},{0xd0, 0x09},{0xd1, 0x00},{0xd2, 0x00},{0xd6, 0x08},{0xd7, 0x00},{0xd8, 0x00},{0xd9, 0x00},{0xda, 0x00},{0xdb, 0x00},{0xd3, 0x0a},{0xd4, 0x00},{0xd5, 0x00},{0xa4, 0x00},{0xa5, 0x00},{0xa6, 0x77},{0xa7, 0x77},{0xa8, 0x77},{0xa9, 0x77},{0xa1, 0x80},{0xa2, 0x80},{0xfe, 0x01},{0xdf, 0x0d},{0xdc, 0x25},{0xdd, 0x30},{0xe0, 0x77},{0xe1, 0x80},{0xe2, 0x77},{0xe3, 0x90},{0xe6, 0x90},{0xe7, 0xa0},{0xe8, 0x90},{0xe9, 0xa0},{0xfe, 0x00},/*AWB*/{0xfe, 0x01},{0x4f, 0x00},{0x4f, 0x00},{0x4b, 0x01},{0x4f, 0x00},{0x4c, 0x01},{0x4d, 0x71},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x91},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x70},{0x4e, 0x01},{0x4c, 0x01},{0x4d, 0x90},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xb0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x8f},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x6f},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xaf},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xd0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xf0},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xcf},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0xef},{0x4e, 0x02},{0x4c, 0x01},{0x4d, 0x6e},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8e},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xae},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xce},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8d},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xad},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcd},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8c},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xac},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcc},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xcb},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x4b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x6b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8b},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0xab},{0x4e, 0x03},{0x4c, 0x01},{0x4d, 0x8a},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xaa},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xca},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xca},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xc9},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0x8a},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0x89},{0x4e, 0x04},{0x4c, 0x01},{0x4d, 0xa9},{0x4e, 0x04},{0x4c, 0x02},{0x4d, 0x0b},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x0a},{0x4e, 0x05},{0x4c, 0x01},{0x4d, 0xeb},{0x4e, 0x05},{0x4c, 0x01},{0x4d, 0xea},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x09},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x29},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x2a},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x4a},{0x4e, 0x05},{0x4c, 0x02},{0x4d, 0x8a},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x49},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x69},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x89},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0xa9},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x48},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x68},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0x69},{0x4e, 0x06},{0x4c, 0x02},{0x4d, 0xca},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc9},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe9},{0x4e, 0x07},{0x4c, 0x03},{0x4d, 0x09},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc8},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe8},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xa7},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xc7},{0x4e, 0x07},{0x4c, 0x02},{0x4d, 0xe7},{0x4e, 0x07},{0x4c, 0x03},{0x4d, 0x07},{0x4e, 0x07},{0x4f, 0x01},{0x50, 0x80},{0x51, 0xa8},{0x52, 0x47},{0x53, 0x38},{0x54, 0xc7},{0x56, 0x0e},{0x58, 0x08},{0x5b, 0x00},{0x5c, 0x74},{0x5d, 0x8b},{0x61, 0xdb},{0x62, 0xb8},{0x63, 0x86},{0x64, 0xc0},{0x65, 0x04},{0x67, 0xa8},{0x68, 0xb0},{0x69, 0x00},{0x6a, 0xa8},{0x6b, 0xb0},{0x6c, 0xaf},{0x6d, 0x8b},{0x6e, 0x50},{0x6f, 0x18},{0x73, 0xf0},{0x70, 0x0d},{0x71, 0x60},{0x72, 0x80},{0x74, 0x01},{0x75, 0x01},{0x7f, 0x0c},{0x76, 0x70},{0x77, 0x58},{0x78, 0xa0},{0x79, 0x5e},{0x7a, 0x54},{0x7b, 0x58},{0xfe, 0x00},/*CC*/{0xfe, 0x02},{0xc0, 0x01},{0xc1, 0x44},{0xc2, 0xfd},{0xc3, 0x04},{0xc4, 0xF0},{0xc5, 0x48},{0xc6, 0xfd},{0xc7, 0x46},{0xc8, 0xfd},{0xc9, 0x02},{0xca, 0xe0},{0xcb, 0x45},{0xcc, 0xec},{0xcd, 0x48},{0xce, 0xf0},{0xcf, 0xf0},{0xe3, 0x0c},{0xe4, 0x4b},{0xe5, 0xe0},/*ABS*/{0xfe, 0x01},{0x9f, 0x40},{0xfe, 0x00},/*OUTPUT*/{0xfe, 0x00},{0xf2, 0x00},/*frame rate 50Hz*/{0xfe, 0x00},{0x05, 0x01},{0x06, 0x56},{0x07, 0x00},{0x08, 0x32},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xfe, 0x02},{0x40, 0xbf},{0x46, 0xcf},{0xfe, 0x00},{0xfe, 0x03},{0x02, 0x22},{0x03, 0x10},{0x04, 0x10},{0x05, 0x00},{0x06, 0x88},{0x01, 0x83},{0x10, 0x84},{0x11, 0x1e},{0x12, 0x80},{0x13, 0x0c},{0x15, 0x10},{0x17, 0xf0},{0x21, 0x10},{0x22, 0x04},{0x23, 0x10},{0x24, 0x10},{0x25, 0x10},{0x26, 0x05},{0x29, 0x03},{0x2a, 0x0a},{0x2b, 0x06},{0xfe, 0x00},{REG_NULL, 0x00},
};static const struct sensor_register gc2145_mipi_full[] = {/*SENSORDB("GC2145_Sensor_2M")*/{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0x50},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xfd, 0x00},{0xfa, 0x11},{0x18, 0x22},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x04},{0x96, 0xb0},{0x97, 0x06},{0x98, 0x40},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x06},{0xed, 0x04},{0xee, 0x60},{0xef, 0x90},{0xfe, 0x01},{0x74, 0x01},{0xfe, 0x00},{0x7e, 0x3c},{0x7f, 0x00},{0xfe, 0x01},{0xa0, 0x03},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0xc0},{0x03, 0x04},{0x04, 0x90},{0x05, 0x30},{0x06, 0x90},{0x07, 0x30},{0x08, 0x80},{0x0a, 0x82},{0x1b, 0x01},{0xfe, 0x00},{0xfe, 0x01},{0x21, 0x15},{0xfe, 0x00},{0x20, 0x15},{0xfe, 0x03},{0x12, 0x80},{0x13, 0x0c},{0x04, 0x01},{0x05, 0x00},{0xfe, 0x00},{REG_NULL, 0x00},
};static const struct sensor_register gc2145_mipi_svga_20fps[] = {/*frame rate 50Hz*/{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0x50},{0xfe, 0x01},{0x25, 0x00},{0x26, 0xfa},{0x27, 0x04},{0x28, 0xe2},{0x29, 0x04},{0x2a, 0xe2},{0x2b, 0x04},{0x2c, 0xe2},{0x2d, 0x04},{0x2e, 0xe2},{0xfe, 0x00},{0xb6, 0x01},{0xfd, 0x01},{0xfa, 0x00},{0x18, 0x22},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x02},{0x96, 0x58},{0x97, 0x03},{0x98, 0x20},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x02},{0xed, 0x02},{0xee, 0x30},{0xef, 0x48},{0xfe, 0x02},{0x9d, 0x08},{0xfe, 0x01},{0x74, 0x00},{0xfe, 0x00},{0x7e, 0x3c},{0x7f, 0x00},{0xfe, 0x01},{0xa0, 0x03},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0x60},{0x03, 0x02},{0x04, 0x48},{0x05, 0x18},{0x06, 0x50},{0x07, 0x10},{0x08, 0x38},{0x0a, 0x80},//{0x1b, 0x04},{0x21, 0x04},{0xfe, 0x00},{0x20, 0x03},{0xfe, 0x03},{0x12, 0x40},{0x13, 0x06},{0x04, 0x01},{0x05, 0x00},{0xfe, 0x00},{REG_NULL, 0x00},
};static const struct sensor_register gc2145_mipi_svga_30fps[] = {/*frame rate 50Hz*/{0xfe, 0x00},{0x05, 0x02},{0x06, 0x20},{0x07, 0x00},{0x08, 0xb8},{0xfe, 0x01},{0x25, 0x01},{0x26, 0xac},{0x27, 0x05},//4e2 pad{0x28, 0x04},{0x29, 0x05},//6d6 pad{0x2a, 0x04},{0x2b, 0x05},//7d0 pad{0x2c, 0x04},{0x2d, 0x05},{0x2e, 0x04},{0xfe, 0x00},{0xfe, 0x00},{0xfd, 0x01},{0xfa, 0x00},{0x18, 0x62},{0xfd, 0x03},/*crop window*/{0xfe, 0x00},{0x90, 0x01},{0x91, 0x00},{0x92, 0x00},{0x93, 0x00},{0x94, 0x00},{0x95, 0x02},{0x96, 0x58},{0x97, 0x03},{0x98, 0x20},{0x99, 0x11},{0x9a, 0x06},/*AWB*/{0xfe, 0x00},{0xec, 0x02},{0xed, 0x02},{0xee, 0x30},{0xef, 0x48},{0xfe, 0x02},{0x9d, 0x08},{0xfe, 0x01},{0x74, 0x00},{0xfe, 0x00},{0x7e, 0x00},{0x7f, 0x60},{0xfe, 0x01},{0xa0, 0x0b},/*AEC*/{0xfe, 0x01},{0x01, 0x04},{0x02, 0x60},{0x03, 0x02},{0x04, 0x48},{0x05, 0x18},{0x06, 0x50},{0x07, 0x10},{0x08, 0x38},{0x0a, 0xc0},{0x1b, 0x04},{0x21, 0x04},{0xfe, 0x00},{0x20, 0x03},{0xfe, 0x03},{0x12, 0x40},{0x13, 0x06},{0x04, 0x01},{0x05, 0x00},{0xfe, 0x00},{REG_NULL, 0x00},
};static const struct gc2145_framesize gc2145_dvp_framesizes[] = {{ /* SVGA */.width		= 800,.height		= 600,.max_fps = {.numerator = 10000,.denominator = 160000,},.regs		= gc2145_dvp_svga_20fps,}, { /* SVGA */.width		= 800,.height		= 600,.max_fps = {.numerator = 10000,.denominator = 300000,},.regs		= gc2145_dvp_svga_30fps,}, { /* FULL */.width		= 1600,.height		= 1200,.max_fps = {.numerator = 10000,.denominator = 160000,},.regs		= gc2145_dvp_full,}
};static const struct gc2145_framesize gc2145_mipi_framesizes[] = {{ /* SVGA */.width		= 800,.height		= 600,.max_fps = {.numerator = 10000,.denominator = 160000,},.regs		= gc2145_mipi_svga_20fps,}, { /* SVGA */.width		= 800,.height		= 600,.max_fps = {.numerator = 10000,.denominator = 300000,},.regs		= gc2145_mipi_svga_30fps,}, { /* FULL */.width		= 1600,.height		= 1200,.max_fps = {.numerator = 10000,.denominator = 160000,},.regs		= gc2145_mipi_full,}
};static const s64 link_freq_menu_items[] = {240000000
};static const struct gc2145_pixfmt gc2145_formats[] = {{.code = MEDIA_BUS_FMT_UYVY8_2X8,}
};static inline struct gc2145 *to_gc2145(struct v4l2_subdev *sd)
{return container_of(sd, struct gc2145, sd);
}/* sensor register write */
static int gc2145_write(struct i2c_client *client, u8 reg, u8 val)
{struct i2c_msg msg;u8 buf[2];int ret;dev_dbg(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val);buf[0] = reg & 0xFF;buf[1] = val;msg.addr = client->addr;msg.flags = client->flags;msg.buf = buf;msg.len = sizeof(buf);ret = i2c_transfer(client->adapter, &msg, 1);if (ret >= 0)return 0;dev_err(&client->dev,"gc2145 write reg(0x%x val:0x%x) failed !\n", reg, val);return ret;
}/* sensor register read */
static int gc2145_read(struct i2c_client *client, u8 reg, u8 *val)
{struct i2c_msg msg[2];u8 buf[1];int ret;buf[0] = reg & 0xFF;msg[0].addr = client->addr;msg[0].flags = client->flags;msg[0].buf = buf;msg[0].len = sizeof(buf);msg[1].addr = client->addr;msg[1].flags = client->flags | I2C_M_RD;msg[1].buf = buf;msg[1].len = 1;ret = i2c_transfer(client->adapter, msg, 2);if (ret >= 0) {*val = buf[0];return 0;}dev_err(&client->dev,"gc2145 read reg:0x%x failed !\n", reg);return ret;
}static int gc2145_write_array(struct i2c_client *client,const struct sensor_register *regs)
{int i, ret = 0;i = 0;while (regs[i].addr != REG_NULL) {ret = gc2145_write(client, regs[i].addr, regs[i].value);if (ret) {dev_err(&client->dev, "%s failed !\n", __func__);break;}i++;}return ret;
}static void gc2145_get_default_format(struct gc2145 *gc2145,struct v4l2_mbus_framefmt *format)
{format->width = gc2145->framesize_cfg[0].width;format->height = gc2145->framesize_cfg[0].height;format->colorspace = V4L2_COLORSPACE_SRGB;format->code = gc2145_formats[0].code;format->field = V4L2_FIELD_NONE;
}static void gc2145_set_streaming(struct gc2145 *gc2145, int on)
{struct i2c_client *client = gc2145->client;int ret = 0;u8 val;dev_dbg(&client->dev, "%s: on: %d\n", __func__, on);if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) {val = on ? 0x94 : 0x84;ret = gc2145_write(client, 0xfe, 0x03);ret |= gc2145_write(client, 0x10, val);} else {val = on ? 0x0f : 0;ret = gc2145_write(client, 0xf2, val);}if (ret)dev_err(&client->dev, "gc2145 soft standby failed\n");
}/** V4L2 subdev video and pad level operations*/static int gc2145_enum_mbus_code(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_mbus_code_enum *code)
{struct i2c_client *client = v4l2_get_subdevdata(sd);dev_dbg(&client->dev, "%s:\n", __func__);if (code->index >= ARRAY_SIZE(gc2145_formats))return -EINVAL;code->code = gc2145_formats[code->index].code;return 0;
}static int gc2145_enum_frame_sizes(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_size_enum *fse)
{struct gc2145 *gc2145 = to_gc2145(sd);struct i2c_client *client = v4l2_get_subdevdata(sd);int i = ARRAY_SIZE(gc2145_formats);dev_dbg(&client->dev, "%s:\n", __func__);if (fse->index >= gc2145->cfg_num)return -EINVAL;while (--i)if (fse->code == gc2145_formats[i].code)break;fse->code = gc2145_formats[i].code;fse->min_width  = gc2145->framesize_cfg[fse->index].width;fse->max_width  = fse->min_width;fse->max_height = gc2145->framesize_cfg[fse->index].height;fse->min_height = fse->max_height;return 0;
}static int gc2145_get_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *fmt)
{struct i2c_client *client = v4l2_get_subdevdata(sd);struct gc2145 *gc2145 = to_gc2145(sd);dev_dbg(&client->dev, "%s enter\n", __func__);if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_APIstruct v4l2_mbus_framefmt *mf;mf = v4l2_subdev_get_try_format(sd, cfg, 0);mutex_lock(&gc2145->lock);fmt->format = *mf;mutex_unlock(&gc2145->lock);return 0;
#elsereturn -ENOTTY;
#endif}mutex_lock(&gc2145->lock);fmt->format = gc2145->format;mutex_unlock(&gc2145->lock);dev_dbg(&client->dev, "%s: %x %dx%d\n", __func__,gc2145->format.code, gc2145->format.width,gc2145->format.height);return 0;
}static void __gc2145_try_frame_size_fps(struct gc2145 *gc2145,struct v4l2_mbus_framefmt *mf,const struct gc2145_framesize **size,unsigned int fps)
{const struct gc2145_framesize *fsize = &gc2145->framesize_cfg[0];const struct gc2145_framesize *match = NULL;unsigned int i = gc2145->cfg_num;unsigned int min_err = UINT_MAX;while (i--) {unsigned int err = abs(fsize->width - mf->width)+ abs(fsize->height - mf->height);if (err < min_err && fsize->regs[0].addr) {min_err = err;match = fsize;}fsize++;}if (!match) {match = &gc2145->framesize_cfg[0];} else {fsize = &gc2145->framesize_cfg[0];for (i = 0; i < gc2145->cfg_num; i++) {if (fsize->width == match->width &&fsize->height == match->height &&fps >= DIV_ROUND_CLOSEST(fsize->max_fps.denominator,fsize->max_fps.numerator))match = fsize;fsize++;}}mf->width  = match->width;mf->height = match->height;if (size)*size = match;
}#ifdef GC2145_EXPOSURE_CONTROL
/** the function is called before sensor register setting in VIDIOC_S_FMT*/
/* Row times = Hb + Sh_delay + win_width + 4*/static int gc2145_aec_ctrl(struct v4l2_subdev *sd,struct v4l2_mbus_framefmt *mf)
{struct i2c_client *client = v4l2_get_subdevdata(sd);int ret = 0;u8 value;static unsigned int capture_fps = 10, capture_lines = 1266;static unsigned int preview_fps = 20, preview_lines = 1266;static unsigned int lines_10ms = 1;static unsigned int shutter_h = 0x04, shutter_l = 0xe2;static unsigned int cap = 0, shutter = 0x04e2;dev_info(&client->dev, "%s enter\n", __func__);if ((mf->width == 800 && mf->height == 600) && cap == 1) {cap = 0;ret = gc2145_write(client, 0xfe, 0x00);ret |= gc2145_write(client, 0xb6, 0x00);ret |= gc2145_write(client, 0x03, shutter_h);ret |= gc2145_write(client, 0x04, shutter_l);ret |= gc2145_write(client, 0x82, 0xfa);ret |= gc2145_write(client, 0xb6, 0x01);if (ret)dev_err(&client->dev, "gc2145 reconfig failed!\n");}if (mf->width == 1600 && mf->height == 1200) {cap = 1;ret = gc2145_write(client, 0xfe, 0x00);ret |= gc2145_write(client, 0xb6, 0x00);ret |= gc2145_write(client, 0x82, 0xf8);/*shutter calculate*/ret |= gc2145_read(client, 0x03, &value);shutter_h = value;shutter = (value << 8);ret |= gc2145_read(client, 0x04, &value);shutter_l = value;shutter |= (value & 0xff);dev_info(&client->dev, "%s(%d) 800x600 shutter read(0x%04x)!\n",__func__, __LINE__, shutter);shutter = shutter * capture_lines / preview_lines;shutter = shutter * capture_fps / preview_fps;lines_10ms = capture_fps * capture_lines / 100;if (shutter > lines_10ms) {shutter = shutter + lines_10ms / 2;shutter /= lines_10ms;shutter *= lines_10ms;}if (shutter < 1)shutter = 0x276;dev_info(&client->dev, "%s(%d)lines_10ms(%d),cal(0x%08x)!\n",__func__, __LINE__, lines_10ms, shutter);ret |= gc2145_write(client, 0x03, ((shutter >> 8) & 0x1f));ret |= gc2145_write(client, 0x04, (shutter & 0xff));if (ret)dev_err(&client->dev, "full exp reconfig failed!\n");}return ret;
}
#endifstatic int gc2145_set_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *fmt)
{struct i2c_client *client = v4l2_get_subdevdata(sd);int index = ARRAY_SIZE(gc2145_formats);struct v4l2_mbus_framefmt *mf = &fmt->format;const struct gc2145_framesize *size = NULL;struct gc2145 *gc2145 = to_gc2145(sd);dev_info(&client->dev, "%s enter\n", __func__);__gc2145_try_frame_size_fps(gc2145, mf, &size, gc2145->fps);while (--index >= 0)if (gc2145_formats[index].code == mf->code)break;if (index < 0)return -EINVAL;mf->colorspace = V4L2_COLORSPACE_SRGB;mf->code = gc2145_formats[index].code;mf->field = V4L2_FIELD_NONE;mutex_lock(&gc2145->lock);if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_APImf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);*mf = fmt->format;
#elsereturn -ENOTTY;
#endif} else {if (gc2145->streaming) {mutex_unlock(&gc2145->lock);return -EBUSY;}gc2145->frame_size = size;gc2145->format = fmt->format;}#ifdef GC2145_EXPOSURE_CONTROLif (gc2145->power_on)gc2145_aec_ctrl(sd, mf);
#endifmutex_unlock(&gc2145->lock);return 0;
}static int gc2145_init(struct v4l2_subdev *sd, u32 val);
static int gc2145_s_stream(struct v4l2_subdev *sd, int on)
{struct i2c_client *client = v4l2_get_subdevdata(sd);struct gc2145 *gc2145 = to_gc2145(sd);int ret = 0;unsigned int fps;unsigned int delay_us;fps = DIV_ROUND_CLOSEST(gc2145->frame_size->max_fps.denominator,gc2145->frame_size->max_fps.numerator);dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,gc2145->frame_size->width,gc2145->frame_size->height,DIV_ROUND_CLOSEST(gc2145->frame_size->max_fps.denominator,gc2145->frame_size->max_fps.numerator));mutex_lock(&gc2145->lock);on = !!on;if (gc2145->streaming == on)goto unlock;if (!on) {/* Stop Streaming Sequence */gc2145_set_streaming(gc2145, on);gc2145->streaming = on;/* delay to enable oneframe complete */delay_us = 1000 * 1000 / fps;usleep_range(delay_us, delay_us+10);dev_info(&client->dev, "%s: on: %d, sleep(%dus)\n",__func__, on, delay_us);goto unlock;}if (ret)dev_err(&client->dev, "init error\n");ret = gc2145_write_array(client, gc2145->frame_size->regs);if (ret)goto unlock;gc2145_set_streaming(gc2145, on);gc2145->streaming = on;unlock:mutex_unlock(&gc2145->lock);return ret;
}static int gc2145_set_test_pattern(struct gc2145 *gc2145, int value)
{return 0;
}static int gc2145_s_ctrl(struct v4l2_ctrl *ctrl)
{struct gc2145 *gc2145 =container_of(ctrl->handler, struct gc2145, ctrls);switch (ctrl->id) {case V4L2_CID_TEST_PATTERN:return gc2145_set_test_pattern(gc2145, ctrl->val);}return 0;
}static const struct v4l2_ctrl_ops gc2145_ctrl_ops = {.s_ctrl = gc2145_s_ctrl,
};static const char * const gc2145_test_pattern_menu[] = {"Disabled","Vertical Color Bars",
};/* -----------------------------------------------------------------------------* V4L2 subdev internal operations*/#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
static int gc2145_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{struct gc2145 *gc2145 = to_gc2145(sd);struct i2c_client *client = v4l2_get_subdevdata(sd);struct v4l2_mbus_framefmt *format =v4l2_subdev_get_try_format(sd, fh->pad, 0);dev_dbg(&client->dev, "%s:\n", __func__);gc2145_get_default_format(gc2145, format);return 0;
}
#endifstatic int gc2145_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,struct v4l2_mbus_config *config)
{struct gc2145 *gc2145 = to_gc2145(sd);if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) {config->type = V4L2_MBUS_CSI2_DPHY;config->flags = V4L2_MBUS_CSI2_1_LANE |V4L2_MBUS_CSI2_CHANNEL_0 |V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;} else {config->type = V4L2_MBUS_PARALLEL;config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |V4L2_MBUS_VSYNC_ACTIVE_LOW |V4L2_MBUS_PCLK_SAMPLE_RISING;}return 0;
}static int gc2145_g_frame_interval(struct v4l2_subdev *sd,struct v4l2_subdev_frame_interval *fi)
{struct gc2145 *gc2145 = to_gc2145(sd);fi->interval = gc2145->frame_size->max_fps;return 0;
}static int gc2145_s_frame_interval(struct v4l2_subdev *sd,struct v4l2_subdev_frame_interval *fi)
{struct i2c_client *client = v4l2_get_subdevdata(sd);struct gc2145 *gc2145 = to_gc2145(sd);const struct gc2145_framesize *size = NULL;struct v4l2_mbus_framefmt mf;unsigned int fps;int ret = 0;dev_dbg(&client->dev, "Setting %d/%d frame interval\n",fi->interval.numerator, fi->interval.denominator);mutex_lock(&gc2145->lock);if (gc2145->format.width == 1600)goto unlock;fps = DIV_ROUND_CLOSEST(fi->interval.denominator,fi->interval.numerator);mf = gc2145->format;__gc2145_try_frame_size_fps(gc2145, &mf, &size, fps);if (gc2145->frame_size != size) {dev_info(&client->dev, "%s match wxh@FPS is %dx%d@%d\n",__func__, size->width, size->height,DIV_ROUND_CLOSEST(size->max_fps.denominator,size->max_fps.numerator));ret |= gc2145_write_array(client, size->regs);if (ret)goto unlock;gc2145->frame_size = size;gc2145->fps = fps;}
unlock:mutex_unlock(&gc2145->lock);return ret;
}static void gc2145_get_module_inf(struct gc2145 *gc2145,struct rkmodule_inf *inf)
{memset(inf, 0, sizeof(*inf));strlcpy(inf->base.sensor, DRIVER_NAME, sizeof(inf->base.sensor));strlcpy(inf->base.module, gc2145->module_name,sizeof(inf->base.module));strlcpy(inf->base.lens, gc2145->len_name, sizeof(inf->base.lens));
}static long gc2145_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{struct gc2145 *gc2145 = to_gc2145(sd);long ret = 0;u32 stream = 0;switch (cmd) {case RKMODULE_GET_MODULE_INFO:gc2145_get_module_inf(gc2145, (struct rkmodule_inf *)arg);break;case RKMODULE_SET_QUICK_STREAM:stream = *((u32 *)arg);gc2145_set_streaming(gc2145, !!stream);break;default:ret = -ENOIOCTLCMD;break;}return ret;
}#ifdef CONFIG_COMPAT
static long gc2145_compat_ioctl32(struct v4l2_subdev *sd,unsigned int cmd, unsigned long arg)
{void __user *up = compat_ptr(arg);struct rkmodule_inf *inf;struct rkmodule_awb_cfg *cfg;long ret;u32 stream = 0;switch (cmd) {case RKMODULE_GET_MODULE_INFO:inf = kzalloc(sizeof(*inf), GFP_KERNEL);if (!inf) {ret = -ENOMEM;return ret;}ret = gc2145_ioctl(sd, cmd, inf);if (!ret) {ret = copy_to_user(up, inf, sizeof(*inf));if (ret)ret = -EFAULT;}kfree(inf);break;case RKMODULE_AWB_CFG:cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);if (!cfg) {ret = -ENOMEM;return ret;}ret = copy_from_user(cfg, up, sizeof(*cfg));if (!ret)ret = gc2145_ioctl(sd, cmd, cfg);elseret = -EFAULT;kfree(cfg);break;case RKMODULE_SET_QUICK_STREAM:ret = copy_from_user(&stream, up, sizeof(u32));if (!ret)ret = gc2145_ioctl(sd, cmd, &stream);elseret = -EFAULT;break;default:ret = -ENOIOCTLCMD;break;}return ret;
}
#endifstatic int gc2145_init(struct v4l2_subdev *sd, u32 val)
{int ret;struct gc2145 *gc2145 = to_gc2145(sd);struct i2c_client *client = gc2145->client;dev_info(&client->dev, "%s(%d)\n", __func__, __LINE__);if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY)ret = gc2145_write_array(client, gc2145_mipi_init_regs);elseret = gc2145_write_array(client, gc2145_dvp_init_regs);return ret;
}static int gc2145_power(struct v4l2_subdev *sd, int on)
{int ret;struct gc2145 *gc2145 = to_gc2145(sd);struct i2c_client *client = gc2145->client;dev_info(&client->dev, "%s(%d) on(%d)\n", __func__, __LINE__, on);if (on) {if (!IS_ERR(gc2145->pwdn_gpio)) {gpiod_set_value_cansleep(gc2145->pwdn_gpio, 0);usleep_range(2000, 5000);}ret = gc2145_init(sd, 0);usleep_range(10000, 20000);if (ret)dev_err(&client->dev, "init error\n");gc2145->power_on = true;} else {if (!IS_ERR(gc2145->pwdn_gpio)) {gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);usleep_range(2000, 5000);}gc2145->power_on = false;}return 0;
}static int gc2145_enum_frame_interval(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_interval_enum *fie)
{struct gc2145 *gc2145 = to_gc2145(sd);if (fie->index >= gc2145->cfg_num)return -EINVAL;fie->code = MEDIA_BUS_FMT_UYVY8_2X8;fie->width = gc2145->framesize_cfg[fie->index].width;fie->height = gc2145->framesize_cfg[fie->index].height;fie->interval = gc2145->framesize_cfg[fie->index].max_fps;return 0;
}static const struct v4l2_subdev_core_ops gc2145_subdev_core_ops = {.log_status = v4l2_ctrl_subdev_log_status,.subscribe_event = v4l2_ctrl_subdev_subscribe_event,.unsubscribe_event = v4l2_event_subdev_unsubscribe,.ioctl = gc2145_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl32 = gc2145_compat_ioctl32,
#endif.s_power = gc2145_power,
};static const struct v4l2_subdev_video_ops gc2145_subdev_video_ops = {.s_stream = gc2145_s_stream,.g_frame_interval = gc2145_g_frame_interval,.s_frame_interval = gc2145_s_frame_interval,
};static const struct v4l2_subdev_pad_ops gc2145_subdev_pad_ops = {.enum_mbus_code = gc2145_enum_mbus_code,.enum_frame_size = gc2145_enum_frame_sizes,.enum_frame_interval = gc2145_enum_frame_interval,.get_fmt = gc2145_get_fmt,.set_fmt = gc2145_set_fmt,.get_mbus_config = gc2145_g_mbus_config,
};#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
static const struct v4l2_subdev_ops gc2145_subdev_ops = {.core  = &gc2145_subdev_core_ops,.video = &gc2145_subdev_video_ops,.pad   = &gc2145_subdev_pad_ops,
};static const struct v4l2_subdev_internal_ops gc2145_subdev_internal_ops = {.open = gc2145_open,
};
#endifstatic int gc2145_detect(struct gc2145 *gc2145)
{struct i2c_client *client = gc2145->client;u8 pid, ver;int ret;dev_dbg(&client->dev, "%s:\n", __func__);/* Check sensor revision */ret = gc2145_read(client, REG_SC_CHIP_ID_H, &pid);if (!ret)ret = gc2145_read(client, REG_SC_CHIP_ID_L, &ver);if (!ret) {unsigned short id;id = SENSOR_ID(pid, ver);if (id != GC2145_ID) {ret = -1;dev_err(&client->dev,"Sensor detection failed (%04X, %d)\n",id, ret);} else {dev_info(&client->dev, "Found GC%04X sensor\n", id);if (!IS_ERR(gc2145->pwdn_gpio))gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);}}return ret;
}static int __gc2145_power_on(struct gc2145 *gc2145)
{int ret;struct device *dev = &gc2145->client->dev;dev_info(dev, "%s(%d)\n", __func__, __LINE__);if (!IS_ERR(gc2145->power_gpio)) {gpiod_set_value_cansleep(gc2145->power_gpio, 1);usleep_range(2000, 5000);}if (!IS_ERR(gc2145->reset_gpio)) {gpiod_set_value_cansleep(gc2145->reset_gpio, 0);usleep_range(2000, 5000);gpiod_set_value_cansleep(gc2145->reset_gpio, 1);usleep_range(2000, 5000);}if (!IS_ERR(gc2145->xvclk)) {ret = clk_set_rate(gc2145->xvclk, 24000000);if (ret < 0)dev_info(dev, "Failed to set xvclk rate (24MHz)\n");}if (!IS_ERR(gc2145->pwdn_gpio)) {gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);usleep_range(2000, 5000);}if (!IS_ERR(gc2145->supplies)) {ret = regulator_bulk_enable(GC2145_NUM_SUPPLIES,gc2145->supplies);if (ret < 0)dev_info(dev, "Failed to enable regulators\n");usleep_range(20000, 50000);}if (!IS_ERR(gc2145->pwdn_gpio)) {gpiod_set_value_cansleep(gc2145->pwdn_gpio, 0);usleep_range(2000, 5000);}if (!IS_ERR(gc2145->reset_gpio)) {gpiod_set_value_cansleep(gc2145->reset_gpio, 0);usleep_range(2000, 5000);}if (!IS_ERR(gc2145->xvclk)) {ret = clk_prepare_enable(gc2145->xvclk);if (ret < 0)dev_info(dev, "Failed to enable xvclk\n");}usleep_range(7000, 10000);gc2145->power_on = true;return 0;
}static void __gc2145_power_off(struct gc2145 *gc2145)
{dev_info(&gc2145->client->dev, "%s(%d)\n", __func__, __LINE__);if (!IS_ERR(gc2145->xvclk))clk_disable_unprepare(gc2145->xvclk);if (!IS_ERR(gc2145->supplies))regulator_bulk_disable(GC2145_NUM_SUPPLIES, gc2145->supplies);if (!IS_ERR(gc2145->pwdn_gpio))gpiod_set_value_cansleep(gc2145->pwdn_gpio, 1);if (!IS_ERR(gc2145->reset_gpio))gpiod_set_value_cansleep(gc2145->reset_gpio, 0);if (!IS_ERR(gc2145->power_gpio))gpiod_set_value_cansleep(gc2145->power_gpio, 0);gc2145->power_on = false;
}static int gc2145_configure_regulators(struct gc2145 *gc2145)
{unsigned int i;for (i = 0; i < GC2145_NUM_SUPPLIES; i++)gc2145->supplies[i].supply = gc2145_supply_names[i];return devm_regulator_bulk_get(&gc2145->client->dev,GC2145_NUM_SUPPLIES,gc2145->supplies);
}static int gc2145_parse_of(struct gc2145 *gc2145)
{struct device *dev = &gc2145->client->dev;struct device_node *endpoint;int ret;endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);if (!endpoint) {dev_err(dev, "Failed to get endpoint\n");return -EINVAL;}ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),&gc2145->bus_cfg);if (ret) {dev_err(dev, "Failed to parse endpoint\n");of_node_put(endpoint);return ret;}if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) {gc2145->framesize_cfg = gc2145_mipi_framesizes;gc2145->cfg_num = ARRAY_SIZE(gc2145_mipi_framesizes);} else {gc2145->framesize_cfg = gc2145_dvp_framesizes;gc2145->cfg_num = ARRAY_SIZE(gc2145_dvp_framesizes);}gc2145->power_gpio = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);if (IS_ERR(gc2145->power_gpio))dev_info(dev, "Failed to get power-gpios, maybe no use\n");gc2145->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);if (IS_ERR(gc2145->pwdn_gpio))dev_info(dev, "Failed to get pwdn-gpios, maybe no use\n");gc2145->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);if (IS_ERR(gc2145->reset_gpio))dev_info(dev, "Failed to get reset-gpios, maybe no use\n");ret = gc2145_configure_regulators(gc2145);if (ret)dev_info(dev, "Failed to get power regulators\n");return ret;
}static int gc2145_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct device *dev = &client->dev;struct device_node *node = dev->of_node;struct v4l2_subdev *sd;struct gc2145 *gc2145;char facing[2];int ret;dev_info(dev, "driver version: %02x.%02x.%02x",DRIVER_VERSION >> 16,(DRIVER_VERSION & 0xff00) >> 8,DRIVER_VERSION & 0x00ff);gc2145 = devm_kzalloc(&client->dev, sizeof(*gc2145), GFP_KERNEL);if (!gc2145)return -ENOMEM;ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,&gc2145->module_index);ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,&gc2145->module_facing);ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,&gc2145->module_name);ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,&gc2145->len_name);if (ret) {dev_err(dev, "could not get module information!\n");return -EINVAL;}gc2145->client = client;gc2145->xvclk = devm_clk_get(&client->dev, "xvclk");if (IS_ERR(gc2145->xvclk)) {dev_err(&client->dev, "Failed to get xvclk\n");return -EINVAL;}ret = gc2145_parse_of(gc2145);if (ret != 0)return -EINVAL;v4l2_ctrl_handler_init(&gc2145->ctrls, 3);gc2145->link_frequency =v4l2_ctrl_new_std(&gc2145->ctrls, &gc2145_ctrl_ops,V4L2_CID_PIXEL_RATE, 0,GC2145_PIXEL_RATE, 1,GC2145_PIXEL_RATE);v4l2_ctrl_new_int_menu(&gc2145->ctrls, NULL, V4L2_CID_LINK_FREQ,0, 0, link_freq_menu_items);v4l2_ctrl_new_std_menu_items(&gc2145->ctrls, &gc2145_ctrl_ops,V4L2_CID_TEST_PATTERN,ARRAY_SIZE(gc2145_test_pattern_menu) - 1,0, 0, gc2145_test_pattern_menu);gc2145->sd.ctrl_handler = &gc2145->ctrls;if (gc2145->ctrls.error) {dev_err(&client->dev, "%s: control initialization error %d\n",__func__, gc2145->ctrls.error);return  gc2145->ctrls.error;}sd = &gc2145->sd;client->flags |= I2C_CLIENT_SCCB;
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_APIv4l2_i2c_subdev_init(sd, client, &gc2145_subdev_ops);sd->internal_ops = &gc2145_subdev_internal_ops;sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |V4L2_SUBDEV_FL_HAS_EVENTS;
#endif#if defined(CONFIG_MEDIA_CONTROLLER)gc2145->pad.flags = MEDIA_PAD_FL_SOURCE;sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;ret = media_entity_pads_init(&sd->entity, 1, &gc2145->pad);if (ret < 0) {v4l2_ctrl_handler_free(&gc2145->ctrls);return ret;}
#endifmutex_init(&gc2145->lock);gc2145_get_default_format(gc2145, &gc2145->format);gc2145->frame_size = &gc2145->framesize_cfg[0];gc2145->format.width = gc2145->framesize_cfg[0].width;gc2145->format.height = gc2145->framesize_cfg[0].height;gc2145->fps = DIV_ROUND_CLOSEST(gc2145->framesize_cfg[0].max_fps.denominator,gc2145->framesize_cfg[0].max_fps.numerator);__gc2145_power_on(gc2145);gc2145->xvclk_frequency = clk_get_rate(gc2145->xvclk);if (gc2145->xvclk_frequency < 6000000 ||gc2145->xvclk_frequency > 27000000)goto error;ret = gc2145_detect(gc2145);if (ret < 0) {dev_info(&client->dev, "Check id  failed:\n""check following information:\n""Power/PowerDown/Reset/Mclk/I2cBus !!\n");goto error;}memset(facing, 0, sizeof(facing));if (strcmp(gc2145->module_facing, "back") == 0)facing[0] = 'b';elsefacing[0] = 'f';snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",gc2145->module_index, facing,DRIVER_NAME, dev_name(sd->dev));ret = v4l2_async_register_subdev_sensor_common(sd);if (ret)goto error;dev_info(&client->dev, "%s sensor driver registered !!\n", sd->name);gc2145->power_on = false;return 0;error:v4l2_ctrl_handler_free(&gc2145->ctrls);
#if defined(CONFIG_MEDIA_CONTROLLER)media_entity_cleanup(&sd->entity);
#endifmutex_destroy(&gc2145->lock);__gc2145_power_off(gc2145);return ret;
}static int gc2145_remove(struct i2c_client *client)
{struct v4l2_subdev *sd = i2c_get_clientdata(client);struct gc2145 *gc2145 = to_gc2145(sd);v4l2_ctrl_handler_free(&gc2145->ctrls);v4l2_async_unregister_subdev(sd);
#if defined(CONFIG_MEDIA_CONTROLLER)media_entity_cleanup(&sd->entity);
#endifmutex_destroy(&gc2145->lock);__gc2145_power_off(gc2145);return 0;
}static const struct i2c_device_id gc2145_id[] = {{ "gc2145", 0 },{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(i2c, gc2145_id);#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id gc2145_of_match[] = {{ .compatible = "galaxycore,gc2145", },{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, gc2145_of_match);
#endifstatic struct i2c_driver gc2145_i2c_driver = {.driver = {.name	= DRIVER_NAME,.of_match_table = of_match_ptr(gc2145_of_match),},.probe		= gc2145_probe,.remove		= gc2145_remove,.id_table	= gc2145_id,
};static int __init sensor_mod_init(void)
{return i2c_add_driver(&gc2145_i2c_driver);
}static void __exit sensor_mod_exit(void)
{i2c_del_driver(&gc2145_i2c_driver);
}device_initcall_sync(sensor_mod_init);
module_exit(sensor_mod_exit);MODULE_AUTHOR("Benoit Parrot <bparrot@ti.com>");
MODULE_DESCRIPTION("GC2145 CMOS Image Sensor driver");
MODULE_LICENSE("GPL v2");

可以看出该驱动结构就是v4l2的方式。

sensor_register这个是camera的寄存器设置,厂商调好的,一般不动。根据相应的选择配置就行。比如上面使用c2145->framesize_cfg[0]--------gc2145_dvp_framesizes[0]----gc2145_dvp_svga_20fps

1.BT601配置要点

  • hsync-active/vsync-active必须配置,用于v4l2框架异步注册识别BT601接口,若不配置会识别为BT656接口;
  • pclk-sample/bus-width可选;
  • 必须在sensor驱动的g_mbus_config接口中,通过flag指明当前sensor的hsync-acitve/vsyncactive/pclk-ative的有效极性,否则会导致无法收到数据;
  • pinctrl需要引用对,以对bt601相关gpio做相应iomux,否则会导致无法收到数据;

g_mbus_config接口示例代码如下:
 

static int gc2145_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,struct v4l2_mbus_config *config)
{struct gc2145 *gc2145 = to_gc2145(sd);if (gc2145->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) {config->type = V4L2_MBUS_CSI2_DPHY;config->flags = V4L2_MBUS_CSI2_1_LANE |V4L2_MBUS_CSI2_CHANNEL_0 |V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;} else {config->type = V4L2_MBUS_PARALLEL;config->flags = V4L2_MBUS_HSYNC_ACTIVE_HIGH |V4L2_MBUS_VSYNC_ACTIVE_LOW |V4L2_MBUS_PCLK_SAMPLE_RISING;}return 0;
}

2.BT656/BT1120配置要点

  • hsync-active/vsync-active不要配置,否则v4l2框架异步注册时会识别为BT601;
  • pclk-sample/bus-width可选;
  • 必须在sensor驱动的g_mbus_config接口中,通过flag变量指明当前sensor的pclk-ative的有效极性,否则会导致无法收到数据;
  • 必须实现v4l2_subdev_video_ops中的querystd接口,指明当前接口为ATSC接口,否则会导致无法收到数据;
  • 必须实现RKMODULE_GET_BT656_MBUS_INFO,BT656/BT1120都是调用这个ioctl,接口兼容,实现参考drivers/media/i2c/nvp6158_drv/nvp6158_v4l2.c
  • pinctrl需要引用对,以对bt656/bt1120相关gpio做相应iomux,否则会导致无法收到数据。

g_mbus_config接口示例代码如下:
 

static int avafpga_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *config)
{
config->type = V4L2_MBUS_BT656;
config->flags = V4L2_MBUS_PCLK_SAMPLE_RISING;
return 0;
}

querystd接口示例如下:
 

static int avafpga_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{*std = V4L2_STD_ATSC;return 0;
}

BT601和BT656/BT1120的区别就是前者有行长同步信号,后者没有, 行场同步信号嵌入在数据流中。

指定数据的排列,这里用MEDIA_BUS_FMT_UYVY8_2X8

static const struct gc2145_pixfmt gc2145_formats[] = {{.code = MEDIA_BUS_FMT_UYVY8_2X8,}
};

其他的基本和v4l2框架一致,就不细说了。

相关文章:

瑞芯微RK3588驱动设计之DVP并口摄像头2

dts配置看瑞芯微RK3588驱动配置之DVP并口摄像头1_rockchip 调试dvp设备 直接显示摄像头数据-CSDN博客 这里看看驱动的具体实现&#xff0c;以gc2145为例。 gc2145的驱动源码如下&#xff1a; // SPDX-License-Identifier: GPL-2.0 /** GC2145 CMOS Image Sensor driver*** C…...

安卓手机APP开发__支持64位的架构

安卓手机APP开发__支持64位的架构 目录 概述 读取你的APP 快速的状态检查 你的APP使用了原生的代码吗&#xff1f; 你的APP包含了64位的代码库吗&#xff1f; 确保在这些目录中有原生的代码库. 使用APK分析器查看原生的代码库 通过解压缩APK查看原生的代码库 用安卓工…...

Foxmail使用经验总结

目录 1.概述 2.版本历史 3.使用方法 3.1.安装和设置账户 3.2.收取和阅读邮件 ​​​​​​​3.3.发送邮件 ​​​​​​​3.4.管理联系人 ​​​​​​​3.5.日程安排和任务管理 ​​​​​​​3.6.定制设置和插件 ​​​​​​​3.7.跨平台同步 4.小结 1.概述 Fox…...

信息系统项目管理师0601:项目立项管理 — 考点总结(可直接理解记忆)

点击查看专栏目录 项目立项管理 — 考点总结(可直接理解记忆) 1.项目建议书(又称立项申请)是项目建设单位向上级主管部门提交项目申请时所必须的文件,是对拟建项目提出的框架性的总体设想。在项目建议书批准后,方可开展对外工作(掌握)。 2.项目建议书应该包括的核心内…...

实验三:机器学习1.0

要求&#xff1a; 针对实验1和实验2构建的数据集信息分析 设计实现通过数据简介进行大类分类的程序 代码实现&#xff1a; 训练集数据获取&#xff1a; read_data.py import json import pickledef read_intro():data []trypathr"E:\Procedure\Python\Experiment\f…...

Vue 3 + Vite项目实战:常见问题与解决方案全解析

文章目录 一、项目使用本地图片打包后不显示1、在html中时候&#xff0c;本地运行和打包后线上运行都ok。2、用动态数据&#xff0c;本地运行ok&#xff0c;打包后线上运行不显示3、适用于处理单个链接的资源文件4、用动态数据且本地和线上访问都可显示 二、使用插件vite-plugi…...

飞天使-k8s知识点31-rancher的正确打开方式

文章目录 安装之前优化一下内核参数以及系统内核版本 rancher安装主要是使用以下命令nginx的配置为解决办法 安装之前优化一下内核参数以及系统内核版本 内核版本 4.17 cat > /etc/modules-load.d/iptables.conf <<EOF ip_tables iptable_filter EOF 然后重启服务器…...

Vue.component v2v3注册(局部与全局)组件使用详解

在Vue中&#xff0c;可以通过两种方式注册组件&#xff1a;局部注册和全局注册。 局部注册是在父组件中通过import和components选项注册的组件&#xff0c;仅在当前父组件及其子组件中可用。 // 父组件中import ChildComponent from ./ChildComponent.vue;export default {co…...

HNU-算法设计与分析-作业5

第五次作业【回溯算法】 文章目录 第五次作业【回溯算法】<1> 算法分析题5-3 回溯法重写0-1背包<2> 算法分析题5-5 旅行商问题&#xff08;剪枝&#xff09;<3> 算法实现题5-2 最小长度电路板排列问题<4> 算法实现题5-7 n色方柱问题<5> 算法实现…...

基础之音视频2

01 前言 02 mp 03 mp实例 简易音乐播放器 04 音频 sound-pool 1.作用 播放多个音频&#xff0c;短促音频 2.过程 加载load- 3.示例 模拟手机选铃声 步骤&#xff1a; 创建SoundPool对象&#xff0c;设置相关属性 音频流存入hashmap 播放音频 05 videoview 3gp 体积小 mp4 …...

两小时看完花书(深度学习入门篇)

1.深度学习花书前言 机器学习早期的时候十分依赖于已有的知识库和人为的逻辑规则&#xff0c;需要人们花大量的时间去制定合理的逻辑判定&#xff0c;可以说是有多少人工&#xff0c;就有多少智能。后来逐渐发展出一些简单的机器学习方法例如logistic regression、naive bayes等…...

21【Aseprite 作图】画白菜

1 对着参考图画轮廓 2 缩小尺寸 变成这样 3 本来是红色的描边&#xff0c;可以通过油漆桶工具&#xff08;取消 “连续”&#xff09;&#xff0c;就把红色的轮廓线&#xff0c;变成黑色的 同时用吸管工具&#xff0c;吸取绿色和白色&#xff0c;用油漆桶填充颜色 4 加上阴影…...

2024.05.15 [AI开发配环境]个人使用最新版远程服务器配环境大纲:docker、云盘、ssh、conda等

不包括在宿主机安装docker。 docker 找到心仪的镜像&#xff0c;比如从网上pull&#xff1a;https://hub.docker.com/r/pytorch/pytorch/tags?page&page_size&ordering&name2.0.1 docker pull pytorch/pytorch:2.0.1-cuda11.7-cudnn8-devel# 新建容器 docker r…...

opencv 轮廓区域检测

直线检测 void LineDetect(const cv::Mat &binaryImage) {cv::Mat xImage,yImage,binaryImage1,binaryImage2;// 形态学变化&#xff0c;闭操作 先膨胀&#xff0c;再腐蚀 可以填充小洞&#xff0c;填充小的噪点cv::Mat element cv::getStructuringElement(cv::MORPH_RE…...

2024-5-16

今日安排&#xff1a; 完结 nf_tables 模块的基本学习&#xff0c;然后开始审计源码mount 的使用&#xff0c;学习 namespace (昨昨昨昨天残留的任务)&#xff08;&#xff1a;看我能搁到什么时候静不下心学习新知识就做 CTF 题目&#x1f991;&#x1f991;&#x1f991; 今…...

IT行业的现状与未来:技术创新引领时代变革

随着技术的不断进步&#xff0c;IT行业已成为推动全球经济和社会发展的关键力量。从云计算、大数据、人工智能到物联网、5G通信和区块链&#xff0c;这些技术正在重塑我们的生活和工作方式。本文将探讨当前IT行业的现状及未来发展趋势&#xff0c;并邀请行业领袖、技术专家和创…...

Redis分布式锁【简单版】

文章目录 概要例子1【SETNX EXPIRE】例子2【 Redisson 】 概要 redis分布式锁六种方案 SETNX EXPIRE 方案&#xff1a; 描述&#xff1a;使用Redis的SETNX命令来尝试设置一个键值对&#xff0c;如果该键不存在&#xff0c;则设置成功并设置过期时间&#xff0c;实现锁的功能…...

18.Blender 渲染工程、打光方法及HDR贴图导入

HDR环境 如何导入Blender的HDR环境图 找到材质球信息 在右上角&#xff0c;点击箭头&#xff0c;展开详细部分 点击材质球&#xff0c;会出现下面一列材质球&#xff0c;将鼠标拖到第二个材质球&#xff0c;会显示信息 courtyard.exr 右上角打开已渲染模式 左边这里选择世界…...

VBA在Excel中部首组查字法的应用

VBA在Excel中部首组查字法的应用 文章目录 前言一、网站截图二、操作思路三、代码1.创建数据发送及返回方法2.创建截取字符串中的数值的方法3.获取部首对应的编码4.获取特定部首的汉字运行效果截图前言 使用汉语字典查生字、生词,多用拼音查字法和部首查字法。以前都是用纸质…...

ASP.NET MVC 4升级迁移到ASP.NET MVC 5

背景&#xff1a;今天针对一个老项目进行框架升级&#xff0c;老项目使用的是MVC 4&#xff0c;现在要升级到MVC5。 备份项目.NET升级4.5以上版本通过Nuget&#xff0c;更新或者直接安装包 包名oldVersionnewVersion说明Microsoft.AspNet.Mvc4.0.05.x.xMicrosoft.AspNet.Razo…...

AIGC时代已至,你准备好抓住机遇了吗?

一、行业前景 AIGC&#xff0c;即人工智能生成内容&#xff0c;是近年来人工智能领域中发展迅猛的一个分支。随着大数据、云计算、机器学习等技术的不断进步&#xff0c;AIGC已经取得了显著的成果&#xff0c;并且在广告、游戏、自媒体、教育、电商等多个领域实现了广泛应用。…...

2024CCPC郑州邀请赛暨河南省赛

比赛记录&#xff1a;看群里大家嘎嘎拿牌&#xff0c;自己个人来solo了一下&#xff0c;发现简单到中等题很多&#xff0c;写了两小时出了7题&#xff0c;但是写的比较慢&#xff0c;对难题把握还是不准确 补题 &#xff1a; A题确实巧妙充分利用题目的数据范围来思考问题&…...

Spring 各版本发布时间与区别

版本版本特性Spring Framework 1.01. 所有代码都在一个项目中 2. 支持核心功能IoC、AOP 3. 内置支持Hibernate、iBatis等第三方框架 4. 对第三方技术简单封装。如&#xff1a;JDBC、Mail、事务等 5. 只支持XML配置方式。6.主要通过 XML 配置文件来管理对象和依赖关系&#xff0…...

前端模块导入导出方式

不同的导出方式和相应的导入方式&#xff0c;可以提炼成 3 种类型&#xff1a;name、default 和 list。 以下是使用示例&#xff1a; // Name Export | Name Import // 一个“命名”的导出 export const name value import { name } from ...❌ 错误示例&#xff1a; export…...

docker01-简介和概述

什么是docker&#xff1f; 我们现在开发项目是在windows操作系统使用idea开发&#xff0c;本地windows操作系统上有我们项目所需的jdk&#xff0c;mysql&#xff0c;redis&#xff0c;tomcat等环境&#xff0c;如果我们想打包我们的项目到一个别的服务器上&#xff0c;在别的服…...

java数据结构与算法(对称二叉树)

前言 为什么学习数据结构和算法&#xff1f; 1.直面大厂的高薪。 2.学习编程的语言。 3.输出优雅的代码和高性能的程序。 每日练习2题&#xff0c;希望大家都能收获高薪offer&#xff0c;实现自由跳槽。 实现原理 主要判断二叉树的以中间线为轴&#xff0c;两边的对称的…...

[原创](Modern C++)现代C++的std::function, 强大的多态函数包装器(包含std::mem_fn使用方式).

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…...

解决间歇性 SSLPeerUnverifiedException 问题

问题背景 您在使用 SonarQube 与 GitHub Enterprise 进行拉取请求装饰时,遇到了间歇性的 javax.net.ssl.SSLPeerUnverifiedException 异常。具体错误信息如下: txt javax.net.ssl.SSLPeerUnverifiedException: Hostname XXXXXXX not verified (no certificates)at okhttp3…...

Linux程序开发(一):Linux基础入门安装和实操手册

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…...

Java | Leetcode Java题解之第92题反转链表II

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode reverseBetween(ListNode head, int left, int right) {// 设置 dummyNode 是这一类问题的一般做法ListNode dummyNode new ListNode(-1);dummyNode.next head;ListNode pre dummyNode;for (int i 0; …...