ov519.c
来自「trident tm5600的linux驱动」· C语言 代码 · 共 2,231 行 · 第 1/4 页
C
2,231 行
/** * OV519 driver * * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) * * (This module is adapted from the ov51x-jpeg package) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */#define MODULE_NAME "ov519"#include "gspca.h"MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");MODULE_DESCRIPTION("OV519 USB Camera Driver");MODULE_LICENSE("GPL");/* global parameters */static int frame_rate;/* Number of times to retry a failed I2C transaction. Increase this if you * are getting "Failed to read sensor ID..." */static int i2c_detect_tries = 10;/* ov519 device descriptor */struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ /* Determined by sensor type */ char sif; unsigned char primary_i2c_slave; /* I2C write id of sensor */ unsigned char brightness; unsigned char contrast; unsigned char colors; __u8 hflip; __u8 vflip; char compress; /* Should the next frame be compressed? */ char compress_inited; /* Are compression params uploaded? */ char stopped; /* Streaming is temporarily paused */ char frame_rate; /* current Framerate (OV519 only) */ char clockdiv; /* clockdiv override for OV519 only */ char sensor; /* Type of image sensor chip (SEN_*) */#define SEN_UNKNOWN 0#define SEN_OV6620 1#define SEN_OV6630 2#define SEN_OV7610 3#define SEN_OV7620 4#define SEN_OV7640 5#define SEN_OV7670 6#define SEN_OV76BE 7#define SEN_OV8610 8};/* V4L2 controls supported by the driver */static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);static struct ctrl sd_ctrls[] = { { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, .maximum = 255, .step = 1,#define BRIGHTNESS_DEF 127 .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, .maximum = 255, .step = 1,#define CONTRAST_DEF 127 .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Color", .minimum = 0, .maximum = 255, .step = 1,#define COLOR_DEF 127 .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, },/* next controls work with ov7670 only */#define HFLIP_IDX 3 { { .id = V4L2_CID_HFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Mirror", .minimum = 0, .maximum = 1, .step = 1,#define HFLIP_DEF 0 .default_value = HFLIP_DEF, }, .set = sd_sethflip, .get = sd_gethflip, },#define VFLIP_IDX 4 { { .id = V4L2_CID_VFLIP, .type = V4L2_CTRL_TYPE_BOOLEAN, .name = "Vflip", .minimum = 0, .maximum = 1, .step = 1,#define VFLIP_DEF 0 .default_value = VFLIP_DEF, }, .set = sd_setvflip, .get = sd_getvflip, },};static struct v4l2_pix_format vga_mode[] = { {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 320, .sizeimage = 320 * 240 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 640, .sizeimage = 640 * 480 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0},};static struct v4l2_pix_format sif_mode[] = { {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 176, .sizeimage = 176 * 144 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 1}, {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, .bytesperline = 352, .sizeimage = 352 * 288 * 3 / 8 + 590, .colorspace = V4L2_COLORSPACE_JPEG, .priv = 0},};/* OV519 Camera interface register numbers */#define OV519_CAM_H_SIZE 0x10#define OV519_CAM_V_SIZE 0x11#define OV519_CAM_X_OFFSETL 0x12#define OV519_CAM_X_OFFSETH 0x13#define OV519_CAM_Y_OFFSETL 0x14#define OV519_CAM_Y_OFFSETH 0x15#define OV519_CAM_DIVIDER 0x16#define OV519_CAM_DFR 0x20#define OV519_CAM_FORMAT 0x25/* OV519 System Controller register numbers */#define OV519_SYS_RESET1 0x51#define OV519_SYS_EN_CLK1 0x54#define OV519_GPIO_DATA_OUT0 0x71#define OV519_GPIO_IO_CTRL0 0x72#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number *//* I2C registers */#define R51x_I2C_W_SID 0x41#define R51x_I2C_SADDR_3 0x42#define R51x_I2C_SADDR_2 0x43#define R51x_I2C_R_SID 0x44#define R51x_I2C_DATA 0x45#define R518_I2C_CTL 0x47 /* OV518(+) only *//* I2C ADDRESSES */#define OV7xx0_SID 0x42#define OV8xx0_SID 0xa0#define OV6xx0_SID 0xc0/* OV7610 registers */#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */#define OV7610_REG_SAT 0x03 /* saturation */#define OV8610_REG_HUE 0x04 /* 04 reserved */#define OV7610_REG_CNT 0x05 /* Y contrast */#define OV7610_REG_BRT 0x06 /* Y brightness */#define OV7610_REG_COM_C 0x14 /* misc common regs */#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */#define OV7610_REG_COM_I 0x29 /* misc settings *//* OV7670 registers */#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */#define OV7670_REG_BLUE 0x01 /* blue gain */#define OV7670_REG_RED 0x02 /* red gain */#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */#define OV7670_REG_COM1 0x04 /* Control 1 */#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */#define OV7670_REG_COM3 0x0c /* Control 3 */#define OV7670_REG_COM4 0x0d /* Control 4 */#define OV7670_REG_COM5 0x0e /* All "reserved" */#define OV7670_REG_COM6 0x0f /* Control 6 */#define OV7670_REG_AECH 0x10 /* More bits of AEC value */#define OV7670_REG_CLKRC 0x11 /* Clock control */#define OV7670_REG_COM7 0x12 /* Control 7 */#define OV7670_COM7_FMT_VGA 0x00#define OV7670_COM7_YUV 0x00 /* YUV */#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */#define OV7670_COM7_FMT_MASK 0x38#define OV7670_COM7_RESET 0x80 /* Register reset */#define OV7670_REG_COM8 0x13 /* Control 8 */#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */#define OV7670_COM8_AWB 0x02 /* White balance enable */#define OV7670_COM8_AGC 0x04 /* Auto gain enable */#define OV7670_COM8_BFILT 0x20 /* Band filter enable */#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */#define OV7670_REG_COM10 0x15 /* Control 10 */#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */#define OV7670_REG_VSTART 0x19 /* Vert start high bits */#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */#define OV7670_MVFP_VFLIP 0x10 /* vertical flip */#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */#define OV7670_REG_AEW 0x24 /* AGC upper limit */#define OV7670_REG_AEB 0x25 /* AGC lower limit */#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */#define OV7670_REG_HREF 0x32 /* HREF pieces */#define OV7670_REG_TSLB 0x3a /* lots of stuff */#define OV7670_REG_COM11 0x3b /* Control 11 */#define OV7670_COM11_EXP 0x02#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */#define OV7670_REG_COM12 0x3c /* Control 12 */#define OV7670_REG_COM13 0x3d /* Control 13 */#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */#define OV7670_REG_COM14 0x3e /* Control 14 */#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */#define OV7670_REG_COM15 0x40 /* Control 15 */#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */#define OV7670_REG_COM16 0x41 /* Control 16 */#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */#define OV7670_REG_BRIGHT 0x55 /* Brightness */#define OV7670_REG_CONTRAS 0x56 /* Contrast control */#define OV7670_REG_GFIX 0x69 /* Fix gain control */#define OV7670_REG_RGB444 0x8c /* RGB 444 control */#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */struct ov_regvals { __u8 reg; __u8 val;};struct ov_i2c_regvals { __u8 reg; __u8 val;};static const struct ov_i2c_regvals norm_6x20[] = { { 0x12, 0x80 }, /* reset */ { 0x11, 0x01 }, { 0x03, 0x60 }, { 0x05, 0x7f }, /* For when autoadjust is off */ { 0x07, 0xa8 }, /* The ratio of 0x0c and 0x0d controls the white point */ { 0x0c, 0x24 }, { 0x0d, 0x24 }, { 0x0f, 0x15 }, /* COMS */ { 0x10, 0x75 }, /* AEC Exposure time */ { 0x12, 0x24 }, /* Enable AGC */ { 0x14, 0x04 }, /* 0x16: 0x06 helps frame stability with moving objects */ { 0x16, 0x06 },/* { 0x20, 0x30 }, * Aperture correction enable */ { 0x26, 0xb2 }, /* BLC enable */ /* 0x28: 0x05 Selects RGB format if RGB on */ { 0x28, 0x05 }, { 0x2a, 0x04 }, /* Disable framerate adjust *//* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ { 0x2d, 0x99 }, { 0x33, 0xa0 }, /* Color Processing Parameter */ { 0x34, 0xd2 }, /* Max A/D range */ { 0x38, 0x8b }, { 0x39, 0x40 }, { 0x3c, 0x39 }, /* Enable AEC mode changing */ { 0x3c, 0x3c }, /* Change AEC mode */ { 0x3c, 0x24 }, /* Disable AEC mode changing */ { 0x3d, 0x80 }, /* These next two registers (0x4a, 0x4b) are undocumented. * They control the color balance */ { 0x4a, 0x80 }, { 0x4b, 0x80 }, { 0x4d, 0xd2 }, /* This reduces noise a bit */ { 0x4e, 0xc1 }, { 0x4f, 0x04 },/* Do 50-53 have any effect? *//* Toggle 0x12[2] off and on here? */};static const struct ov_i2c_regvals norm_6x30[] = { { 0x12, 0x80 }, /* Reset */ { 0x00, 0x1f }, /* Gain */ { 0x01, 0x99 }, /* Blue gain */ { 0x02, 0x7c }, /* Red gain */ { 0x03, 0xc0 }, /* Saturation */ { 0x05, 0x0a }, /* Contrast */ { 0x06, 0x95 }, /* Brightness */ { 0x07, 0x2d }, /* Sharpness */ { 0x0c, 0x20 }, { 0x0d, 0x20 }, { 0x0e, 0x20 }, { 0x0f, 0x05 }, { 0x10, 0x9a }, { 0x11, 0x00 }, /* Pixel clock = fastest */ { 0x12, 0x24 }, /* Enable AGC and AWB */ { 0x13, 0x21 }, { 0x14, 0x80 }, { 0x15, 0x01 }, { 0x16, 0x03 }, { 0x17, 0x38 }, { 0x18, 0xea }, { 0x19, 0x04 }, { 0x1a, 0x93 }, { 0x1b, 0x00 }, { 0x1e, 0xc4 }, { 0x1f, 0x04 }, { 0x20, 0x20 }, { 0x21, 0x10 }, { 0x22, 0x88 }, { 0x23, 0xc0 }, /* Crystal circuit power level */ { 0x25, 0x9a }, /* Increase AEC black ratio */ { 0x26, 0xb2 }, /* BLC enable */ { 0x27, 0xa2 }, { 0x28, 0x00 }, { 0x29, 0x00 }, { 0x2a, 0x84 }, /* 60 Hz power */ { 0x2b, 0xa8 }, /* 60 Hz power */ { 0x2c, 0xa0 }, { 0x2d, 0x95 }, /* Enable auto-brightness */ { 0x2e, 0x88 }, { 0x33, 0x26 }, { 0x34, 0x03 }, { 0x36, 0x8f }, { 0x37, 0x80 }, { 0x38, 0x83 }, { 0x39, 0x80 }, { 0x3a, 0x0f }, { 0x3b, 0x3c }, { 0x3c, 0x1a }, { 0x3d, 0x80 }, { 0x3e, 0x80 }, { 0x3f, 0x0e }, { 0x40, 0x00 }, /* White bal */ { 0x41, 0x00 }, /* White bal */ { 0x42, 0x80 }, { 0x43, 0x3f }, /* White bal */ { 0x44, 0x80 }, { 0x45, 0x20 }, { 0x46, 0x20 }, { 0x47, 0x80 }, { 0x48, 0x7f }, { 0x49, 0x00 }, { 0x4a, 0x00 }, { 0x4b, 0x80 }, { 0x4c, 0xd0 }, { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ { 0x4e, 0x40 }, { 0x4f, 0x07 }, /* UV avg., col. killer: max */ { 0x50, 0xff }, { 0x54, 0x23 }, /* Max AGC gain: 18dB */ { 0x55, 0xff }, { 0x56, 0x12 }, { 0x57, 0x81 }, { 0x58, 0x75 }, { 0x59, 0x01 }, /* AGC dark current comp.: +1 */ { 0x5a, 0x2c }, { 0x5b, 0x0f }, /* AWB chrominance levels */ { 0x5c, 0x10 }, { 0x3d, 0x80 }, { 0x27, 0xa6 }, { 0x12, 0x20 }, /* Toggle AWB */ { 0x12, 0x24 },};/* Lawrence Glaister <lg@jfm.bc.ca> reports: * * Register 0x0f in the 7610 has the following effects: * * 0x85 (AEC method 1): Best overall, good contrast range * 0x45 (AEC method 2): Very overexposed * 0xa5 (spec sheet default): Ok, but the black level is * shifted resulting in loss of contrast * 0x05 (old driver setting): very overexposed, too much * contrast */static const struct ov_i2c_regvals norm_7610[] = { { 0x10, 0xff }, { 0x16, 0x06 }, { 0x28, 0x24 }, { 0x2b, 0xac }, { 0x12, 0x00 }, { 0x38, 0x81 }, { 0x28, 0x24 }, /* 0c */ { 0x0f, 0x85 }, /* lg's setting */ { 0x15, 0x01 }, { 0x20, 0x1c }, { 0x23, 0x2a }, { 0x24, 0x10 }, { 0x25, 0x8a }, { 0x26, 0xa2 }, { 0x27, 0xc2 }, { 0x2a, 0x04 }, { 0x2c, 0xfe }, { 0x2d, 0x93 }, { 0x30, 0x71 }, { 0x31, 0x60 }, { 0x32, 0x26 }, { 0x33, 0x20 }, { 0x34, 0x48 }, { 0x12, 0x24 }, { 0x11, 0x01 }, { 0x0c, 0x24 }, { 0x0d, 0x24 },};static const struct ov_i2c_regvals norm_7620[] = { { 0x00, 0x00 }, /* gain */ { 0x01, 0x80 }, /* blue gain */ { 0x02, 0x80 }, /* red gain */ { 0x03, 0xc0 }, /* OV7670_REG_VREF */ { 0x06, 0x60 }, { 0x07, 0x00 }, { 0x0c, 0x24 }, { 0x0c, 0x24 }, { 0x0d, 0x24 }, { 0x11, 0x01 }, { 0x12, 0x24 }, { 0x13, 0x01 }, { 0x14, 0x84 }, { 0x15, 0x01 }, { 0x16, 0x03 }, { 0x17, 0x2f }, { 0x18, 0xcf }, { 0x19, 0x06 }, { 0x1a, 0xf5 }, { 0x1b, 0x00 }, { 0x20, 0x18 }, { 0x21, 0x80 }, { 0x22, 0x80 }, { 0x23, 0x00 }, { 0x26, 0xa2 }, { 0x27, 0xea }, { 0x28, 0x20 }, { 0x29, 0x00 }, { 0x2a, 0x10 }, { 0x2b, 0x00 }, { 0x2c, 0x88 }, { 0x2d, 0x91 }, { 0x2e, 0x80 }, { 0x2f, 0x44 }, { 0x60, 0x27 }, { 0x61, 0x02 }, { 0x62, 0x5f }, { 0x63, 0xd5 }, { 0x64, 0x57 }, { 0x65, 0x83 }, { 0x66, 0x55 }, { 0x67, 0x92 }, { 0x68, 0xcf }, { 0x69, 0x76 }, { 0x6a, 0x22 }, { 0x6b, 0x00 }, { 0x6c, 0x02 }, { 0x6d, 0x44 }, { 0x6e, 0x80 }, { 0x6f, 0x1d }, { 0x70, 0x8b }, { 0x71, 0x00 }, { 0x72, 0x14 }, { 0x73, 0x54 }, { 0x74, 0x00 }, { 0x75, 0x8e }, { 0x76, 0x00 }, { 0x77, 0xff }, { 0x78, 0x80 }, { 0x79, 0x80 }, { 0x7a, 0x80 }, { 0x7b, 0xe2 }, { 0x7c, 0x00 },};/* 7640 and 7648. The defaults should be OK for most registers. */static const struct ov_i2c_regvals norm_7640[] = { { 0x12, 0x80 }, { 0x12, 0x14 },};/* 7670. Defaults taken from OmniVision provided data,* as provided by Jonathan Corbet of OLPC */static const struct ov_i2c_regvals norm_7670[] = { { OV7670_REG_COM7, OV7670_COM7_RESET }, { OV7670_REG_TSLB, 0x04 }, /* OV */ { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ { OV7670_REG_CLKRC, 0x01 },/* * Set the hardware window. These values from OV don't entirely * make sense - hstop is less than hstart. But they work... */ { OV7670_REG_HSTART, 0x13 },
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?