From 3fb0c76627ee5737cb242eae155597bf578b6531 Mon Sep 17 00:00:00 2001 From: GWater Date: Mon, 27 Oct 2008 23:03:14 +0100 Subject: [PATCH] Add OV7670 sensor. Signed-off-by: GWater --- microdia-dev.c | 6 +- microdia.h | 1 + ov7670.c | 1459 ++++++++++++++------------------------------------------ ov7670.h | 3 +- 4 files changed, 377 insertions(+), 1092 deletions(-) rewrite ov7670.c (94%) diff --git a/microdia-dev.c b/microdia-dev.c index ae189dd..e91b201 100644 --- a/microdia-dev.c +++ b/microdia-dev.c @@ -56,6 +56,11 @@ struct sensor_info sensors[] = { .name = "OV7660", .probe = ov7660_probe }, + { + .id = OV7670_SENSOR, + .name = "OV7670", + .probe = ov7670_probe + }, }; /** @@ -346,4 +351,3 @@ int microdia_6260_flip_detect(struct usb_microdia *dev) return ret; }*/ - diff --git a/microdia.h b/microdia.h index 0669b6c..8cc7b94 100644 --- a/microdia.h +++ b/microdia.h @@ -305,6 +305,7 @@ enum microdia_sensors { OV9655_SENSOR = 2, SOI968_SENSOR = 3, OV7660_SENSOR = 4, + OV7670_SENSOR = 5, }; diff --git a/ov7670.c b/ov7670.c dissimilarity index 94% index b90aa1a..3fcf17e 100644 --- a/ov7670.c +++ b/ov7670.c @@ -1,1090 +1,369 @@ -/** - * @file ov7670.c - * @author Phil Mitchell - * @date 2008-05-09 - * - * @brief Common functions and data for the OmniVision OV7670 sensor. - * - * @note Copyright (C) Phil Mitchell - * - * @par Licences - * - * 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 - */ - -#include "microdia.h" -#include "sn9c20x.h" -#include "ov7670.h" - -/** - * @brief Initializes OV7670 Sensor Registers - * - * @param dev Pointer to the device - * - * @return Zero (success) or negative (USB-error value) - * - */ -int ov7670_initialise(struct usb_microdia *dev) -{ - __u8 buf[32]; - int ret; - - /* - * Phase 1 - */ - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM7, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CLKRC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x04; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_TSLB, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM7, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xb6; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HREF, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_VREF, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM14, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x3a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SCALING_XSC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x35; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SCALING_YSC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x11; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SCALING_DCWCTR, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xf0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SCALING_PCLK_DIV, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SCALING_PCLK_DELAY, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xe0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_GAIN, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AECH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x08; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM9, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x05; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BD50MAX, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x07; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BD60MAX, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x95; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AEW, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x33; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AEB, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xe3; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_VPT, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x75; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x65; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xa1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xd8; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xd8; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xf0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x90; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x94; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC7, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xe5; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x61; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x4b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x16, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x27; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MVFP, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ADCCTR1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x91; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ADCCTR2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x07; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x29, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CHLF, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x35, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x1d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ADC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x71; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ACOM, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x2a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_OFON, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x78; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM12, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x4d, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x20; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x4e, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_GFIX, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x19; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_REG74, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x4f; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x8d, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x8e, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x8f, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x90, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x91, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x96, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x9a, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x84; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xb0, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0c; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ABLC1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0e; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xb2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x82; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_THL_ST, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xb8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xf0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x20; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x7d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x29; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x4a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x8c; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x59, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xa5; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5a, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xde; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5b, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x96; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5c, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x66; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5d, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x10; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5e, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBCTR3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x55; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBCTR2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x11; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBCTR1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x9e; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBCTR0, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_GGAIN, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BLUE, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_RED, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xe7; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x6e; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x70; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x1d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x56; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x73; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BRIGHT, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x55; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CONTRAS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CONTRAS_CENTER, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x9e; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTXS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x08; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM16, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EDGE, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x03; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_REG75, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x63; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_REG76, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x04; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DNSTH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x06; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_REG77, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc2; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM13, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x09; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_REG4B, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x30; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SATCTR, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x08; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM16, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x48; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CONTRAS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x11; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_ARBLM, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc2; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM11, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x88; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_NT_CTRL, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x96, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x30; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x97, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x20; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x98, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x30; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x99, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x84; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x9a, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x29; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x9b, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x03; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x9c, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x99; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BD50ST, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x7f; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BD60ST, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x04; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x78, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x01; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xf0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0f; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x10; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x7e; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x01; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0c; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0f; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x20; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x09; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x03; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x40; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x05; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x30; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0xc8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x26; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x79, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x20; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC2, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x06; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x05; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x05; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC7, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x13; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HSTART, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x01; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HSTOP, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x02; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_VSTRT, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x7a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_VSTOP, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x59; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x30; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x9a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTXS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x84; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x59, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x91; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5a, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x57; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5b, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x75; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5c, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x6d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5d, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x13; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - 0x5e, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x07; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x07; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_LCC7, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xdf; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xdf; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_HAECC4, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x4d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_AWBC6, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTX3, dev->sensor_flags, buf); - if (ret < 0) - goto err; - /* - * Phase 2 - */ - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DBLV, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CLKRC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EXHCH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EXHCL, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DM_LNL, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DM_LNH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc2; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM11, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_BRIGHT, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x60; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CONTRAS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x6e; - buf[1] = 0x70; - buf[2] = 0x00; - buf[3] = 0x1d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 4, - OV7670_CTL_MTX1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x56; - buf[1] = 0x73; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 2, - OV7670_CTL_MTX5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x9a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTXS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x6e; - buf[1] = 0x70; - buf[2] = 0x00; - buf[3] = 0x1d; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 4, - OV7670_CTL_MTX1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x56; - buf[1] = 0x73; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 2, - OV7670_CTL_MTX5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x9a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MTXS, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x01; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EDGE, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x03; - buf[1] = 0x09; - buf[2] = 0x16; - buf[3] = 0x38; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 4, - OV7670_CTL_GAM1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x47; - buf[1] = 0x53; - buf[2] = 0x5e; - buf[3] = 0x6a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 4, - OV7670_CTL_GAM5, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x74; - buf[1] = 0x80; - buf[2] = 0x8c; - buf[3] = 0x9b; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 4, - OV7670_CTL_GAM9, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xb2; - buf[1] = 0xcc; - buf[2] = 0xe5; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 3, - OV7670_CTL_GAM13, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x24; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_SLOP, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM11, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xc0; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM11, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x76; - buf[1] = 0x65; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 2, - OV7670_CTL_HAECC1, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0xe7; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_COM8, dev->sensor_flags, buf); - if (ret < 0) - goto err; - /* - * Phase 3 - */ - buf[0] = 0x0a; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DBLV, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x80; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_CLKRC, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EXHCH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_EXHCL, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DM_LNL, dev->sensor_flags, buf); - if (ret < 0) - goto err; - buf[0] = 0x00; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_DM_LNH, dev->sensor_flags, buf); - if (ret < 0) - goto err; - - return ret; -/* - * Error Handler - */ -err: - UDIA_ERROR("R/W for sensor register failed. Ret code = %d\n", ret); - return ret; -} - -/** - * @brief OV7670 Auto-Flip - * - * @param dev Pointer to the device - * @param vflip Flag to indicate whether or not Camera is currently flipped - * - * @return Zero (success) or negative (USB-error value) - * - */ -int ov7670_auto_flip(struct usb_microdia *dev, __u8 vflip) -{ - int ret; - __u8 buf[2]; - - ret = sn9c20x_read_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MVFP, dev->sensor_flags, buf); - if (ret < 0) - return ret; - - if (vflip == 0) - buf[0] = buf[0] & (0xff ^ OV7670_VFLIP_BIT); - else - buf[0] = buf[0] | OV7670_VFLIP_BIT; - ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, - OV7670_CTL_MVFP, dev->sensor_flags, buf); - - return ret; -} +/** + * @file ov7670.c + * @author Phil Mitchell + * @date 2008-05-09 + * + * @brief Common functions and data for the OmniVision OV7670 sensor. + * + * @note Copyright (C) Phil Mitchell + * + * @par Licences + * + * 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 + */ + +#include "microdia.h" +#include "sn9c20x.h" +#include "ov7670.h" + +static __u8 ov7670_init[][2] { + /* Phase 1 */ +{OV7670_CTL_COM7, 0x80}, +{OV7670_CTL_CLKRC, 0x80}, +{OV7670_CTL_TSLB, 0x04}, +{OV7670_CTL_COM7, 0x00}, +{OV7670_CTL_HREF, 0xb6}, +{OV7670_CTL_VREF, 0x0a}, +{OV7670_CTL_COM3, 0x00}, +{OV7670_CTL_COM14, 0x00}, +{OV7670_CTL_SCALING_XSC, 0x3a}, +{OV7670_CTL_SCALING_YSC, 0x35}, +{OV7670_CTL_SCALING_DCWCTR, 0x11}, +{OV7670_CTL_SCALING_PCLK_DIV, 0xf0}, +{OV7670_CTL_SCALING_PCLK_DELAY, 0x02}, +{OV7670_CTL_COM8, 0xe0}, +{OV7670_CTL_GAIN, 0x00}, +{OV7670_CTL_AECH, 0x00}, +{OV7670_CTL_COM4, 0x40}, +{OV7670_CTL_COM9, 0x08}, +{OV7670_CTL_BD50MAX, 0x05}, +{OV7670_CTL_BD60MAX, 0x07}, +{OV7670_CTL_AEW, 0x95}, +{OV7670_CTL_AEB, 0x33}, +{OV7670_CTL_VPT, 0xe3}, +{OV7670_CTL_HAECC1, 0x75}, +{OV7670_CTL_HAECC2, 0x65}, +{0xa1, 0x0b}, +{OV7670_CTL_HAECC3, 0xd8}, +{OV7670_CTL_HAECC4, 0xd8}, +{OV7670_CTL_HAECC5, 0xf0}, +{OV7670_CTL_HAECC6, 0x90}, +{OV7670_CTL_HAECC7, 0x94}, +{OV7670_CTL_COM8, 0xe5}, +{OV7670_CTL_COM5, 0x61}, +{OV7670_CTL_COM6, 0x4b}, +{0x16, 0x02}, +{OV7670_CTL_MVFP, 0x27}, +{OV7670_CTL_ADCCTR1, 0x02}, +{OV7670_CTL_ADCCTR2, 0x91}, +{0x29, 0x07}, +{OV7670_CTL_CHLF, 0x0b}, +{0x35, 0x0b}, +{OV7670_CTL_ADC, 0x1d}, +{OV7670_CTL_ACOM, 0x71}, +{OV7670_CTL_OFON, 0x2a}, +{OV7670_CTL_COM12, 0x78}, +{0x4d, 0x40}, +{0x4e, 0x20}, +{OV7670_CTL_GFIX, 0x00}, +{OV7670_CTL_REG74, 0x19}, +{0x8d, 0x4f}, +{0x8e, 0x00}, +{0x8f, 0x00}, +{0x90, 0x00}, +{0x91, 0x00}, +{0x96, 0x00}, +{0x9a, 0x80}, +{0xb0, 0x84}, +{OV7670_CTL_ABLC1, 0x0c}, +{0xb2, 0x0e}, +{OV7670_CTL_THL_ST, 0x82}, +{0xb8, 0x0a}, +{OV7670_CTL_AWBC1, 0x0a}, +{OV7670_CTL_AWBC2, 0xf0}, +{OV7670_CTL_AWBC3, 0x20}, +{OV7670_CTL_AWBC4, 0x7d}, +{OV7670_CTL_AWBC5, 0x29}, +{OV7670_CTL_AWBC6, 0x4a}, +{0x59, 0x8c}, +{0x5a, 0xa5}, +{0x5b, 0xde}, +{0x5c, 0x96}, +{0x5d, 0x66}, +{0x5e, 0x10}, +{OV7670_CTL_AWBCTR3, 0x0a}, +{OV7670_CTL_AWBCTR2, 0x55}, +{OV7670_CTL_AWBCTR1, 0x11}, +{OV7670_CTL_AWBCTR0, 0x9e}, +{OV7670_CTL_GGAIN, 0x40}, +{OV7670_CTL_BLUE, 0x40}, +{OV7670_CTL_RED, 0x40}, +{OV7670_CTL_COM8, 0xe7}, +{OV7670_CTL_MTX1, 0x6e}, +{OV7670_CTL_MTX2, 0x70}, +{OV7670_CTL_MTX3, 0x02}, +{OV7670_CTL_MTX4, 0x1d}, +{OV7670_CTL_MTX5, 0x56}, +{OV7670_CTL_MTX6, 0x73}, +{OV7670_CTL_BRIGHT, 0x0a}, +{OV7670_CTL_CONTRAS, 0x55}, +{OV7670_CTL_CONTRAS_CENTER, 0x80}, +{OV7670_CTL_MTXS, 0x9e}, +{OV7670_CTL_COM16, 0x08}, +{OV7670_CTL_EDGE, 0x02}, +{OV7670_CTL_REG75, 0x03}, +{OV7670_CTL_REG76, 0x63}, +{OV7670_CTL_DNSTH, 0x04}, +{OV7670_CTL_REG77, 0x06}, +{OV7670_CTL_COM13, 0xc2}, +{OV7670_CTL_REG4B, 0x09}, +{OV7670_CTL_SATCTR, 0x30}, +{OV7670_CTL_COM16, 0x08}, +{OV7670_CTL_CONTRAS, 0x48}, +{OV7670_CTL_ARBLM, 0x11}, +{OV7670_CTL_COM11, 0xc2}, +{OV7670_CTL_NT_CTRL, 0x88}, +{0x96, 0x00}, +{0x97, 0x30}, +{0x98, 0x20}, +{0x99, 0x30}, +{0x9a, 0x84}, +{0x9b, 0x29}, +{0x9c, 0x03}, +{OV7670_CTL_BD50ST, 0x99}, +{OV7670_CTL_BD60ST, 0x7f}, +{0x78, 0x04}, +{0x79, 0x01}, +{0xc8, 0xf0}, +{0x79, 0x0f}, +{0xc8, 0x00}, +{0x79, 0x10}, +{0xc8, 0x7e}, +{0x79, 0x0a}, +{0xc8, 0x80}, +{0x79, 0x0b}, +{0xc8, 0x01}, +{0x79, 0x0c}, +{0xc8, 0x0f}, +{0x79, 0x0d}, +{0xc8, 0x20}, +{0x79, 0x09}, +{0xc8, 0x80}, +{0x79, 0x02}, +{0xc8, 0xc0}, +{0x79, 0x03}, +{0xc8, 0x40}, +{0x79, 0x05}, +{0xc8, 0x30}, +{0x79, 0x26}, +{OV7670_CTL_LCC1, 0x20}, +{OV7670_CTL_LCC2, 0x00}, +{OV7670_CTL_LCC3, 0x06}, +{OV7670_CTL_LCC4, 0x00}, +{OV7670_CTL_LCC5, 0x05}, +{OV7670_CTL_LCC6, 0x05}, +{OV7670_CTL_LCC7, 0x0a}, +{OV7670_CTL_HSTART, 0x13}, +{OV7670_CTL_HSTOP, 0x01}, +{OV7670_CTL_VSTRT, 0x02}, +{OV7670_CTL_VSTOP, 0x7a}, +{OV7670_CTL_AWBC4, 0x59}, +{OV7670_CTL_AWBC5, 0x30}, +{OV7670_CTL_MTXS, 0x9a}, +{0x59, 0x84}, +{0x5a, 0x91}, +{0x5b, 0x57}, +{0x5c, 0x75}, +{0x5d, 0x6d}, +{0x5e, 0x13}, +{OV7670_CTL_LCC3, 0x07}, +{OV7670_CTL_LCC6, 0x07}, +{OV7670_CTL_LCC7, 0x0d}, +{OV7670_CTL_HAECC3, 0xdf}, +{OV7670_CTL_HAECC4, 0xdf}, +{OV7670_CTL_AWBC6, 0x4d}, +{OV7670_CTL_MTX3, 0x00}, + /* Phase 2 */ +{OV7670_CTL_DBLV, 0x0a}, +{OV7670_CTL_CLKRC, 0x80}, +{OV7670_CTL_EXHCH, 0x00}, +{OV7670_CTL_EXHCL, 0x00}, +{OV7670_CTL_DM_LNL, 0x00}, +{OV7670_CTL_DM_LNH,0x00}, +{OV7670_CTL_COM11, 0xc2}, +{OV7670_CTL_BRIGHT, 0x0a}, +{OV7670_CTL_CONTRAS, 0x60}, +{OV7670_CTL_MTX1, 0x6e}, +{OV7670_CTL_MTX1 + 1, 0x70}, +{OV7670_CTL_MTX1 + 2, 0x00}, +{OV7670_CTL_MTX1 + 3, 0x1d}, +{OV7670_CTL_MTX5, 0x56}, +{OV7670_CTL_MTX5 + 1, 0x73}, +{OV7670_CTL_MTXS, 0x9a}, +{OV7670_CTL_MTX1, 0x6e}, +{OV7670_CTL_MTX1 + 1, 0x70}, +{OV7670_CTL_MTX1 + 2, 0x00}, +{OV7670_CTL_MTX1 + 3, 0x1d}, +{OV7670_CTL_MTX5, 0x56}, +{OV7670_CTL_MTX5 + 1, 0x73}, +{OV7670_CTL_MTXS, 0x9a}, +{OV7670_CTL_EDGE, 0x01}, +{OV7670_CTL_GAM1, 0x03}, +{OV7670_CTL_GAM1 + 1, 0x09}, +{OV7670_CTL_GAM1 + 2, 0x16}, +{OV7670_CTL_GAM1 + 3, 0x38}, +{OV7670_CTL_GAM5, 0x47}, +{OV7670_CTL_GAM5 + 1, 0x53}, +{OV7670_CTL_GAM5 + 2, 0x5e}, +{OV7670_CTL_GAM5 + 3, 0x6a}, +{OV7670_CTL_GAM9, 0x74}, +{OV7670_CTL_GAM9 + 1, 0x80}, +{OV7670_CTL_GAM9 + 2, 0x8c}, +{OV7670_CTL_GAM9 + 3, 0x9b}, +{OV7670_CTL_GAM13, 0xb2}, +{OV7670_CTL_GAM13 + 1, 0xcc}, +{OV7670_CTL_GAM13 + 2, 0xe5}, +{OV7670_CTL_SLOP, 0x24}, +{OV7670_CTL_COM11, 0xc0}, +{OV7670_CTL_COM11, 0xc0}, +{OV7670_CTL_HAECC1, 0x76}, +{OV7670_CTL_HAECC1 + 1, 0x65}, +{OV7670_CTL_COM8, 0xe7}, + /* Phase 3 */ +{OV7670_CTL_DBLV, 0x0a}, +{OV7670_CTL_CLKRC, 0x80}, +{OV7670_CTL_EXHCH, 0x00}, +{OV7670_CTL_EXHCL, 0x00}, +{OV7670_CTL_DM_LNL, 0x00}, +{OV7670_CTL_DM_LNH, 0x00}, +}; + +struct microdia_video_format ov7670_fmts[] = { + { + .pix_fmt = V4L2_PIX_FMT_SBGGR8, + .desc = "Bayer 8bit (BGGR)", + .depth = 8, + .set_format = sn9c20x_set_raw + }, + { + .pix_fmt = V4L2_PIX_FMT_JPEG, + .desc = "JPEG (YUV 4:2:2)", + .depth = 16, + .set_format = sn9c20x_set_jpeg + } +}; + +struct microdia_video_resolution ov7670_resolutions[] = { + { + .width = 160, + .height = 120, + .scale = SN9C20X_1_4_SCALE, + .window = {0, 17, 640, 480} + }, + { + .width = 320, + .height = 240, + .scale = SN9C20X_1_2_SCALE, + .window = {0, 7, 640, 480} + }, + { + .width = 640, + .height = 480, + .scale = SN9C20X_NO_SCALE, + .window = {0, 7, 640, 480} + }, +}; + +int ov7670_probe(struct usb_microdia *dev) +{ + int ret; + __u8 buf[2]; + dev->camera.sensor_slave_address = 0x30; + ret = sn9c20x_read_i2c_data(dev, 2, 0x0a, buf); + if (ret == 0) { + if (buf[0] != 0x76) + return -EINVAL; + if (buf[1] == 0x70) { + ov7670_initialize(dev); + dev->camera.modes = ov7670_resolutions; + dev->camera.nmodes = ARRAY_SIZE(ov7670_resolutions); + dev->camera.fmts = ov7670_fmts; + dev->camera.nfmts = ARRAY_SIZE(ov7670_fmts); + return OV7670_SENSOR; + } + } else { + UDIA_INFO("Failed on i2c read in ov7670 probe\n"); + } + return -EINVAL; +} + +/** + * @brief Initialize ov7670 sensors + * + * @param dev Pointer to device structure + * + * @return 0 or negative error code + * + * This function applies the default settings from #ov7670_init to + * the ov7670 sensor + * + */ +int ov7670_initialize(struct usb_microdia *dev) +{ + int ret, i; + __u8 value, reg; + + for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) { + reg = ov7670_init[i][0]; + value = ov7670_init[i][1]; + ret = sn9c20x_write_i2c_data(dev, 1, reg, &value); + if (ret < 0) { + UDIA_INFO("Sensor Init Error (%d). line %d\n", ret, i); + break; + } + } + + return ret; + +} + +/** + * @brief OV7670 Auto-Flip + * + * @param dev Pointer to the device + * @param vflip Flag to indicate whether or not Camera is currently flipped + * + * @return Zero (success) or negative (USB-error value) + * + */ +int ov7670_auto_flip(struct usb_microdia *dev, __u8 vflip) +{ + int ret; + __u8 buf[2]; + + ret = sn9c20x_read_i2c_data(dev, dev->sensor_slave_address, 1, + OV7670_CTL_MVFP, dev->sensor_flags, buf); + if (ret < 0) + return ret; + + if (vflip == 0) + buf[0] = buf[0] & (0xff ^ OV7670_VFLIP_BIT); + else + buf[0] = buf[0] | OV7670_VFLIP_BIT; + ret = sn9c20x_write_i2c_data(dev, dev->sensor_slave_address, 1, + OV7670_CTL_MVFP, dev->sensor_flags, buf); + + return ret; +} diff --git a/ov7670.h b/ov7670.h index 9f35b7e..aaa528b 100644 --- a/ov7670.h +++ b/ov7670.h @@ -181,5 +181,6 @@ #define OV7670_CTL_SATCTR 0xc9 int ov7670_auto_flip(struct usb_microdia *, __u8); -int ov7670_initialise(struct usb_microdia *); +int ov7670_initialize(struct usb_microdia *dev); +int ov7670_probe(struct usb_microdia *dev); #endif -- 2.11.4.GIT