os/linux-2.6-tag--devboard-R2_10-4/arch/cris/arch-v32/drivers/elphel/mt9x001.c

Go to the documentation of this file.
00001 /*!********************************************************************************
00002 *! FILE NAME  : mt9x001.c
00003 *! DESCRIPTION: sensor support for Micron image sensors:
00004 *! MT9M001(1280x1024)
00005 *! MT9D001(1600x1200)
00006 *! MT9T001(2048x1536)
00007 *! MT9P001/MT9P031(2592x1944)
00008 *!
00009 *! Copyright (C) 2004-2008 Elphel, Inc.
00010 *! -----------------------------------------------------------------------------**3
00011 *!
00012 *!  This program is free software: you can redistribute it and/or modify
00013 *!  it under the terms of the GNU General Public License as published by
00014 *!  the Free Software Foundation, either version 3 of the License, or
00015 *!  (at your option) any later version.
00016 *!
00017 *!  This program is distributed in the hope that it will be useful,
00018 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *!  GNU General Public License for more details.
00021 *!
00022 *!  You should have received a copy of the GNU General Public License
00023 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00024 *! -----------------------------------------------------------------------------**
00025 *!  $Log: mt9x001.c,v $
00026 *!  Revision 1.1.1.1  2008/11/27 20:04:00  elphel
00027 *!
00028 *!
00029 *!  Revision 1.24  2008/11/17 06:43:32  elphel
00030 *!  bug fix (wrong parameter name)
00031 *!
00032 *!  Revision 1.23  2008/11/15 07:03:43  elphel
00033 *!  sensor gains now modify parameters to match sensor capabilities, changed truncating to rounding
00034 *!
00035 *!  Revision 1.22  2008/10/29 04:18:28  elphel
00036 *!  v.8.0.alpha10 made a separate structure for global parameters (not related to particular frames in a frame queue)
00037 *!
00038 *!  Revision 1.21  2008/10/22 05:27:55  elphel
00039 *!  bug fix ("||" was instead of "|"), removed some unused debug output
00040 *!
00041 *!  Revision 1.20  2008/10/22 03:47:16  elphel
00042 *!  added P_VIRT_KEEP parameter to enable VIRT_WIDTH, VIRT_HEIGHT preservation (if !=0), otherwise these parameters are set to minimalallowed by sensor an FPS limit
00043 *!
00044 *!  Revision 1.19  2008/10/20 18:45:07  elphel
00045 *!  just more debug printk
00046 *!
00047 *!  Revision 1.18  2008/10/18 06:14:21  elphel
00048 *!  8.0.alpha4 - removed some obsolete parameters, renumbered others, split P_FLIP into P_FLIPH and P_FLIPV (different latencies because of bad frames), pgm_window-> pgm_window, pgm_window_safe
00049 *!
00050 *!  Revision 1.17  2008/10/12 06:13:10  elphel
00051 *!  snapshot
00052 *!
00053 *!  Revision 1.16  2008/10/11 18:46:07  elphel
00054 *!  snapshot
00055 *!
00056 *!  Revision 1.15  2008/10/08 21:26:25  elphel
00057 *!  snapsot 7.2.0.pre4 - first images (actually - second)
00058 *!
00059 *!  Revision 1.14  2008/10/06 08:31:08  elphel
00060 *!  snapshot, first images
00061 *!
00062 *!  Revision 1.13  2008/10/04 16:10:12  elphel
00063 *!  snapshot
00064 *!
00065 *!  Revision 1.12  2008/09/28 00:31:57  elphel
00066 *!  snapshot
00067 *!
00068 *!  Revision 1.11  2008/09/25 00:58:11  elphel
00069 *!  snapshot
00070 *!
00071 *!  Revision 1.10  2008/09/22 22:55:48  elphel
00072 *!  snapshot
00073 *!
00074 *!  Revision 1.9  2008/09/12 00:23:59  elphel
00075 *!  removed cc353.c, cc353.h
00076 *!
00077 *!  Revision 1.8  2008/09/11 01:05:32  elphel
00078 *!  snapshot
00079 *!
00080 *!  Revision 1.7  2008/09/04 17:37:13  elphel
00081 *!  documenting
00082 *!
00083 *!  Revision 1.6  2008/08/11 19:17:01  elphel
00084 *!  reduced syntax complaints by KDevelop
00085 *!
00086 *!  Revision 1.5  2008/07/27 23:25:07  elphel
00087 *!  next snapshot
00088 *!
00089 *!  Revision 1.4  2008/07/27 04:27:49  elphel
00090 *!  next snapshot
00091 *!
00092 *!  Revision 1.3  2008/06/20 03:54:19  elphel
00093 *!  another snapshot
00094 *!
00095 *!  Revision 1.2  2008/06/19 02:17:36  elphel
00096 *!  continuing work - just a snapshot
00097 *!
00098 *!  Revision 1.9  2008/05/02 15:13:35  elphel
00099 *!  switch to hardware i2c write,added related sensor parameters
00100 *!
00101 *!  Revision 1.8  2008/05/01 01:28:57  elphel
00102 *!  hardware i2c control - macros, variables
00103 *!
00104 *!  Revision 1.7  2008/03/20 22:29:30  elphel
00105 *!  added trigger-related code and parameters
00106 *!
00107 *!  Revision 1.6  2008/02/12 21:53:20  elphel
00108 *!  Modified I2c to support multiple buses, added raw access (no address registers) and per-slave protection bitmasks
00109 *!
00110 *!  Revision 1.5  2008/02/05 18:28:59  spectr_rain
00111 *!  correct timing for MT9P sensor with binning and skipping 1,2,4
00112 *!
00113 *!  Revision 1.4  2007/12/27 14:27:43  spectr_rain
00114 *!  fixed FPS, correct work with the skipping - TODO - check the binning
00115 *!
00116 *!  Revision 1.3  2007/10/16 23:17:51  elphel
00117 *!  cosmetic
00118 *!
00119 
00120 //  Revision 1.2  2007/10/16 20:03:38  elphel
00121 //  cosmetic
00122 //
00123 //  Revision 1.1.1.1  2007/09/30 03:19:56  elphel
00124 //  This is a fresh tree based on elphel353-2.10
00125 //
00126 //  Revision 1.12  2007/09/30 03:19:56  elphel
00127 //  Cleanup, fixed broken acquisition of individual JPEG images into circbuf (in mode 7)
00128 //
00129 //  Revision 1.11  2007/09/19 04:22:33  elphel
00130 //  fixed debug output
00131 //
00132 //  Revision 1.10  2007/09/19 00:34:21  elphel
00133 //  support for frame rate limiting, disabled extra debug  messages
00134 //
00135 //  Revision 1.9  2007/09/18 06:09:22  elphel
00136 //  support for merged P_FLIP, support fro P_FPSLM (fps limit mode) that allow to limit FPS (upper limit) and maintain FPS (lower limit) preventing exposure time to exceed one divided by fps limit
00137 //
00138 //  Revision 1.8  2007/09/12 18:05:35  spectr_rain
00139 //  *** empty log message ***
00140 //
00141 //  Revision 1.7  2007/08/17 10:23:19  spectr_rain
00142 //  switch to GPL3 license
00143 //
00144 //  Revision 1.6  2007/07/20 10:17:46  spectr_rain
00145 //  *** empty log message ***
00146 //
00147 //  Revision 1.10  2007/07/09 22:05:43  elphel
00148 //  minor sensor phase adjustment (constant so far)
00149 //
00150 //  Revision 1.9  2007/07/09 21:10:14  elphel
00151 //  Reducing EMI from the sensor front end cable by reducing the drive strengths on the lines. Improving phase adjustment (and phase error measurements) for the sensors. Dealing with the delayed (with respect to pixel data) line/frame valid signals in MT9P001 sensors
00152 //
00153 //  Revision 1.8  2007/07/09 05:15:17  elphel
00154 //  set slowest speed on the outputs to reduce EMI
00155 //
00156 //  Revision 1.7  2007/06/28 02:24:40  elphel
00157 //  Increased default frequency for 5MPix sensor to 96MHz
00158 //
00159 //  Revision 1.6  2007/06/18 07:57:24  elphel
00160 //  Fixed bug working with MT9P031 - added sensor reset/reinit after frequency change
00161 //
00162 //  Revision 1.5  2007/05/21 17:45:11  elphel
00163 //  boundary scan support, added 359/347 detection
00164 //
00165 //  Revision 1.4  2007/04/23 22:48:32  spectr_rain
00166 //  *** empty log message ***
00167 //
00168 //  Revision 1.3  2007/04/17 18:28:06  spectr_rain
00169 //  *** empty log message ***
00170 //
00171 //  Revision 1.2  2007/04/04 03:55:22  elphel
00172 //  Improved i2c, added i2c as character devices (to use from php)
00173 //
00174 //  Revision 1.1.1.1  2007/02/23 10:11:48  elphel
00175 //  initial import into CVS
00176 //
00177 //  Revision 1.12  2006/12/01 00:18:12  spectr_rain
00178 //  *** empty log message ***
00179 //
00180 //  Revision 1.11  2006/11/28 18:33:26  spectr_rain
00181 //  *** empty log message ***
00182 //
00183 //  Revision 1.9  2006/11/01 18:49:57  spectr_rain
00184 //  *** empty log message ***
00185 //
00186 //  Revision 1.8  2006/09/12 15:21:55  spectr_rain
00187 //  use ve for integration time if e == 0
00188 //
00189 //  Revision 1.7  2006/09/02 22:04:17  spectr_rain
00190 //  *** empty log message ***
00191 //
00192 //  Revision 1.6  2006/09/02 00:19:49  spectr_rain
00193 //  lock sensor while readrawimage
00194 //
00195 //  Revision 1.5  2006/07/17 12:22:42  spectr_rain
00196 //  enable autoexposition
00197 //
00198 //  Revision 1.4  2006/07/13 04:21:15  elphel
00199 //  mt9p031 now wants the same bayer as others - maybe DLYHOR bit was set earlier?
00200 //
00201 //  Revision 1.3  2006/07/12 19:32:49  spectr_rain
00202 //  fix Bayer pattern for less than 5MPx sensors
00203 //
00204 //  Revision 1.2  2006/07/12 06:03:16  elphel
00205 //  bug fix
00206 //
00207 //  Revision 1.1.1.1  2006/07/11 19:15:00  spectr_rain
00208 //  unwork with less than 5MPx Micron sensor, initial branch
00209 //
00210 //  Revision 1.25  2006/06/05 07:31:22  spectr_rain
00211 //  set blank vertical to 0 if pfh > 0
00212 //
00213 //  Revision 1.24  2006/02/16 03:37:06  elphel
00214 //  *** empty log message ***
00215 //
00216 //  Revision 1.23  2006/02/08 01:53:56  spectr_rain
00217 //  fix broken mutex in check of down_interruptible
00218 //
00219 //  Revision 1.22  2006/01/15 22:24:03  elphel
00220 //  bug fix, made binning a non-stop parameter
00221 //
00222 //  Revision 1.21  2006/01/15 13:03:27  spectr_rain
00223 //  fix deadlock
00224 //
00225 //  Revision 1.19  2006/01/12 03:52:14  elphel
00226 //  *** empty log message ***
00227 //
00228 //  Revision 1.18  2006/01/10 15:41:54  spectr_rain
00229 //  use gain compensation for color canal scale
00230 //
00231 //  Revision 1.17  2006/01/05 05:36:13  spectr_rain
00232 //  *** empty log message ***
00233 //
00234 //  Revision 1.15  2006/01/05 05:21:32  spectr_rain
00235 //  *** empty log message ***
00236 //
00237 //  Revision 1.14  2006/01/05 05:15:27  spectr_rain
00238 //  new sensitivity/scale iface
00239 //
00240 //  Revision 1.13  2006/01/05 00:01:21  elphel
00241 //  fixed hang-up - removed restarting a frame that was sometimes hanging a sensor until reset
00242 //
00243 //  Revision 1.12  2005/11/29 09:13:31  spectr_rain
00244 //  add autoexposure
00245 //
00246 //  Revision 1.11  2005/11/23 05:13:25  spectr_rain
00247 //  use exposition and gain with autoexposition
00248 //
00249 //  Revision 1.10  2005/11/22 09:21:01  elphel
00250 //  Fixed skipping of half frames, improved period calculation (not yet for binning modes)
00251 //
00252 //  Revision 1.9  2005/10/12 17:58:08  elphel
00253 //  fixed wrong fps reporting in mt9x001.c
00254 //
00255 //  Revision 1.8  2005/10/11 08:25:41  elphel
00256 //  fixed long exposures without slowing down sensor (especially for 3MPix sensor)
00257 //
00258 //  Revision 1.7  2005/09/15 22:46:51  elphel
00259 //  Fixed bug with 1.3MPix Micron sensor (introduced in previous release)
00260 //
00261 //  Revision 1.6  2005/09/10 23:33:22  elphel
00262 //  Support of realtime clock and timestamps in the images
00263 //
00264 //  Revision 1.5  2005/09/06 03:40:37  elphel
00265 //  changed parameters, added support for the photo-finish mode
00266 //
00267 //  Revision 1.4  2005/08/27 05:16:27  elphel
00268 //  binning
00269 //
00270 //  Revision 1.3  2005/08/27 00:46:39  elphel
00271 //  bayer control with &byr=
00272 //
00273 //  Revision 1.2  2005/05/10 21:08:49  elphel
00274 //  *** empty log message ***
00275 //
00276 
00277 */
00278 
00279 
00280 /****************** INCLUDE FILES SECTION ***********************************/
00281 #include <linux/types.h> 
00282 #include <asm/div64.h>   
00283 
00284 #include <linux/module.h>
00285 #include <linux/sched.h>
00286 #include <linux/slab.h>
00287 
00288 #include <linux/time.h>
00289 
00290 
00291 #include <linux/errno.h>
00292 #include <linux/kernel.h>
00293 #include <linux/fs.h>
00294 #include <linux/string.h>
00295 #include <linux/init.h>
00296 #include <linux/autoconf.h>
00297 
00298 #include <asm/system.h>
00299 //#include <asm/svinto.h> // obsolete
00300 #include <asm/io.h>
00301 
00302 #include <asm/irq.h>
00303 
00304 #include <asm/delay.h>
00305 #include <asm/uaccess.h>
00306 #include <asm/elphel/c313a.h>
00307 
00308 //#include "cc3x3.h"
00309 #include "fpgactrl.h"  // defines port_csp0_addr, port_csp4_addr 
00310 #include "x3x3.h" // detect sensor
00311 
00312 #include "cci2c.h"
00313 #include "mt9x001.h"
00314 //#include "hist.h"
00315 #include "framepars.h"      // parameters manipulation
00316 #include "sensor_common.h"
00317 #include "pgm_functions.h"
00318 #include "x3x3.h"           // hardware definitions
00319 
00324 #if ELPHEL_DEBUG
00325  #define MDF4(x) { if (GLOBALPARS(G_DEBUG) & (1 <<4)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
00326  #define ELPHEL_DEBUG_THIS 0
00327 // #define ELPHEL_DEBUG_THIS 1
00328 #else
00329  #define MDF4(x)
00330  #define ELPHEL_DEBUG_THIS 0
00331 #endif
00332 
00333 #if ELPHEL_DEBUG_THIS
00334   #define MDF1(x) printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x
00335   #define MDD1(x) printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); x ; udelay (ELPHEL_DEBUG_DELAY)
00336   #define D(x) printk("%s:%d:",__FILE__,__LINE__);x
00337   #define D1(x) x
00338   #define MD7(x) printk("%s:%d:",__FILE__,__LINE__);x
00339   #define MD9(x) printk("%s:%d:",__FILE__,__LINE__);x
00340 #else
00341   #define MDF1(x)
00342   #define MDD1(x)
00343   #define D(x)
00344   #define D1(x)
00345   #define MD7(x)
00346   #define MD9(x)
00347 #endif
00348 
00349 //  #define DEFAULT_XTRA          1000   // number of pixel times to add to the frame compression time (just a guess)
00352 
00358 //#define USELONGLONG 1
00359 //#define USELONGLONG 0 
00360 
00361 struct sensor_t mt9m001={
00362 // sensor constants
00363    .imageWidth  = 1280,     
00364    .imageHeight = 1024,     
00365    .clearWidth  = 1289,     
00366    .clearHeight = 1033,     
00367    .clearTop    = 8,        
00368    .clearLeft   = 16,       
00369    .arrayWidth  = 1312,     
00370    .arrayHeight = 1048,     
00371    .minWidth    = 4,        
00372    .minHeight   = 3,        
00373    .minHorBlank = 19,       
00374    .minLineDur  = 244,      
00375    .maxHorBlank = 2047,     
00376    .minVertBlank= 16,       
00377    .maxVertBlank= 2047,     
00378    .maxShutter  = 0x3fff,   
00379    .flips       = 3,        
00380    .init_flips  = 3,        
00381    .bayer       = 3,        
00382    .dcmHor      = 0x8b,     
00383    .dcmVert     = 0x8b,     
00384    .binHor      = 0x01,     
00385    .binVert     = 0x01,     
00386    .maxGain256  = 4032,     
00387    .minClockFreq= 20000000, 
00388    .maxClockFreq= 48000000, 
00389    .nomClockFreq= 48000000, 
00390    .sensorType  = SENSOR_MT9X001 + MT9M_TYP,  
00391    .i2c_addr    = MT9X001_I2C_ADDR,           
00392    .i2c_period  = 2500,     
00393    .i2c_bytes   = 2,        
00394    .hact_delay  = 0,        
00395    .sensorPhase90=0,        
00396    .sensorPhase = 0,        
00397    .needReset=    SENSOR_NEED_RESET_CLK | SENSOR_NEED_RESET_PHASE  
00398 };
00399 
00400 struct sensor_t mt9d001={
00401 // sensor constants
00402    .imageWidth  = 1600,     
00403    .imageHeight = 1200,     
00404    .clearWidth  = 1609,     
00405    .clearHeight = 1209,     
00406    .clearTop    = 8,        
00407    .clearLeft   = 20,       
00408    .arrayWidth  = 1632,     
00409    .arrayHeight = 1224,     
00410    .minWidth    = 4,        
00411    .minHeight   = 3,        
00412    .minHorBlank = 19,       
00413    .minLineDur  = 617,      
00414    .maxHorBlank = 2047,     
00415    .minVertBlank= 16,       
00416    .maxVertBlank= 2047,     
00417    .maxShutter  = 0x3fff,   
00418    .flips       = 3,        
00419    .init_flips  = 3,        
00420    .bayer       = 3,        
00421    .dcmHor      = 0x8b,     
00422    .dcmVert     = 0x8b,     
00423    .binHor      = 0x01,     
00424    .binVert     = 0x01,     
00425    .maxGain256  = 4032,     
00426    .minClockFreq= 20000000, 
00427    .maxClockFreq= 48000000, 
00428    .nomClockFreq= 48000000, 
00429    .sensorType  = SENSOR_MT9X001 + MT9D_TYP,      
00430    .i2c_addr    = MT9X001_I2C_ADDR,
00431    .i2c_period  = 2500,     
00432    .i2c_bytes   = 2,        
00433    .hact_delay  = 0,        
00434    .sensorPhase90=0,        
00435    .sensorPhase = 0,        
00436    .needReset=    SENSOR_NEED_RESET_CLK | SENSOR_NEED_RESET_PHASE   
00437 };
00438 struct sensor_t mt9t001={
00440    .imageWidth  = 2048,     
00441    .imageHeight = 1536,     
00442    .clearWidth  = 2048,     
00443    .clearHeight = 1545,     
00444    .clearTop    = 16,       
00445    .clearLeft   = 28,       
00446    .arrayWidth  = 2112,     
00447    .arrayHeight = 1568,     
00448    .minWidth    = 2,        
00449    .minHeight   = 2,        
00450    .minHorBlank = 21,       
00451    .minLineDur  = 511,      
00452    .maxHorBlank = 2047,     
00453    .minVertBlank= 4,        
00454    .maxVertBlank= 2047,     
00455    .maxShutter  = 0xfffff,  
00456    .flips       = 3,        
00457    .init_flips  = 3,        
00458    .bayer       = 3,        
00459    .dcmHor      = 0xff,     
00460    .dcmVert     = 0xff,     
00461    .binHor      = 0xff,     
00462    .binVert     = 0xff,     
00463    .maxGain256  = 4032,     
00464    .minClockFreq= 20000000, 
00465    .maxClockFreq= 48000000, 
00466    .nomClockFreq= 48000000, 
00467    .sensorType  = SENSOR_MT9X001 + MT9T_TYP,      
00468    .i2c_addr    = MT9X001_I2C_ADDR,
00469    .i2c_period  = 2500,     
00470    .i2c_bytes   = 2,        
00471    .hact_delay  = 0,        
00472    .sensorPhase90=0,        
00473    .sensorPhase = 0,        
00474    .needReset=    SENSOR_NEED_RESET_CLK | SENSOR_NEED_RESET_PHASE   
00475 };
00476 struct sensor_t mt9p001={
00478    .imageWidth  = 2592,     
00479    .imageHeight = 1944,     
00480    .clearWidth  = 2608,     
00481    .clearHeight = 1952,     
00482    .clearTop    = 50,       
00483    .clearLeft   = 10,       
00484    .arrayWidth  = 2752,     
00485    .arrayHeight = 2003,     
00486    .minWidth    = 2,        
00487    .minHeight   = 2,        
00488    .minHorBlank = 0,        
00489    .minLineDur  = 647,      
00490    .maxHorBlank = 4095,     
00491    .minVertBlank= 9,        
00492    .maxVertBlank= 2047,     
00493    .maxShutter  = 0xfffff,  
00494    .flips       = 3,        
00495    .init_flips  = 0,        
00496    .bayer       = 3,        
00497    .dcmHor      = 0xff,     
00498    .dcmVert     = 0xff,     
00499    .binHor      = 0xff,     
00500    .binVert     = 0xff,     
00501    .maxGain256  = 4032,     
00502    .minClockFreq= 20000000, 
00503    .maxClockFreq= 96000000, 
00504    .nomClockFreq= 96000000, 
00505    .sensorType  = SENSOR_MT9X001 + MT9P_TYP,  
00506    .i2c_addr    = MT9P001_I2C_ADDR,
00507    .i2c_period  = 2500,     
00508    .i2c_bytes   = 2,        
00509    .hact_delay  = 7500,     
00510    .sensorPhase90= 0,       
00511    .sensorPhase = -60,      
00512    .needReset=    SENSOR_NEED_RESET_CLK | SENSOR_NEED_RESET_PHASE   
00513 };
00514 
00516 
00517 static  unsigned short mt9m001_inits[]= 
00518   {
00519   };
00520 static  unsigned short mt9d001_inits[]= 
00521   {
00522    P_MT9X001_CALTHRESH , 0xa39d,
00523    P_MT9X001_CALCTRL,    0x8498
00524   };
00525 static  unsigned short mt9t001_inits[]= 
00526   {
00527   };
00528 
00529 static  unsigned short mt9p001_inits[]= 
00530   {
00531    P_MT9X001_OUTCTRL,  0x2, 
00532    P_MT9X001_7F     ,  0x0  
00533   };
00534 int mt9x001_pgm_detectsensor (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00535 int mt9x001_pgm_initsensor   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00536 int mt9x001_pgm_window       (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00537 int mt9x001_pgm_window_safe  (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00538 inline int mt9x001_pgm_window_common  (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00539 int mt9x001_pgm_limitfps     (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00540 int mt9x001_pgm_exposure     (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00541 int mt9x001_pgm_gains        (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00542 int mt9x001_pgm_triggermode  (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00543 int mt9x001_pgm_sensorregs   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8);
00545 #define I2C_READ_DATA16(x) ((i2c_read_data[(x)<<1]<<8)+i2c_read_data[((x)<<1)+1])
00546 
00565 int mt9x001_pgm_detectsensor   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00566   unsigned long flags; 
00567   unsigned char    i2c_read_data[2]; 
00568   unsigned char chipver_reg=P_MT9X001_CHIPVER;
00569   int sensor_subtype=0;
00570   struct sensor_t * psensor; 
00571   MDF4(printk(" frame8=%d\n",frame8));
00572 //  MDD1(printk("sensor=0x%x\n", (int)sensor));
00573   if (thispars->pars[P_SENSOR]!=0) { 
00574     MDF1(printk(" sensor 0x%x already detected, exiting\n",(int) thispars->pars[P_SENSOR]));
00575     return sensor->sensorType;
00576   }
00578   CCAM_NEGRST;  
00579   CCAM_TRIG_INT;
00580   CCAM_MRST_OFF;
00581   CCAM_ARST_OFF;
00582   udelay (100);
00583 
00585   psensor= &mt9p001;
00586   local_irq_save(flags); 
00587     X3X3_I2C_STOP_WAIT; 
00588     i2c_writeData(0, (psensor->i2c_addr) & 0xfe,  &chipver_reg, 1, 0); 
00589     i2c_readData (0, (psensor->i2c_addr) | 1,     i2c_read_data, 2, 0); 
00590   local_irq_restore(flags); 
00591   printk("sensor id= 0x%x\r\n",i2c_read_data[0]);
00592   if (((I2C_READ_DATA16(0) ^ MT9P001_PARTID) & MT9X001_PARTIDMASK)==0) {
00593     printk("Found MT9P001 2592x1944 sensor, chip ID=%x\n",(i2c_read_data[0]<<8)+i2c_read_data[1]);
00594     sensor_subtype=MT9P_TYP; //1;
00595   }
00596 //  MDD1(printk("sensor=0x%x\n", (int)sensor));
00597   if (sensor_subtype ==0)  { // not a 5MPix chip
00598     psensor= &mt9m001; //address the same for all others
00599     local_irq_save(flags); 
00600       X3X3_I2C_STOP_WAIT; 
00601       i2c_writeData(0, (psensor->i2c_addr) & 0xfe, &chipver_reg, 1, 0); // no stop before read
00602       i2c_readData (0, (psensor->i2c_addr) | 1,    i2c_read_data, 2, 0); //restart, not strart
00603     local_irq_restore(flags); 
00604     printk("-sensor id= 0x%x\r\n",i2c_read_data[0]);
00605     if (((I2C_READ_DATA16(0)^MT9M001_PARTID) & MT9X001_PARTIDMASK)==0) {
00606       printk("Found MT9M001 1280x1024 sensor, chip ID=%x\r\n",I2C_READ_DATA16(0));
00607       psensor= &mt9m001;
00608       sensor_subtype=MT9M_TYP; //1;
00609     } else if (((I2C_READ_DATA16(0)^MT9D001_PARTID) & MT9X001_PARTIDMASK)==0) {
00610       printk("Found MT9D001 1600x1200 sensor, chip ID=%x\r\n",I2C_READ_DATA16(0));
00611       psensor= &mt9d001; 
00612       sensor_subtype=MT9D_TYP; //2;
00613     } else if (((I2C_READ_DATA16(0)^MT9T001_PARTID) & MT9X001_PARTIDMASK)==0) {
00614       printk("Found MT9T001 2048x1536 sensor, chip ID=%x\r\n",I2C_READ_DATA16(0));
00615       psensor= &mt9t001;
00616       sensor_subtype=MT9T_TYP; //3;
00618     }
00619   }
00620 //  MDD1(printk("sensor=0x%x, sensor_subtype=0x%x\n", (int)sensor, (int)sensor_subtype));
00621   if (sensor_subtype ==0)   return 0;  
00622 
00623 //  memcpy(&sensor, psensor, sizeof(mt9p001)); /// copy sensor definitions
00624   memcpy(sensor, psensor, sizeof(mt9p001)); 
00625 //  MDD1(printk("sensor=0x%x\n", (int)sensor));
00626   MDF1(printk("copied %d bytes of sensor static parameters\r\n",sizeof(mt9p001)));
00627 
00628   add_sensor_proc(onchange_detectsensor,&mt9x001_pgm_detectsensor); 
00629   add_sensor_proc(onchange_initsensor,  &mt9x001_pgm_initsensor);   
00630   add_sensor_proc(onchange_exposure,    &mt9x001_pgm_exposure);     
00631   add_sensor_proc(onchange_window,      &mt9x001_pgm_window);       
00632   add_sensor_proc(onchange_window_safe, &mt9x001_pgm_window_safe);  
00633   add_sensor_proc(onchange_limitfps,    &mt9x001_pgm_limitfps);     
00634   add_sensor_proc(onchange_gains,       &mt9x001_pgm_gains);        
00635   add_sensor_proc(onchange_triggermode, &mt9x001_pgm_triggermode);  
00636   add_sensor_proc(onchange_sensorregs,  &mt9x001_pgm_sensorregs);   
00637 //  MDD1(printk("sensor->sensorType=0x%lx\n", sensor->sensorType));
00638   setFramePar(thispars, P_SENSOR,  sensor->sensorType);
00639 //  MDD1(printk("\n"));
00640   return sensor->sensorType;
00642 }
00643 
00654 int mt9x001_pgm_initsensor   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00655   MDF4(printk(" frame8=%d\n",frame8));
00656   if (frame8 >= 0) return -1; 
00657   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
00658   unsigned long flags; 
00659   struct frameparspair_t pars_to_update[256]; 
00660   unsigned char    i2c_read_data[512]; 
00661   int nupdate=0;
00662   int i;
00663   printk("Resetting MT9X001 sensor\r\n");
00665   CCAM_MRST_ON;
00666   udelay (100);
00667   CCAM_MRST_OFF;
00668   udelay (100);
00669   printk("Reading sensor registers to the shadows:\r\n");
00670   i2c_read_data[0]=0;
00671   local_irq_save(flags); 
00672     X3X3_I2C_STOP_WAIT; 
00673     i2c_writeData(0, (sensor->i2c_addr) & 0xfe,  i2c_read_data, 1, 0);   
00674     i2c_readData (0, (sensor->i2c_addr) | 1,     i2c_read_data, 512, 0); 
00675   local_irq_restore(flags); 
00676 
00677 
00678   nupdate=0;
00679   for (i=0; i<256; i++) { 
00680 //     pars_to_update[nupdate  ].num=P_SENSOR_REGS+i;
00681 //     pars_to_update[nupdate++].val=I2C_READ_DATA16(i);
00682      SETFRAMEPARS_SET(P_SENSOR_REGS+i,I2C_READ_DATA16(i));
00683   }
00684   if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
00685 
00686   printk("Initializing MT9X001 registers with default values:\r\n");
00687   unsigned short * sensor_register_overwrites;
00688   int              sensor_register_overwrites_number;
00689   int              sensor_subtype=sensor->sensorType  - SENSOR_MT9X001;
00690   switch (sensor_subtype) {
00691      case MT9M_TYP:
00692        sensor_register_overwrites=         (unsigned short *) &mt9m001_inits; 
00693        sensor_register_overwrites_number=  sizeof(mt9m001_inits)/4;
00694        break;
00695      case MT9D_TYP:
00696        sensor_register_overwrites=         (unsigned short *) &mt9d001_inits;
00697        sensor_register_overwrites_number=  sizeof(mt9d001_inits)/4;
00698        break;
00699      case MT9T_TYP:
00700        sensor_register_overwrites=         (unsigned short *) &mt9t001_inits;
00701        sensor_register_overwrites_number=  sizeof(mt9t001_inits)/4;
00702        break;
00703      case MT9P_TYP:
00704      default:
00705        sensor_register_overwrites=         (unsigned short *) &mt9p001_inits;
00706        sensor_register_overwrites_number=  sizeof(mt9p001_inits)/4;
00707        break;
00708   }
00710   local_irq_save(flags); 
00711   X3X3_I2C_RUN; 
00712   X3X3_SEQ_RUN;
00713   local_irq_restore(flags); 
00714 
00715   nupdate=0;  
00716   for (i=0; i<sensor_register_overwrites_number;i++ ) { 
00717 //     pars_to_update[nupdate  ].num=P_SENSOR_REGS+sensor_register_overwrites[2*i];
00718 //     pars_to_update[nupdate++].val=sensor_register_overwrites[2*i+1];
00719      SETFRAMEPARS_SET(P_SENSOR_REGS+sensor_register_overwrites[2*i], sensor_register_overwrites[2*i+1]);
00720      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, sensor_register_overwrites[2*i], sensor_register_overwrites[2*i+1]);
00721      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) sensor_register_overwrites[2*i], (int) sensor_register_overwrites[2*i+1]));
00722 
00723   }
00724   if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
00725   return 0;
00726 } 
00727 
00737 
00738 
00739 int mt9x001_pgm_window      (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00740   MDF4(printk(" frame8=%d\n",frame8));
00741   return mt9x001_pgm_window_common (sensor,  thispars, prevpars, frame8);
00742 }
00743 int mt9x001_pgm_window_safe (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00744   MDF4(printk(" frame8=%d\n",frame8));
00745   return mt9x001_pgm_window_common (sensor,  thispars, prevpars, frame8);
00746 }
00747 
00748 
00749 inline int mt9x001_pgm_window_common  (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00750   struct frameparspair_t  pars_to_update[8];
00751   int nupdate=0;
00752   MDF4(printk(" frame8=%d\n",frame8));
00753   if (frame8 >= PARS_FRAMES) return -1; 
00754   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
00755   int i,dv,dh,bv,bh,ww,wh,wl,wt,flip,flipX,flipY,d, v;
00756   int styp = sensor->sensorType & 7;
00757   dh=  thispars->pars[P_DCM_HOR];
00758   dv=  thispars->pars[P_DCM_VERT];
00759   bh=  thispars->pars[P_BIN_HOR];
00760   bv=  thispars->pars[P_BIN_VERT];
00761   ww=  thispars->pars[P_SENSOR_PIXH] * dh;
00762   wh=  thispars->pars[P_SENSOR_PIXV] * dv;
00763   flip=((thispars->pars[P_FLIPH] & 1) | ((thispars->pars[P_FLIPV] & 1) << 1 )) ^ sensor->init_flips; 
00764   flipX =  flip & 1;
00765   flipY = (flip & 2)? 1:0;
00766   d = 2 * bh * (ww / (2 * bh));
00767   if (unlikely(d != ww)) { 
00768 //         setFramePar(thispars, P_SENSOR_PIXH,  d / dh);
00769      SETFRAMEPARS_SET(P_SENSOR_PIXH, d / dh);
00770          ww = d;
00771   }
00773   if ((ww-1) != thispars->pars[P_SENSOR_REGS+P_MT9X001_WIDTH]) {
00774      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_WIDTH, ww-1);
00775      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_WIDTH, ww-1);
00776      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_WIDTH, (int) ww-1));
00777   }
00779   d = (wh+1) & 0xfffe; 
00780   if (unlikely(d != wh)) { 
00781 //      setFramePar(thispars, P_SENSOR_PIXV,  d / dv);
00782      SETFRAMEPARS_SET(P_SENSOR_PIXV, d / dv);
00783      wh = d;
00784   }
00786   if ((wh-1) != thispars->pars[P_SENSOR_REGS+P_MT9X001_HEIGHT]) {
00787      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_HEIGHT, wh-1);
00788      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_HEIGHT, wh-1);
00789      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_HEIGHT, (int) wh-1));
00790   }
00792   wl = thispars->pars[P_WOI_LEFT];
00793   wt = thispars->pars[P_WOI_TOP];
00795   if (!thispars->pars[P_OVERSIZE]) { 
00796       if(flipX) {
00797          wl = sensor->clearWidth - ww - wl - X313_MARGINS * dh;
00798          if(wl < 0) wl = 0;
00799       }
00800       if(flipY) {
00801          wt = sensor->clearHeight - wh - wt - X313_MARGINS * dv;
00802          if(wt < 0) wt = 0;
00803       }
00805       wt = (wt + sensor->clearTop) & 0xfffe; 
00806       wl = (wl + sensor->clearLeft) & 0xfffe; 
00808       switch(styp) {
00809       case MT9P_TYP:
00810          d = (bh > 1) ? ((bh > 2) ? 16 : 8) : 4;
00811          if(flipX)
00812             i = d * ((wl - 2) / d) + 2;
00813          else
00814             i = d * (wl / d);
00815          if(i < wl)
00816             i += d;
00817          wl = i;
00818          break;
00819       case MT9T_TYP:
00820          d = (bh > 1) ? ((bh > 2) ? (16) : (8)) : (4);
00821          if(flipX)
00822             i = d * ((wl - 2) / d) + 2;
00823          else
00824             i = d * (wl / d);
00825          if(i < wl)
00826             i += d;
00827          wl = i;
00828          break;
00829       }
00830   }
00832   if (wl != thispars->pars[P_SENSOR_REGS+P_MT9X001_COLSTART]) {
00833      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_COLSTART, wl);
00834      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_COLSTART, wl);
00835      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_COLSTART, (int) wl));
00836 
00837   }
00839   if (wt != thispars->pars[P_SENSOR_REGS+P_MT9X001_ROWSTART]) {
00840      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_ROWSTART, wt);
00841      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_ROWSTART, wt);
00842      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_ROWSTART,(int)  wt));
00843   }
00846   if((styp == MT9T_TYP) || (styp == MT9P_TYP)) { 
00847      v= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RAM] & 0xff88) | ((bv - 1) << 4) | (dv - 1) ;
00848      if (v != thispars->pars[P_SENSOR_REGS+P_MT9X001_RAM]) {
00849         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_RAM, v);
00850         X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RAM, v);
00851         MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_RAM, (int) v));
00852      }
00853      v=(thispars->pars[P_SENSOR_REGS+P_MT9X001_CAM] & 0xff88) | ((bh - 1) << 4) | (dh - 1);
00854      if (v != thispars->pars[P_SENSOR_REGS+P_MT9X001_CAM]) {
00855         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_CAM, v);
00856         X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_CAM, v);
00857         MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_CAM, (int) v));
00858      }
00859      v= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE2] & 0x3fff) | 
00860          (flipX ? (1 << 14) : 0) | 
00861          (flipY ? (1 << 15) : 0) ; 
00862      if (v != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE2]) {
00863         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_RMODE2, v);
00864         X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RMODE2, v);
00865         MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr, (int) sensor->i2c_addr, (int) P_MT9X001_RMODE2, (int) v));
00866 
00867      }
00868   } else { 
00869      v=  (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xffc3) | 
00870          ((dh == 4) ? (1 << 2) : 0) | 
00871          ((dv == 4) ? (1 << 3) : 0) | 
00872          ((dh == 8) ? (1 << 4) : 0) | 
00873          ((dv == 8) ? (1 << 5) : 0) ; 
00874      if (v != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) {
00875         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_RMODE1, v);
00876         X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RMODE1, v);
00877         MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_RMODE1, (int) v));
00878      }
00879      v=  (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE2] & 0x3fe7) | // preserve other bits from shadows
00880          ((dh == 2) ? (1 << 3) : 0) | 
00881          ((dv == 2) ? (1 << 4) : 0) | 
00882          (flipX ? (1 << 14) : 0) | 
00883          (flipY ? (1 << 15) : 0) ; 
00884      if (v != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE2]) {
00885         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_RMODE2, v);
00886         X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RMODE2, v);
00887         MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_RMODE2, (int) v));
00888      }
00889 
00890    }
00891    if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
00892   return 0;
00893 }
00894 
00906 
00907 
00908 int mt9x001_pgm_limitfps   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
00909   struct frameparspair_t pars_to_update[10]; 
00910   int nupdate=0;
00911   MDF4(printk(" frame8=%d\n",frame8));
00912   if (frame8 >= PARS_FRAMES) return -1; 
00913   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
00914   int dh=  thispars->pars[P_DCM_HOR];
00915   int ww=  thispars->pars[P_SENSOR_PIXH] * dh;
00916   int binning_cost = 0;
00917   int width;
00918   int row_time_in_pixels=0;
00919   int hor_blank_min;
00920   int hor_blank=0;
00921   int p1,p2, pix_period, sclk,fp1000s;
00922   int styp = sensor->sensorType & 7;
00923 #if USELONGLONG
00924   uint64_t ull_fp1000s;
00925 #endif
00926   int target_virt_width=(thispars->pars[P_VIRT_KEEP])?(thispars->pars[P_VIRT_WIDTH]):0;
00927   switch(styp)  {
00928     case MT9P_TYP: //page 16
00929       width = 2 * ww / (2 * dh);
00930       if((width * dh) < ww) width++;
00931       switch(thispars->pars[P_BIN_VERT]) {
00932          case 2:
00933             switch(thispars->pars[P_BIN_HOR]) {
00934                case 1: binning_cost = 276;    break;
00935                case 2: binning_cost = 236;    break;
00936                case 4: binning_cost = 236;    break;
00937                break;
00938             }
00939             break;
00940          case 4:
00941             switch(thispars->pars[P_BIN_HOR]) {
00942                case 1: binning_cost = 826;    break;
00943                case 2: binning_cost = 826;    break;
00944                case 4: binning_cost = 826;    break;
00945                break;
00946             }
00947             break;
00948       }
00949       hor_blank_min = 208 * thispars->pars[P_BIN_VERT] + 64 + (312 + 44 + binning_cost) / 2;
00950   MDF4(printk("hor_blank_min =%d(0x%x)\n",hor_blank_min,hor_blank_min));
00951       hor_blank = hor_blank_min;
00952   MDF4(printk("hor_blank =%d(0x%x)\n",hor_blank,hor_blank));
00953       row_time_in_pixels = width + hor_blank * 2;
00954   MDF4(printk("row_time_in_pixels =%d(0x%x)\n",row_time_in_pixels,row_time_in_pixels));
00955       int i = 2 * (41 + 208 * thispars->pars[P_BIN_VERT] + 99); 
00956      if(i > row_time_in_pixels)  row_time_in_pixels = i;
00957   MDF4(printk("row_time_in_pixels =%d(0x%x)\n",row_time_in_pixels,row_time_in_pixels));
00958       if(target_virt_width > row_time_in_pixels) { 
00959          hor_blank = (target_virt_width - width) / 2;
00960          if(hor_blank > sensor->maxHorBlank) hor_blank = sensor->maxHorBlank;
00961          row_time_in_pixels = width + 2 * hor_blank;
00962   MDF4(printk("row_time_in_pixels =%d(0x%x)\n",row_time_in_pixels,row_time_in_pixels));
00963       }
00964       break;
00965     case MT9T_TYP:
00966       width = 2 * ww / (2 * dh);
00967       if((width * dh) < ww) width++;
00968       switch(thispars->pars[P_BIN_VERT]) {
00969          case 1:  p1 = 331; break;
00970          case 2:  p1 = 673; break;
00971          case 3:  p1 = 999; break;
00972          default: p1 = 999; break; //undocumented
00973       }
00974       switch(thispars->pars[P_BIN_HOR]) {
00975          case 1:  p2 = 38; break;
00976          case 2:  p2 = 22; break;
00977          case 3:  p2 = 14; break;
00978          default: p2 = 38; break; //undocumented
00979       }
00980       hor_blank = sensor->minHorBlank;
00981       row_time_in_pixels = width + p1 + p2 + hor_blank;
00982       if(target_virt_width > row_time_in_pixels) { 
00983          hor_blank = target_virt_width - width - p1 - p2;
00984          if(hor_blank > sensor->maxHorBlank) hor_blank = sensor->maxHorBlank;
00985          row_time_in_pixels = width + p1 + p2 + hor_blank;
00986       }
00987       hor_blank--; 
00988       break;
00989     case MT9D_TYP:
00990       width = 2 * ((ww - 1) / (2 * dh)) + 2; 
00991       hor_blank = sensor->minHorBlank;
00992       p1 = 322;
00993       p2 = 2 - 19; //excluded hor_blank
00994       row_time_in_pixels = width + p1 + p2 + hor_blank;
00995       i = p1 + 295;
00996       if(i > row_time_in_pixels)    row_time_in_pixels = i;
00997       if(target_virt_width > row_time_in_pixels) { 
00998          hor_blank = target_virt_width - width - p1 - p2;
00999          if (hor_blank > sensor->maxHorBlank) hor_blank = sensor->maxHorBlank;
01000          row_time_in_pixels = width + p1 + p2 + hor_blank;
01001       }
01002       break;
01003     case MT9M_TYP:
01004       width = 2 * ((ww - 1) / (2 * dh)) + 2; 
01005       hor_blank = sensor->minHorBlank;
01006       p1 = 242;
01007       p2 = 2 - 19; //excluded hor_blank
01008       row_time_in_pixels= width + p1 + p2 + hor_blank;
01009       if(target_virt_width > row_time_in_pixels) { 
01010          hor_blank = target_virt_width - width - p1 - p2;
01011          if(hor_blank > sensor->maxHorBlank) hor_blank = sensor->maxHorBlank;
01012          row_time_in_pixels = width + p1 + p2 + hor_blank;
01013       }
01014       break;
01015   }
01017   MDF4(printk("row_time_in_pixels =%d(0x%x), thispars->pars[P_VIRT_WIDTH ]=%d(0x%x)\n",row_time_in_pixels,row_time_in_pixels,(int)thispars->pars[P_VIRT_WIDTH ],(int)thispars->pars[P_VIRT_WIDTH ]));
01018   if (thispars->pars[P_VIRT_WIDTH ] != row_time_in_pixels) {
01019     SETFRAMEPARS_SET(P_VIRT_WIDTH, row_time_in_pixels);
01020   }
01022   if (hor_blank != thispars->pars[P_SENSOR_REGS+P_MT9X001_HORBLANK]) {
01023   MDF4(printk("hor_blank =%d(0x%x), thispars->pars[P_SENSOR_REGS+P_MT9X001_HORBLANK]=%d(0x%x)\n",hor_blank,hor_blank,(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_HORBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_HORBLANK]));
01024      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_HORBLANK, hor_blank);
01025      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_HORBLANK, hor_blank);
01026      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_HORBLANK, (int)hor_blank));
01027   }
01029 
01030 //   int vh, vb, wh, h, dv, sclk, row_time_in_pixels, ve, e, i;
01032 
01033 
01034   int dv = thispars->pars[P_DCM_VERT];
01035   int wh = thispars->pars[P_SENSOR_REGS+P_MT9X001_HEIGHT] + 1;
01036 
01037   int height = 2 * (wh / (2 * dv));
01038   if((height * dv) < wh) height++;
01039   int virt_height = height + sensor->minVertBlank;
01040   if (thispars->pars[P_VIRT_KEEP]) {
01041     if (virt_height < thispars->pars[P_VIRT_HEIGHT]) {
01042       virt_height = thispars->pars[P_VIRT_HEIGHT];
01043     }
01044   }
01045 
01046   MDF4(printk("height =%d(0x%x), virt_height=%d(0x%x)\n",height,height,virt_height,virt_height));
01048   if ((thispars->pars[P_TRIG] & 4) ==0) {
01049     int virt_height1= thispars->pars[P_PERIOD_MIN]/row_time_in_pixels; // always non-zero, calculated by pgm_limitfps (common)
01050     if ((row_time_in_pixels * virt_height1) < thispars->pars[P_PERIOD_MIN]) virt_height1++; //round up
01051     if (virt_height < virt_height1) virt_height = virt_height1;
01052   MDF4(printk("height =%d(0x%x), virt_height=%d(0x%x)\n",height,height,virt_height,virt_height));
01053   }
01054 
01055   int vert_blank= virt_height - height; 
01056   if(vert_blank > sensor->maxVertBlank) {
01057       vert_blank = sensor->maxVertBlank;
01058       virt_height = vert_blank + height;
01059   }
01060   MDF4(printk("vert_blank =%d(0x%x), virt_height=%d(0x%x)\n",vert_blank,vert_blank,virt_height,virt_height));
01061 
01063   MDF4(printk("thispars->pars[P_VIRT_HEIGHT ] =%d(0x%x), virt_height=%d(0x%x)\n",(int)thispars->pars[P_VIRT_HEIGHT ],(int)thispars->pars[P_VIRT_HEIGHT ],virt_height,virt_height));
01064   if (thispars->pars[P_VIRT_HEIGHT ] != virt_height) {
01065     SETFRAMEPARS_SET(P_VIRT_HEIGHT, virt_height);
01066   }
01068   pix_period=row_time_in_pixels*virt_height;
01069   MDF4(printk("thispars->pars[P_PERIOD] =%d(0x%x), pix_period=%d(0x%x)\n",(int)thispars->pars[P_PERIOD],(int)thispars->pars[P_PERIOD],pix_period,pix_period));
01070   if (thispars->pars[P_PERIOD] != pix_period) {
01071     SETFRAMEPARS_SET(P_PERIOD, pix_period);
01072   }
01074   sclk=thispars->pars[P_CLK_SENSOR] ; 
01075 #if USELONGLONG
01076   ull_fp1000s=((long long) 1000)* ((long long) sclk);
01077   __div64_32(&ull_fp1000s,pix_period);
01078   fp1000s= ull_fp1000s;
01079 //  fp1000s= ((long long) 1000)* ((long long)sclk) /pix_period;
01080 #else
01081   fp1000s= 10*sclk/(pix_period/100);
01082 #endif
01083   MDF4(printk("thispars->pars[P_FP1000S] =%d(0x%x), fp1000s=%d(0x%x)\n",(int)thispars->pars[P_FP1000S],(int)thispars->pars[P_FP1000S],fp1000s,fp1000s));
01084   if (thispars->pars[P_FP1000S] != fp1000s) {
01085     SETFRAMEPARS_SET(P_FP1000S, fp1000s);
01086   }
01088   MDF4(printk("thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK] =%d(0x%x), vert_blank=%d(0x%x)\n",(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],vert_blank,vert_blank));
01089   if (vert_blank != thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK]) {
01090     SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_VERTBLANK, vert_blank);
01091     X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_VERTBLANK, vert_blank);
01092     MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_VERTBLANK, (int) vert_blank));
01093   }
01094   if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
01095   return 0;
01096 }
01097 
01106 int mt9x001_pgm_exposure   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
01107 #if USELONGLONG
01108   uint64_t ull_fp1000s;
01109   uint64_t ull_exposure;
01110   uint64_t ull_video_exposure;
01111 #endif
01112   int fp1000s;
01113   struct frameparspair_t pars_to_update[10]; 
01114   int nupdate=0;
01115   if (frame8 >= PARS_FRAMES) return -1; 
01116   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
01117 //  MDF1(printk(" fpga_addr=0x%x\n",(int) fpga_addr)); //0x58
01118   int video_exposure =  thispars->pars[P_VEXPOS];
01119 //  MDF1(printk(" video_exposure=0x%x\n",(int) video_exposure)); /// 0x00
01120   int exposure;
01121   MDF4(printk(" frame8=%d, frame=0x%lx (%s)exposure=0x%lx, (%s)video_exposure=0x%lx\n",frame8, thispars->pars[P_FRAME], FRAMEPAR_MODIFIED(P_EXPOS)?"*":" ",thispars->pars[P_EXPOS],FRAMEPAR_MODIFIED(P_VEXPOS)?"*":" ",thispars->pars[P_VEXPOS] ));
01122   int use_vexp=0;
01123   int sclk=thispars->pars[P_CLK_SENSOR] ; 
01124 //  MDF1(printk(" sclk=0x%x\n",(int) sclk)); ///  5b8d800 correct
01125   int styp = sensor->sensorType & 7;
01126 //  MDF1(printk(" styp=0x%x\n",styp)); /// 0x4
01127 
01129   int row_time_in_pixels=thispars->pars[P_VIRT_WIDTH ];
01130   MDF1(printk(" row_time_in_pixels=0x%x\n", row_time_in_pixels)); 
01131 
01132   MDF1(printk(" vert_blank=0x%x\n",vert_blank)); 
01133 
01134   if ((video_exposure>0) && (FRAMEPAR_MODIFIED(P_VEXPOS) || ! (FRAMEPAR_MODIFIED(P_EXPOS) || FRAMEPAR_MODIFIED(P_VIRT_WIDTH)) )) { 
01135   MDF1(printk(" exposure=%d (0x%x), video_exposure=%d (0x%x)\n", (int) thispars->pars[P_VEXPOS], (int) thispars->pars[P_VEXPOS], (int) video_exposure, (int) video_exposure));
01136 #if USELONGLONG
01137   ull_exposure= ((long long)(video_exposure * row_time_in_pixels)) * ((long long) 1000000);
01138   __div64_32(&ull_exposure, sclk);
01139   exposure= ull_exposure;
01140 #else
01141      exposure = (100*video_exposure * row_time_in_pixels) / (sclk/10000); 
01142 #endif
01143      use_vexp=1;
01144   } else { 
01145     exposure = thispars->pars[P_EXPOS];
01146 #if USELONGLONG
01147   ull_video_exposure= (long long) exposure  * (long long) sclk;
01148   __div64_32(&ull_video_exposure, row_time_in_pixels);
01149   __div64_32(&ull_video_exposure, 1000000);
01150   video_exposure= ull_video_exposure;
01151 #else
01153      if (exposure<10000) { 
01154         video_exposure = ( exposure        * (sclk/1000))/ (row_time_in_pixels*1000);
01155      } else if (exposure<100000) { 
01156         video_exposure = ( (exposure/10)   * (sclk/1000))/ (row_time_in_pixels * 100);
01157      } else if (exposure<1000000) { 
01158         video_exposure = ( (exposure/100)  * (sclk/1000))/ (row_time_in_pixels * 10);
01159      } else {
01160         video_exposure = ( (exposure/1000) * (sclk/1000))/ (row_time_in_pixels );
01161      }
01162 #endif
01163   }
01164   if (exposure <1)       exposure=1;
01165   if (video_exposure <1) video_exposure=1;
01166 
01168   if (video_exposure  > sensor->maxShutter) {
01169      video_exposure=sensor->maxShutter;
01170 #if USELONGLONG
01171   ull_exposure= ((long long)(video_exposure * row_time_in_pixels)) *((long long) 1000000);
01172   __div64_32(&ull_exposure, sclk);
01173   exposure= ull_exposure;
01174 #else
01175      exposure = (100*video_exposure * row_time_in_pixels) / (sclk/10000); 
01176 #endif
01177   }
01178 
01180   int pix_period=video_exposure*row_time_in_pixels;
01181   if (thispars->pars[P_FPSFLAGS] & 2) {
01182     if (pix_period > thispars->pars[P_PERIOD_MAX]) {
01183       video_exposure=thispars->pars[P_PERIOD_MAX]/row_time_in_pixels;
01184 #if USELONGLONG
01185       ull_exposure= (((long long) thispars->pars[P_PERIOD_MAX]) *((long long)  1000000));
01186       __div64_32(&ull_exposure, sclk);
01187       exposure= ull_exposure;
01188 #else
01189       exposure = (thispars->pars[P_PERIOD_MAX] * 100) / (sclk/10000); 
01190 #endif
01191     }
01192   } else { 
01193 
01194 
01195 
01196 
01197     if (pix_period > thispars->pars[P_PERIOD]) {
01198         SETFRAMEPARS_SET(P_PERIOD, pix_period);
01199 #if 0
01200       if (vert_blank != thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK]) {
01201         SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_VERTBLANK, vert_blank);
01202       }
01203 #endif
01205 #if USELONGLONG
01206       ull_fp1000s=((long long) 1000)* ((long long) sclk);
01207       __div64_32(&ull_fp1000s,pix_period);
01208       fp1000s= ull_fp1000s;
01209 #else
01210       fp1000s= 10*sclk/(pix_period/100);
01211 #endif
01212       D1(printk(" fp1000s=%d (0x%x)", (int) fp1000s, (int) fp1000s));
01213 
01214       if (thispars->pars[P_FP1000S] != fp1000s) {
01215         SETFRAMEPARS_SET(P_FP1000S, fp1000s);
01216       }
01217     }
01218   }
01219 //  MDF1(printk(" exposure=0x%x, video_exposure\n", (int) exposure, (int) video_exposure,));
01221   if (thispars->pars[P_VEXPOS] != video_exposure) {
01222      SETFRAMEPARS_SET(P_VEXPOS, video_exposure);
01223   }
01225   if (thispars->pars[P_EXPOS] != exposure) {
01226      SETFRAMEPARS_SET(P_EXPOS, exposure);
01227   }
01231   if (((styp == MT9T_TYP) || (styp == MT9P_TYP)) && ((video_exposure >> 16) != thispars->pars[P_SENSOR_REGS+P_MT9X001_SHTRWDTHU])) {
01232      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_SHTRWDTHU, video_exposure >> 16);
01233      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_SHTRWDTHU, video_exposure >> 16);
01234      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_SHTRWDTHU, (int) (video_exposure >> 16)));
01235   }
01237   if ((video_exposure & 0xffff) != thispars->pars[P_SENSOR_REGS+P_MT9X001_SHTRWDTH]) {
01238      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_SHTRWDTH, video_exposure  & 0xffff);
01239      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_SHTRWDTH, video_exposure & 0xffff);
01240      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int)  P_MT9X001_SHTRWDTH, (int) (video_exposure & 0xffff)));
01241   }
01242 //  MDF1(printk(" nupdate=0x%x\n", (int) nupdate));
01243   if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
01244   MDF1(printk(" exposure=%d (0x%x), video_exposure=%d (0x%x) OK!\n", (int) exposure, (int) exposure, (int) video_exposure, (int) video_exposure));
01245   return 0;
01246 }
01247 
01255 inline int gain_mt9x001(int g, int maxGain256) {
01256    if(g > maxGain256)
01257       g = maxGain256;
01258    if(g <= 0x3f0)
01259       g=  (g+0x10) >> 5;
01260    else 
01261       g = ((g+ 0X20) >> 6) + 0x40;
01262    return g;
01263 }
01287 int mt9x001_pgm_gains      (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
01288   struct frameparspair_t pars_to_update[9];
01289   int nupdate=0;
01290   MDF4(printk(" frame8=%d\n",frame8));
01291   if (frame8 >= PARS_FRAMES) return -1; 
01292   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
01293   int g;
01294    g  = gain_mt9x001(thispars->pars[P_GAINR ], sensor->maxGain256); 
01295    if (g != thispars->pars[P_SENSOR_REGS+P_MT9X001_RED]) {
01296      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_RED, g);
01297      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RED, g);
01298      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_RED, (int) g));
01299    }
01300    g=((((g>>6) & 1)+1)*(g & 0x3f))<<5; 
01301    if (thispars->pars[P_GAINR ] != g) {
01302      SETFRAMEPARS_SET(P_GAINR, g);
01303    }
01304 
01305    g  = gain_mt9x001(thispars->pars[P_GAING ],sensor->maxGain256);
01306    if (g != thispars->pars[P_SENSOR_REGS+P_MT9X001_GREEN1]) {
01307      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_GREEN1, g);
01308      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_GREEN1, g);
01309      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_GREEN1, (int) g));
01310    }
01311    g=((((g>>6) & 1)+1)*(g & 0x3f))<<5; 
01312    if (thispars->pars[P_GAING ] != g) {
01313      SETFRAMEPARS_SET(P_GAING, g);
01314    }
01315 
01316    g  = gain_mt9x001(thispars->pars[P_GAINB ],sensor->maxGain256);
01317    if (g != thispars->pars[P_SENSOR_REGS+P_MT9X001_BLUE]) {
01318      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_BLUE, g);
01319      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_BLUE, g);
01320      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_BLUE, (int) g));
01321    }
01322    g=((((g>>6) & 1)+1)*(g & 0x3f))<<5; 
01323    if (thispars->pars[P_GAINB ] != g) {
01324      SETFRAMEPARS_SET(P_GAINB, g);
01325    }
01326    g  = gain_mt9x001(thispars->pars[P_GAINGB ], sensor->maxGain256);
01327    if (g != thispars->pars[P_SENSOR_REGS+P_MT9X001_GREEN2]) {
01328      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_GREEN2, g);
01329      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_GREEN2, g);
01330      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_GREEN2, (int) g));
01331    }
01332    g=((((g>>6) & 1)+1)*(g & 0x3f))<<5; 
01333    if (thispars->pars[P_GAINGB ] != g) {
01334      SETFRAMEPARS_SET(P_GAINGB, g);
01335    }
01337    g= thispars->pars[P_TESTSENSOR ];
01338    g= (g & 0x10000)? (((g & 0xf) << 3) | 1) : 0;
01339    if (g != thispars->pars[P_SENSOR_REGS+P_MT9X001_TEST]) {
01340      SETFRAMEPARS_SET(P_SENSOR_REGS+P_MT9X001_TEST, g);
01341      X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_TEST, g);
01342      MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_TEST, (int) g));
01343 
01344    }
01345    if (nupdate)  setFramePars(thispars, nupdate, pars_to_update);  
01346   return 0;
01347 }
01348 #if 0
01349 #define P_TESTSENSOR    44 // sensor test mode(s) 0x10000 - enable, lower bits - test mode
01350 
01351 #define P_MT9X001_TEST     0xa0  
01352 
01369 #endif
01370 
01371 
01372 
01373 
01382 int mt9x001_pgm_triggermode(struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
01383   MDF4(printk(" frame8=%d\n",frame8));
01384   if (frame8 >= PARS_FRAMES) return -1; 
01385   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
01386   unsigned long newreg= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xfeff) | ((thispars->pars[P_TRIG] & 4)?0x100:0);
01387   if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) {
01388     X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr, P_MT9X001_RMODE1, newreg);
01389     MDF4(printk("  X3X3_I2C_SEND2(0x%x,0x%x, 0x%x, 0x%x)\n", fpga_addr,  (int) sensor->i2c_addr, (int) P_MT9X001_RMODE1, (int) newreg));
01390     setFramePar(thispars, P_SENSOR_REGS+P_MT9X001_RMODE1, newreg); 
01391   }
01392   return 0;
01393 }
01394 
01405 int mt9x001_pgm_sensorregs   (struct sensor_t * sensor,  struct framepars_t * thispars, struct framepars_t * prevpars, int frame8) {
01406   MDF4(printk(" frame8=%d\n",frame8));
01407   if (frame8 >= PARS_FRAMES) return -1; 
01408   int fpga_addr=(frame8 <0) ? X313_I2C_ASAP : (X313_I2C_FRAME0+frame8);
01411 //  unsigned long bmask32= ((thispars->mod32) >> (P_SENSOR_REGS>>5)) & (P_SENSOR_NUMREGS-1) ;
01414 
01415   unsigned long bmask32= ((thispars->mod32) >> (P_SENSOR_REGS>>5)) & (P_SENSOR_NUMREGS-1) ;
01416 
01417   MDF4(printk(" bmask32=0x%lx, thispars->mod32=0x%lx, P_SENSOR_REGS=0x%x, P_SENSOR_NUMREGS=0x%x\n",bmask32,thispars->mod32,P_SENSOR_REGS,P_SENSOR_NUMREGS));
01418   unsigned long mask;
01419   int index,index32;
01420   if (bmask32) {
01421     for (index32=(P_SENSOR_REGS>>5); bmask32; index32++, bmask32 >>= 1) {
01422        MDF4(printk(" index32=0x%x, bmask32=0x%lx\n",index32,bmask32));
01423        if (bmask32 & 1) {
01424          mask=thispars->mod[index32];
01425          MDF4(printk(" mask=0x%lx\n",mask));
01426          for (index=(index32<<5); mask; index++, mask >>= 1) {
01427            if (mask & 1) {
01428              X3X3_I2C_SEND2(fpga_addr,sensor->i2c_addr,(index-P_SENSOR_REGS),thispars->pars[index]);
01429              MDF4(printk("X3X3_I2C_SEND2(0x%x,0x%lx,0x%x,0x%lx)\n",fpga_addr,sensor->i2c_addr,(index-P_SENSOR_REGS),thispars->pars[index]));
01430            }
01431          }
01432          thispars->mod[index32]=0;
01433        }
01434     }
01435     thispars->mod32=0;
01436   } 
01437   return 0;
01438 } 
01439 
01440 

Generated on Fri Nov 28 00:06:23 2008 for elphel by  doxygen 1.5.1