当前位置: 首页 > 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…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...