405 lines
11 KiB
C
405 lines
11 KiB
C
#include "asm/iic.h"
|
||
#include "asm/isp_dev.h"
|
||
#include "gpio.h"
|
||
#include "generic/jiffies.h"
|
||
#include "device/iic.h"
|
||
#include "device/device.h"
|
||
#include "app_config.h"
|
||
|
||
#ifdef CONFIG_VIDEO_ENABLE
|
||
|
||
#define GC6133_DEVP_MAX_W 244
|
||
#define GC6133_DEVP_MAX_H 328
|
||
|
||
#if (CONFIG_VIDEO_IMAGE_W > GC6133_DEVP_MAX_W)
|
||
#define GC6133_DEVP_INPUT_W GC6133_DEVP_MAX_W
|
||
#define GC6133_DEVP_INPUT_H GC6133_DEVP_MAX_H
|
||
#else
|
||
#define GC6133_DEVP_INPUT_W CONFIG_VIDEO_IMAGE_W
|
||
#define GC6133_DEVP_INPUT_H CONFIG_VIDEO_IMAGE_H
|
||
#endif
|
||
|
||
#ifdef CONFIG_VIDEO1_ENABLE /*开启video1则使用video1分辨率*/
|
||
#undef GC6133_DEVP_INPUT_W
|
||
#undef GC6133_DEVP_INPUT_H
|
||
#ifdef CONFIG_VIDEO1_IMAGE_W
|
||
#define GC6133_DEVP_INPUT_W CONFIG_VIDEO1_IMAGE_W
|
||
#define GC6133_DEVP_INPUT_H CONFIG_VIDEO1_IMAGE_H
|
||
#else
|
||
#define GC6133_DEVP_INPUT_W 240
|
||
#define GC6133_DEVP_INPUT_H 320
|
||
#endif
|
||
#endif
|
||
|
||
#define CONFIG_INPUT_FPS 12
|
||
|
||
static void *iic = NULL;
|
||
static u8 GC6133_reset_io[2] = {-1, -1};
|
||
static u8 GC6133_power_io[2] = {-1, -1};
|
||
|
||
#define GC6133_WRCMD 0x80
|
||
#define GC6133_RDCMD 0x81
|
||
|
||
#define GC6133_1WIRE_MODE 1
|
||
|
||
#define DELAY_TIME 10
|
||
static s32 GC6133_set_output_size(u16 *width, u16 *height, u8 *freq);
|
||
|
||
struct reginfo {
|
||
u8 reg;
|
||
u8 val;
|
||
};
|
||
static const struct reginfo sensor_init_data[] = {
|
||
/////////////////////////////////////////////////////
|
||
////////////////////// SYS //////////////////////
|
||
/////////////////////////////////////////////////////
|
||
{0xfe, 0xa0},
|
||
{0xfe, 0xa0},
|
||
{0xfe, 0xa0},
|
||
{0xf1, 0x03}, //output enable
|
||
{0xf6, 0x00},
|
||
{0xfa, 0x10},
|
||
{0xfc, 0x12}, //clock enable
|
||
{0xfe, 0x00}, //Page select
|
||
////////////////////////////////////////////////////
|
||
/////////////// ANALOG & CISCTL ////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x0d, 0x30},
|
||
{0x12, 0xc8},
|
||
{0x14, 0x54}, //dark CFA
|
||
{0x15, 0x32}, //1:sdark 0:ndark
|
||
{0x16, 0x04},
|
||
{0x17, 0x19},
|
||
{0x1d, 0xb9},
|
||
{0x7a, 0x00},
|
||
{0x7b, 0x14},
|
||
{0x7d, 0x36},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// ISP //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x20, 0x7e},
|
||
{0x22, 0xf0},
|
||
{0x24, 0x54}, //output_format
|
||
{0x26, 0x87}, //[5]Y_switch [4]UV_switch [2]skin_en
|
||
////////////////////////////////////////////////////
|
||
///////////////////// BLK //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x2a, 0x2f},
|
||
{0x37, 0x46}, //[4:0]blk_select_row
|
||
|
||
{0x39, ((GC6133_DEVP_MAX_H - GC6133_DEVP_INPUT_H) / 2 - 2) & 0xff},
|
||
{0x3a, 0x80 | ((GC6133_DEVP_MAX_W - GC6133_DEVP_INPUT_W) / 2 - 2) & 0xff},
|
||
|
||
{0x3b, (GC6133_DEVP_INPUT_H >> 8) & 0xff},
|
||
{0x3c, GC6133_DEVP_INPUT_H & 0xff},
|
||
{0x3e, GC6133_DEVP_INPUT_W & 0xff},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// GAIN /////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x3f, 0x10}, //global gain
|
||
////////////////////////////////////////////////////
|
||
///////////////////// DNDD /////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x52, 0x4f},
|
||
{0x53, 0x81},
|
||
{0x54, 0x43},
|
||
{0x56, 0x78},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// ASDE /////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x5b, 0x60}, //dd&ee th
|
||
{0x5c, 0x80}, //60/OT_th
|
||
////////////////////////////////////////////////////
|
||
//////////////////// INTPEE ////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x63, 0x14}, //edge effect
|
||
////////////////////////////////////////////////////
|
||
///////////////////// CC ///////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x65, 0x13}, //Y
|
||
{0x66, 0x26},
|
||
{0x67, 0x07},
|
||
{0x68, 0xf5}, //Cb
|
||
{0x69, 0xea},
|
||
{0x6a, 0x21},
|
||
{0x6b, 0x21}, //Cr
|
||
{0x6c, 0xe4},
|
||
{0x6d, 0xfb},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// YCP //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x81, 0x30}, //cb
|
||
{0x82, 0x30}, //cr
|
||
{0x83, 0x48}, //luma contrast
|
||
{0x8d, 0x78}, //edge dec sa
|
||
{0x8e, 0x25}, //autogray
|
||
////////////////////////////////////////////////////
|
||
///////////////////// AEC //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x90, 0x3c},
|
||
{0x92, 0x40}, //target
|
||
{0x9d, 0x65}, //flicker step
|
||
{0x9e, 0x63}, //[7:4]margin
|
||
{0x9f, 0xf2}, //exp_level 3f2
|
||
{0xa3, 0x30}, //pregain
|
||
{0xa4, 0x01},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// AWB //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0xb1, 0x1e}, //Y_to_C_diff
|
||
{0xb3, 0x20}, //C_max
|
||
{0xbd, 0x70}, //R_limit
|
||
{0xbe, 0x58}, //G_limit
|
||
{0xbf, 0x80}, //B_limit
|
||
////////////////////////////////////////////////////
|
||
/////////////////// Banding ////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0x03, 0x01},
|
||
{0x04, 0x2f},
|
||
{0x01, 0x02}, //hb
|
||
{0x02, 0x02}, //vb
|
||
{0x0f, 0x01},
|
||
////////////////////////////////////////////////////
|
||
///////////////////// SPI //////////////////////
|
||
////////////////////////////////////////////////////
|
||
{0xfe, 0x02},
|
||
{0x01, 0x00}, //spi disable
|
||
{0x02, 0x80}, //ddr_mode
|
||
{0x03, 0x20},
|
||
{0x04, 0x30}, //[5]width x2 [3:0]frequency divider
|
||
{0x09, 0x08},
|
||
{0x0a, 0x00}, //yuv:00 raw8:02
|
||
{0x13, 0x10}, //fifo_prog_full_level
|
||
|
||
{0x20, 0xab},
|
||
{0x21, 0x80},
|
||
{0x22, 0x9d},
|
||
{0x23, 0xb6},
|
||
{0x24, 0x01}, //[1]sck_always [0]BT656
|
||
{0x25, 0xff},
|
||
{0x26, 0x00},
|
||
{0x27, 0x00},
|
||
{0x28, 0x03}, //clock_div_spi
|
||
{0x01, 0x01}, //spi enable
|
||
{0xfe, 0x00},
|
||
};
|
||
|
||
static unsigned char GC6133_wrReg(unsigned char regID, unsigned char regDat)
|
||
{
|
||
u8 ret = 1;
|
||
dev_ioctl(iic, IIC_IOCTL_START, 0);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_WRCMD)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX, regID)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_STOP_BIT, regDat)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
exit:
|
||
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
|
||
return ret;
|
||
}
|
||
|
||
static unsigned char GC6133_rdReg(unsigned char regID, unsigned char *regDat)
|
||
{
|
||
u8 ret = 1;
|
||
dev_ioctl(iic, IIC_IOCTL_START, 0);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_WRCMD)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_STOP_BIT, regID)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
if (dev_ioctl(iic, IIC_IOCTL_TX_WITH_START_BIT, GC6133_RDCMD)) {
|
||
ret = 0;
|
||
printf("iic write err!!! line : %d \n", __LINE__);
|
||
goto exit;
|
||
}
|
||
delay(DELAY_TIME);
|
||
dev_ioctl(iic, IIC_IOCTL_RX_WITH_STOP_BIT, (u32)regDat);
|
||
|
||
exit:
|
||
dev_ioctl(iic, IIC_IOCTL_STOP, 0);
|
||
return ret;
|
||
}
|
||
|
||
static void GC6133_config_SENSOR(u16 *width, u16 *height, u8 *format, u8 *frame_freq)
|
||
{
|
||
int i;
|
||
for (i = 0; i < sizeof(sensor_init_data) / sizeof(sensor_init_data[0]); i++) {
|
||
GC6133_wrReg(sensor_init_data[i].reg, sensor_init_data[i].val);
|
||
}
|
||
}
|
||
static s32 GC6133_set_output_size(u16 *width, u16 *height, u8 *freq)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
static s32 GC6133_ID_check(void)
|
||
{
|
||
u8 pid = 0;
|
||
GC6133_rdReg(0xf0, &pid);
|
||
delay(4000);
|
||
GC6133_rdReg(0xf0, &pid);
|
||
delay(4000);
|
||
printf("GC6133 Sensor ID : 0x%x \n", pid);
|
||
if (pid != 0xba) {
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void GC6133_powerio_ctl(u32 _power_gpio, u32 on_off)
|
||
{
|
||
gpio_direction_output(_power_gpio, on_off);
|
||
}
|
||
static void GC6133_reset(u8 isp_dev)
|
||
{
|
||
u8 res_io;
|
||
u8 powd_io;
|
||
u8 id = 0;
|
||
puts("GC6133 reset\n");
|
||
|
||
if (isp_dev == ISP_DEV_0) {
|
||
res_io = GC6133_reset_io[0];
|
||
powd_io = GC6133_power_io[0];
|
||
} else {
|
||
res_io = GC6133_reset_io[1];
|
||
powd_io = GC6133_power_io[1];
|
||
}
|
||
|
||
if (powd_io != (u8) - 1) {
|
||
GC6133_powerio_ctl(powd_io, 0);
|
||
}
|
||
|
||
if (res_io != (u8) - 1) {
|
||
gpio_direction_output(res_io, 1);
|
||
gpio_direction_output(res_io, 0);
|
||
os_time_dly(1);
|
||
gpio_direction_output(res_io, 1);
|
||
}
|
||
}
|
||
void close_sensor2_iic()
|
||
{
|
||
if (iic) {
|
||
dev_close(iic);
|
||
iic = NULL;
|
||
}
|
||
}
|
||
s32 GC6133_check(u8 isp_dev, u32 _reset_gpio, u32 _power_gpio)
|
||
{
|
||
if (!iic) {
|
||
if (isp_dev == ISP_DEV_0) {
|
||
iic = dev_open("iic0", 0);
|
||
} else {
|
||
iic = dev_open("iic1", 0);
|
||
}
|
||
GC6133_reset_io[isp_dev] = (u8)_reset_gpio;
|
||
GC6133_power_io[isp_dev] = (u8)_power_gpio;
|
||
}
|
||
|
||
if (iic == NULL) {
|
||
printf("GC6133 iic open err!!!\n\n");
|
||
return -1;
|
||
}
|
||
GC6133_reset(isp_dev);
|
||
if (0 != GC6133_ID_check()) {
|
||
printf("-------not GC6133------\n\n");
|
||
dev_close(iic);
|
||
iic = NULL;
|
||
return -1;
|
||
}
|
||
printf("-------hello GC6133------\n\n");
|
||
return 0;
|
||
}
|
||
|
||
|
||
s32 GC6133_init(u8 isp_dev, u16 *width, u16 *height, u8 *format, u8 *frame_freq)
|
||
{
|
||
puts("\n\n GC6133_init \n\n");
|
||
|
||
if (0 != GC6133_check(isp_dev, 0, 0)) {
|
||
return -1;
|
||
}
|
||
|
||
GC6133_config_SENSOR(width, height, format, frame_freq);
|
||
|
||
return 0;
|
||
}
|
||
void set_rev_sensor_GC6133(u16 rev_flag)
|
||
{
|
||
if (!rev_flag) {
|
||
GC6133_wrReg(0x17, 0x17);
|
||
} else {
|
||
GC6133_wrReg(0x17, 0x14);
|
||
}
|
||
}
|
||
|
||
u16 GC6133_dvp_rd_reg(u16 addr)
|
||
{
|
||
u8 val;
|
||
GC6133_rdReg((u8)addr, &val);
|
||
return val;
|
||
}
|
||
|
||
void GC6133_dvp_wr_reg(u16 addr, u16 val)
|
||
{
|
||
GC6133_wrReg((u8)addr, (u8)val);
|
||
}
|
||
|
||
// *INDENT-OFF*
|
||
REGISTER_CAMERA1(GC6133) = { //注意这里是SPI摄像头
|
||
.logo = "GC6133",
|
||
.isp_dev = ISP_DEV_1,//对应的IIC设备
|
||
.in_format = SEN_IN_FORMAT_UYVY,
|
||
.mbus_type = SEN_MBUS_BT656,
|
||
#if GC6133_1WIRE_MODE
|
||
.mbus_config = SEN_MBUS_DATA_WIDTH_1B | SEN_MBUS_PCLK_SAMPLE_FALLING,
|
||
#else
|
||
.mbus_config = SEN_MBUS_DATA_WIDTH_2B | SEN_MBUS_PCLK_SAMPLE_FALLING,
|
||
#endif
|
||
.sync_config = 0,//WL82/AC791才可以H-V SYNC互换,请留意
|
||
.fps = CONFIG_INPUT_FPS,
|
||
.out_fps = CONFIG_INPUT_FPS,
|
||
.sen_size = {GC6133_DEVP_INPUT_W, GC6133_DEVP_INPUT_H},
|
||
.cap_fps = CONFIG_INPUT_FPS,
|
||
.sen_cap_size = {GC6133_DEVP_INPUT_W, GC6133_DEVP_INPUT_H},
|
||
|
||
.ops = {
|
||
.avin_fps = NULL,
|
||
.avin_valid_signal = NULL,
|
||
.avin_mode_det = NULL,
|
||
.sensor_check = GC6133_check,
|
||
.init = GC6133_init,
|
||
.set_size_fps = GC6133_set_output_size,
|
||
.power_ctrl = NULL,
|
||
|
||
|
||
.sleep = NULL,
|
||
.wakeup = NULL,
|
||
.write_reg = GC6133_dvp_wr_reg,
|
||
.read_reg = GC6133_dvp_rd_reg,
|
||
.set_sensor_reverse = set_rev_sensor_GC6133,
|
||
}
|
||
};
|
||
|
||
#endif
|
||
|