www.pudn.com > camera.rar > ov2630_hw.c


// 
// Copyright (c) Microsoft Corporation.  All rights reserved. 
// 
// 
// Use of this sample source code is subject to the terms of the Microsoft 
// license agreement under which you licensed this sample source code. If 
// you did not accept the terms of the license agreement, you are not 
// authorized to use this sample source code. For the terms of the license, 
// please see the license agreement between you and Microsoft or, if applicable, 
// see the LICENSE.RTF on your install media or the root of your tools installation. 
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES. 
// 
// 
// (C) Copyright 2006 Marvell International Ltd. 
// All Rights Reserved 
// 
/*  
** INTEL CONFIDENTIAL 
** Copyright 2000-2006 Intel Corporation All Rights Reserved. 
** 
** The source code contained or described herein and all documents 
** related to the source code (Material) are owned by Intel Corporation 
** or its suppliers or licensors.  Title to the Material remains with 
** Intel Corporation or its suppliers and licensors. The Material contains 
** trade secrets and proprietary and confidential information of Intel 
** or its suppliers and licensors. The Material is protected by worldwide 
** copyright and trade secret laws and treaty provisions. No part of the 
** Material may be used, copied, reproduced, modified, published, uploaded, 
** posted, transmitted, distributed, or disclosed in any way without Intel’s 
** prior express written permission. 
** 
** No license under any patent, copyright, trade secret or other intellectual 
** property right is granted to or conferred upon you by disclosure or 
** delivery of the Materials, either expressly, by implication, inducement, 
** estoppel or otherwise. Any license under such intellectual property rights 
** must be express and approved by Intel in writing. 
*/ 
/*++ 
 
Module Name:  $Workfile: xllp_ov2630_hw.c $ 
 
Abstract:   
     contains all hardware related functions for OV2630 
 
Notes:Only valid for processor code named Monahans. 
 
--*/ 
 
//#include "xllp_camera_os_depend.h" 
#include "Camera_SOC.h" 
#include "ost.h" 
#include "ov2630_hw.h" 
#include "GPX_API.h" 
#include "I2C_DRV.h" 
 
/*********************************************************************** 
*  Register Settings 
***********************************************************************/ 
 
 
 
const static UINT8 ov2630InitSetting[]= 
{ 
 
 
    0x12,    0x80, 
    0x0e,    0x0, 
    0x0f,    0x42, 
    0x13,    0xe7, 
    0x14,    0x4e, 
    0x24,    0x6c, 
    0x25,    0x60, 
    0x35,    0x90, 
    0x36,    0x88, 
    0x37,    0x44, 
    0x3a,    0x90, 
    0x3b,    0x14, 
    0x3f,    0x0f, 
    0x40,    0x0, 
    0x41,    0x0, 
    0x42,    0x0, 
    0x43,    0x0, 
    0x44,    0x80, 
    0x4b,    0x00, 
    0x4c,    0x28, 
    0x50,    0xf4, 
    0x58,    0x7, 
    0x59,    0x20, 
    0x5f,    0x40, 
    0x75,    0x0f, 
    0x78,    0x40, 
    0x7a,    0x10, 
    0x84,    0x4, 
    0x86,    0x20, 
    0x88,    0x0c, 
    0x89,    0x08, 
    0x8a,    0x2, 
    OV2630_REGEND,   0x00 
}; 
 
/*********************************************************************** 
*  Register Settings, Get from OmniVision 
***********************************************************************/ 
static UINT8 UXGA[] = 
{ 
    //0x11,    0x01, 
    0x11,    0x02,   /* workaroud for issue 193451 */ 
    0x34,    0xf0, 
    0x03,    0x48, 
    0x17,    0x2d, 
    0x18,    0x02, 
    0x19,    0x01, 
    0x1a,    0x97, 
    0x1e,    0x40, 
    0x32,    0x1b, 
    0x4d,    0xc0, 
    0x5a,    0x00, 
    0x87,    0x10, 
     
    /* for non-zoom */ 
    0x0c,    0x21, 
    0x16,    0x00, 
    0x12,    0x00, 
    0x48,    0x80, 
    0x4a,    0x00, 
    0x4e,    0x18, 
    0x4f,    0x08, 
    OV2630_REGEND,   0x00 
 
}; 
 
static UINT8 SVGA[] = 
{ 
    0x11,    0x00, 
    0x34,   0x70, 
    0x3,    0x0e, 
    0x17,    0x3f, 
    0x18,    0x02, 
    0x19,    0x0, 
    0x1a,    0x4b, 
    0x1e,    0x00, 
    0x32,    0x1f, 
    0x4d,    0xc0, 
    0x5a,    0x00, 
    0x87,    0x00, 
 
    /* for non-zoom */ 
    0x0c,    0xa0, 
    0x16,    0x00, 
    0x12,    0x41, 
    0x48,    0x00, 
    0x4a,    0x00, 
    0x4e,    0x08, 
    0x4f,    0x00, 
    OV2630_REGEND,   0x00 
 
 
 
}; 
 
static UINT8 CIF[] = 
{ 
    0x11,    0x01, 
    0x34,    0x70, 
    0x03,    0x0a, 
    0x17,    0x3f, 
    0x18,    0x01, 
    0x19,    0x00, 
    0x1a,    0x25, 
    0x1e,    0x00, 
    0x32,    0xbf, 
    0x4d,    0xc0, 
    0x5a,    0x80, 
    0x87,    0x00, 
     
    /* for non-zoom */ 
    0x0c,    0xa0, 
    0x16,    0x00, 
    0x12,    0x21, 
    0x48,    0x00, 
    0x4a,    0x00, 
    0x4e,    0x08, 
    0x4f,    0x00, 
    OV2630_REGEND,   0x00 
 
}; 
 
const static UINT8 gSensorSlaveAddr = 0x30; 
 
/*********************************************************************** 
*  Private/helper api 
***********************************************************************/ 
#ifdef PXA_DEBUG_PARAM_CHECK 
static PXA_STATUS_T PrvGetRegValue( UINT8 *regP, UINT8 regAddr, UINT8 *regValueP ) 
{ 
    UINT32 index = 0; 
    UINT8 curReg = 0; 
     
    while( curReg < OV2630_REGEND ) 
    { 
        curReg = regP[index << 1]; 
        if( curReg == regAddr ) 
        { 
            *regValueP = regP[(index << 1) + 1]; 
            return PXA_STATUS_SUCCESS; 
        }     
        index ++; 
    }  
         
    return PXA_STATUS_FAILURE; 
 
} 
 
static PXA_STATUS_T PrvSetRegValue( UINT8 *regP, UINT8 regAddr, UINT8 regValue ) 
{ 
    UINT32 index = 0; 
    UINT8 curReg = 0; 
     
    while( curReg < OV2630_REGEND ) 
    { 
        curReg = regP[index << 1]; 
        if( curReg == regAddr ) 
        { 
            regP[(index << 1) + 1] = regValue; 
            return PXA_STATUS_SUCCESS; 
        }     
        index ++; 
    }  
         
    return PXA_STATUS_FAILURE; 
 
} 
#endif 
 
/*********************************************************************** 
*  Sensor read/write  
***********************************************************************/ 
static int PrvReadSensorReg( const UINT8 subAddress, UINT8 *bufP ) 
{ 
    UINT8 buffer[1]; 
    int status; 
    buffer[0] = subAddress; 
     
    //status = OS_I2CMasterWriteData( gSensorSlaveAddr, buffer, 1); 
    status = I2C_WriteData(gSensorSlaveAddr, buffer, 1, TRUE, PXA_I2C_NORMAL_LEVEL); 
    if (!status) { 
        //status = OS_I2CMasterReadData( gSensorSlaveAddr, buffer, 1); 
        status = I2C_ReadData(gSensorSlaveAddr, buffer, 1, TRUE, PXA_I2C_NORMAL_LEVEL); 
        *bufP = buffer[0]; 
    } 
     
    return status; 
} 
 
static int PrvWriteSensorReg( const UINT8 subAddress, UINT8 *bufP ) 
{ 
    UINT8 buffer[2]; 
    int status; 
    buffer[0] = subAddress; 
    buffer[1] = *bufP; 
     
    //status = OS_I2CMasterWriteData( gSensorSlaveAddr, buffer, 2); 
    status = I2C_WriteData(gSensorSlaveAddr, buffer, 2, TRUE, PXA_I2C_NORMAL_LEVEL); 
     
    return status; 
} 
 
static int PrvRMWSensorReg( const UINT8 subAddress, UINT8 *bufP, UINT8 andMask, UINT8 orMask )  
{ 
    int status; 
    status = PrvReadSensorReg( subAddress, bufP ); 
    if (!status) { 
        *bufP &= andMask; 
        *bufP |= orMask; 
        status = PrvWriteSensorReg( subAddress, bufP ); 
    } 
    return status; 
} 
 
int OV2630ReadSensorReg( const UINT8 subAddress, UINT8 *bufP ) 
{ 
    return PrvReadSensorReg(subAddress, bufP); 
} 
 
int OV2630WriteSensorReg( const UINT8 subAddress, UINT8 *bufP ) 
{ 
    return PrvWriteSensorReg(subAddress, bufP); 
} 
 
PXA_STATUS_T OV2630SetRegs( const UINT8 *regP ) 
{ 
    UINT32    curReg = 0; 
    PXA_STATUS_T    status = PXA_STATUS_SUCCESS; 
         
    // The list is a register number followed by the value. 
    while( regP[curReg << 1] < OV2630_REGEND ) 
    { 
        UINT8 regVal = regP[(curReg << 1) + 1]; 
 
        status = (PrvWriteSensorReg( regP[curReg << 1], ®Val ) == 0) ? 
                 PXA_STATUS_SUCCESS : PXA_STATUS_FAILURE; 
         
        if( curReg == 0 ) 
            OV2630Wait( 5 ); 
             
        curReg++; 
    } 
         
    return status; 
} 
 
 
 
PXA_STATUS_T OV2630ReadAllRegs( UINT8 *bufP, UINT32 numRegs ) 
{ 
    UINT32    curReg; 
     
    for( curReg = 0; curReg < numRegs; curReg++, bufP++ ) 
        PrvReadSensorReg( (UINT8)curReg, bufP ); 
 
 
    return PXA_STATUS_SUCCESS; 
} 
 
/*********************************************************************** 
*  Power & Reset 
***********************************************************************/ 
void OV2630PowerDown(UINT8 powerMode ) 
{ 
    // OV2630 PWRDWN, 0 = NORMAL, 1=POWER DOWN 
    // Call_GPX 
 
    if( powerMode == PXA_CAMERA_POWER_OFF ) 
        GPX_SetOutputLevel(GPX_GPIO_CAMERA_HI_PWDN, PXA_HI ); 
    else 
        GPX_SetOutputLevel(GPX_GPIO_CAMERA_HI_PWDN, PXA_LO ); 
 
   PXA_OST_DelayMilliSeconds(100 ); 
} 
 
void OV2630Reset( ) 
{ 
    OV2630SetRegs(ov2630InitSetting); 
    return; 
} 
 
void OV2630Wait( int ms ) 
{ 
    Sleep( ms ); 
} 
 
 
/*********************************************************************** 
*  Settings 
***********************************************************************/ 
int OV2630VersionRevision(UINT8 * pCmRevision, UINT8 *pSensorRevision) 
{ 
    PrvReadSensorReg( OV2630_PIDH, pCmRevision ); 
    PrvReadSensorReg( OV2630_PIDL, pSensorRevision ); 
    return PXA_STATUS_SUCCESS; 
} 
 
void OV2630SetHSYNC() 
{ 
    UINT8    val; 
     
    // Makes HREF become HSYNC 
    PrvReadSensorReg( OV2630_COMK, &val ); 
    val |= 0x40; 
    PrvWriteSensorReg( OV2630_COMK, &val ); 
} 
 
void OV2630AutoFunctionOn() 
{ 
    UINT8 val; 
    PrvReadSensorReg( OV2630_COMI, &val ); 
    val |= 0x07;    // don't disturb AWB 
    PrvWriteSensorReg( OV2630_COMI, &val ); 
} 
 
void OV2630AutoFunctionOff() 
{ 
    UINT8 val; 
    PrvReadSensorReg( OV2630_COMI, &val ); 
    val &= ~0x07;    // don't disturb AWB 
    PrvWriteSensorReg( OV2630_COMI, &val ); 
} 
 
 
/*********************************************************************** 
*  Viewfinder, still  
***********************************************************************/ 
int OV2630ViewfinderOn() 
{ 
    UINT8    com3; 
     
    PrvReadSensorReg( OV2630_COMD, &com3 ); 
    com3 &= ~0x01; 
    PrvWriteSensorReg( OV2630_COMD, &com3 ); 
         
    return OV_ERR_NONE; 
} 
 
 
int OV2630ViewfinderOff() 
{ 
    UINT8    com3; 
     
    PrvReadSensorReg( OV2630_COMD, &com3 ); 
    com3 |= 0x01; 
    PrvWriteSensorReg( OV2630_COMD, &com3 ); 
     
    return OV_ERR_NONE; 
} 
 
 
int OV2630HaltVideoOutput() 
{ 
    UINT8    com3; 
     
    // Set the camera to only output 1 frame. 
    PrvReadSensorReg( OV2630_COMD, &com3 ); 
    com3 |= 1; 
    PrvWriteSensorReg( OV2630_COMD, &com3 ); 
     
    return OV_ERR_NONE; 
} 
 
int OV2630ResumetoFullOutputMode() 
{ 
    UINT8    mode; 
     
    // Output still frames continuously 
    // Turn off single capture mode COM3. 
    PrvRMWSensorReg( OV2630_COMD, (&mode), ((UINT8) ~1), 0 ); 
    return OV_ERR_NONE; 
} 
 
int OV2630GetSingleImage() 
{ 
    UINT8    mode; 
     
    PrvRMWSensorReg( OV2630_COMD, &mode, (UINT8) ~1, 1 ); 
    return OV_ERR_NONE; 
} 
 
/*********************************************************************** 
*  Format  
***********************************************************************/ 
PXA_STATUS_T OV2630SetFormat(UINT32 captureWidth,  
                              UINT32 captureHeight,  
                              UINT32 *winStartX,  
                              UINT32 *winStartY,  
                              UINT32 *winEndX,  
                              UINT32 *winEndY) 
{ 
    OV2630_MODE mode; 
    UINT16 hStart; 
    UINT16 vStart; 
    UCHAR regVal; 
 
 
     
 
 
    // 
    // let the sensor work on proper mode 
    // 
    if((captureWidth <= 400) && (captureHeight <= 292)){ 
        mode = OV2630_CIF; 
    } else if((captureWidth <= 800) && (captureHeight <= 600)) { 
        mode = OV2630_SVGA; 
    } else if((captureWidth <= 1600) && (captureHeight <= 1200)) { 
        mode = OV2630_UXGA; 
    } else { 
        return PXA_STATUS_WRONG_PARAMETER; 
    } 
  
    if (mode == OV2630_CIF){ 
        OV2630SetRegs(CIF); 
    }else if (mode == OV2630_SVGA){ 
       OV2630SetRegs(SVGA); 
    }else{ 
       OV2630SetRegs(UXGA); 
    } 
 
    // 
    // set cropping window 
    // 
    if (mode == OV2630_CIF) { 
        captureWidth *= 2; 
    } 
     
    
    if (mode == OV2630_CIF){ 
 
        hStart = (UINT16)(511 + (800 -captureWidth)/2); 
 
        vStart = (UINT16)(2 + (292 - captureHeight)/4); 
 
         
    }else if (mode == OV2630_SVGA){ 
 
     
        hStart = (UINT16)(511 + (800 -captureWidth)/2); 
 
        vStart = (UINT16)(2 + (600 - captureHeight)/4); 
     
    }else{ 
 
        hStart = (UINT16)(363 + (1600 -captureWidth)/2); 
        vStart = (UINT16)(4 + (1200 - captureHeight)/4); 
    } 
 
     
    
    // set Horizontal Window Start 
    regVal = hStart>>3; 
    PrvWriteSensorReg(OV2630_HREFST, ®Val); 
    PrvReadSensorReg(OV2630_COMM, ®Val); 
    regVal &= ~0x07; 
    regVal |= hStart & 0x07; 
    PrvWriteSensorReg(OV2630_COMM, ®Val); 
 
 
    // set Vertical Window Start 
    regVal = vStart>>2; 
    PrvWriteSensorReg(OV2630_VSTRT, ®Val); 
    PrvReadSensorReg(OV2630_COMA, ®Val); 
    regVal &= ~0x03; 
    regVal |= vStart & 0x03; 
    PrvWriteSensorReg(OV2630_COMA, ®Val); 
 
 
 
 
 
 
    // 
    // return window region 
    // 
     
    *winStartX = hStart; 
    *winStartY = vStart; 
    *winEndX   = hStart + captureWidth; 
    *winEndY   = vStart + captureHeight; 
     
    return PXA_STATUS_SUCCESS; 
}