#include <linux/types.h>
#include <asm/div64.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/autoconf.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/elphel/c313a.h>
#include "fpgactrl.h"
#include "x3x3.h"
#include "cci2c.h"
#include "mt9x001.h"
#include "framepars.h"
#include "sensor_common.h"
#include "pgm_functions.h"
Include dependency graph for mt9x001.c:
Go to the source code of this file.
Defines | |
#define | MDF4(x) |
#define | ELPHEL_DEBUG_THIS 0 |
#define | MDF1(x) |
#define | MDD1(x) |
#define | D(x) |
#define | D1(x) |
#define | MD7(x) |
#define | MD9(x) |
#define | I2C_READ_DATA16(x) ((i2c_read_data[(x)<<1]<<8)+i2c_read_data[((x)<<1)+1]) |
read 2 bytes from i2c | |
Functions | |
int | mt9x001_pgm_detectsensor (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
detect and initialize sensor and related data structures
| |
int | mt9x001_pgm_initsensor (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
reset and init sensor resets sensor, reads sensor registers, schedules "secret" manufacturer's corrections to the registers (stops/re-enables hardware i2c) i2c is supposed to be already programmed | |
int | mt9x001_pgm_window (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
program sensor WOI and mirroring Only validating, changing related parameters/scheduling actions, no hardwaer programming here | |
int | mt9x001_pgm_window_safe (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
int | mt9x001_pgm_window_common (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
int | mt9x001_pgm_limitfps (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
check if compressor can keep up, limit sensor FPS if needed FPS is limited by increasing verical blanking, it can not be be made too big, so this method does not work to make time lapse rate. horisontal blanking is kept at minimum (to reduce ERS effect) if not specified. If it is specified (>minimal) - it will be used instead. calculate line period. | |
int | mt9x001_pgm_exposure (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
program sensor exposure - nothing to be done here, all sensor-specific | |
int | mt9x001_pgm_gains (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
program analog gains program analog gains TODO: Make separate read-only P_ACTUAL_GAIN** ? apply sensor-specific restrictions on the allowed gain values includes sensor test mode on/off/selection | |
int | mt9x001_pgm_triggermode (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
program trigger mode as sensor-specific | |
int | mt9x001_pgm_sensorregs (struct sensor_t *sensor, struct framepars_t *thispars, struct framepars_t *prevpars, int frame8) |
program sensor registers (probably just those that are manually set) NOTE: all modes but ASAP are limited to 64 registers/frame, no overflow checks are performed! | |
int | gain_mt9x001 (int g, int maxGain256) |
calculates hardware specific analog gains | |
Variables | |
sensor_t | mt9m001 |
sensor_t | mt9d001 |
sensor_t | mt9t001 |
sensor_t | mt9p001 |
static unsigned short | mt9m001_inits [] |
a place to add some general purpose register writes to sensors during init | |
static unsigned short | mt9d001_inits [] |
static unsigned short | mt9t001_inits [] |
static unsigned short | mt9p001_inits [] |
read 2 bytes from i2c
Definition at line 545 of file mt9x001.c.
Referenced by mt9x001_pgm_detectsensor(), and mt9x001_pgm_initsensor().
int gain_mt9x001 | ( | int | g, | |
int | maxGain256 | |||
) | [inline] |
calculates hardware specific analog gains
g | gain value (integer, 256 for unity gain) | |
maxGain256 | maximal supported gain (integer, 256 for unity gain) |
Definition at line 1255 of file mt9x001.c.
Referenced by mt9x001_pgm_gains().
int mt9x001_pgm_detectsensor | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
detect and initialize sensor and related data structures
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to. Only -1 (ASAP) is allowed here |
this function uses software i2c operations - they need to have interrupts (and hardware i2c off)
each two bytes - one short word, big endian
current sensor
already initialized - calle second time after common pgm_detectsensor(), first time is inside pgm_detectsensor()
set control lines
set negative MRST polarity
try MT9P001 first
IRQ Off
no stop before read (cxi2c.c)
restart, not strart (cxi2c.c)
IRQ restore
IRQ Off
IRQ restore
if(d[2] == 0x01) - MT9T001 chip rev 01 - color gains had a bug
no sensor found
Sensor recognized, go on
copy sensor definitions
detect sensor type, sets sensor structure (capabilities), function pointers NOTE: will be called directly, not through pointers
resets sensor, reads sensor registers, schedules "secret" manufacturer's corrections to the registers (stops/re-enables hardware i2c)
program exposure
program sensor WOI and mirroring (flipping)
program sensor WOI and mirroring (flipping) - now - only flipping? with lower latency
check compressor will keep up, limit sensor FPS if needed
program analog gains
program sensor trigger mode
write sensor registers (only changed from outside the driver as they may have different latencies)?
NOTE: hardware i2c is turned off
Definition at line 565 of file mt9x001.c.
References add_sensor_proc(), CCAM_ARST_OFF, CCAM_MRST_OFF, CCAM_NEGRST, CCAM_TRIG_INT, flags, sensor_t::i2c_addr, I2C_READ_DATA16, i2c_readData(), i2c_writeData(), local_irq_restore, local_irq_save, MDF1, MDF4, memcpy(), mt9d001, MT9D001_PARTID, MT9D_TYP, mt9m001, MT9M001_PARTID, MT9M_TYP, mt9p001, MT9P001_PARTID, MT9P_TYP, mt9t001, MT9T001_PARTID, MT9T_TYP, MT9X001_PARTIDMASK, mt9x001_pgm_exposure(), mt9x001_pgm_gains(), mt9x001_pgm_initsensor(), mt9x001_pgm_limitfps(), mt9x001_pgm_sensorregs(), mt9x001_pgm_triggermode(), mt9x001_pgm_window(), mt9x001_pgm_window_safe(), onchange_detectsensor, onchange_exposure, onchange_gains, onchange_initsensor, onchange_limitfps, onchange_sensorregs, onchange_triggermode, onchange_window, onchange_window_safe, P_MT9X001_CHIPVER, P_SENSOR, framepars_t::pars, printk, sensor, setFramePar(), udelay, and X3X3_I2C_STOP_WAIT.
Referenced by pgm_detectsensor().
int mt9x001_pgm_exposure | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
program sensor exposure - nothing to be done here, all sensor-specific
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to (or "-1" - ASAP) |
maximum 7? registers updated
wrong frame
pixel clock, in Hz
NOTE: Is decimation taken care of here ??? FIXME: probably not (here and when deciding to use exposure, not number of lines)!!!
0
int vert_blank= thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK ];
0
if video exposure is non-zero, P_VEXPOS is marked as modified or P_EXPOS is not modified - use video exposure (lines), else - absolute exposure (usec)
use number of lines
in microseconds
use time in microseconds
TODO - use shifts, not division where possible?
<0.01 sec
0.1 sec
1.0 sec
is video exposure longer than maximal for the sensor?
in microseconds
is exposure longer then maximal period (specified for constant fps?
in microseconds
no limit on maximal period
is exposure increasing period (not limited by ([P_FPSFLAGS] & 2) ? In theta case P_PERIOD and P_FP1000S will need to be updated schedule updating P_PERIOD if it changed TODO: Check duplicate vert_blank calculation (mt9x001_pgm_limitfps)
schedule updating P_FP1000S if it changed
is video exposure P_VEXPOS modified?
is exposure P_EXPOS modified?
Now sensor registers schedule updating P_MT9X001_VERTBLANK senosr register and shadow high word of shutter width (>=3MPix)
low word of shutter width (all sensors)
save changes to gains and sensor register shadows
Definition at line 1106 of file mt9x001.c.
References FRAMEPAR_MODIFIED, MDF1, MDF4, P_CLK_SENSOR, P_EXPOS, P_FRAME, P_VEXPOS, P_VIRT_WIDTH, framepars_t::pars, PARS_FRAMES, printk, sclk, sensor, X313_I2C_ASAP, and X313_I2C_FRAME0.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_gains | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
program analog gains program analog gains TODO: Make separate read-only P_ACTUAL_GAIN** ? apply sensor-specific restrictions on the allowed gain values includes sensor test mode on/off/selection
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to (or "-1" - ASAP) |
wrong frame
gain 8.8 -> sensor register
register -> gain 8.8
gain 8.8 -> sensor register
register -> gain 8.8
gain 8.8 -> sensor register
register -> gain 8.8
gain 8.8 -> sensor register
register -> gain 8.8
test mode off/on/select
(on?0x10000:0) | (Micron_tests_mode) 0x0 - off, 0x10000..0x1000F
save changes to gains and sensor register shadows
Definition at line 1287 of file mt9x001.c.
References gain_mt9x001(), MDF4, P_GAINB, P_GAING, P_GAINGB, P_GAINR, P_MT9X001_BLUE, P_MT9X001_GREEN1, P_MT9X001_GREEN2, P_MT9X001_RED, P_MT9X001_TEST, P_SENSOR_REGS, P_TESTSENSOR, framepars_t::pars, PARS_FRAMES, printk, sensor, setFramePars(), SETFRAMEPARS_SET, X313_I2C_ASAP, X313_I2C_FRAME0, and X3X3_I2C_SEND2.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_initsensor | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
reset and init sensor resets sensor, reads sensor registers, schedules "secret" manufacturer's corrections to the registers (stops/re-enables hardware i2c) i2c is supposed to be already programmed
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to (or "-1" - ASAP) |
should be ASAP
this function uses software i2c operations - they need to have interrupts (and hardware i2c off)
for all the sensor registers. Other P_* values will reuse the same ones
each two bytes - one short word, big endian
reset sensor by applying MRST (low):
IRQ Off (rather long - all 256 registers through i2c, but there is no hurry - sensor is off)
data (register #) is 0. no stop before read (cxi2c.c)
read all 256 registers (512 bytes) restart, not strart (cxi2c.c)
IRQ restore
save these registers as shadows and propagate
possible to modify register range to save (that is why nupdate is separate from i)
save changes to sensor register shadows
why casting is needed?
enable hardware i2c - NOTE: the only place where the i2c controller is enabled.
IRQ Off, so both sequencers to be started at the same time
IRQ restore
Second pass over the registers to set
unconditionally set those registers NOTE: Should be < 63 of them!
save changes to sensor register shadows
Definition at line 654 of file mt9x001.c.
References CCAM_MRST_OFF, CCAM_MRST_ON, flags, I2C_READ_DATA16, i2c_readData(), i2c_writeData(), local_irq_restore, local_irq_save, MDF4, mt9d001_inits, MT9D_TYP, mt9m001_inits, MT9M_TYP, mt9p001_inits, MT9P_TYP, mt9t001_inits, MT9T_TYP, P_SENSOR_REGS, printk, sensor, SENSOR_MT9X001, setFramePars(), SETFRAMEPARS_SET, udelay, X313_I2C_ASAP, X313_I2C_FRAME0, X3X3_I2C_RUN, X3X3_I2C_SEND2, X3X3_I2C_STOP_WAIT, and X3X3_SEQ_RUN.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_limitfps | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
check if compressor can keep up, limit sensor FPS if needed FPS is limited by increasing verical blanking, it can not be be made too big, so this method does not work to make time lapse rate. horisontal blanking is kept at minimum (to reduce ERS effect) if not specified. If it is specified (>minimal) - it will be used instead. calculate line period.
FIXME - uses P_VIRTUAL_WIDTH w/o decreasing it when changing image size? Replace VIRT_WIDTH with HOR_BANK? Or require always set them to zero when chnaging WOI?
maximum 7 registers updated (need to recount)
wrong frame
strange 41 and 99, why not 140?
extend line by adding horizontal blanking
extend line by adding horizontal blanking
confusing - for mt9p001 (not others which refer reg[0x05]) :"HB Horizontal Blanking Horizontal_Blank+1"
docs, p.6
extend line by adding horizontal blanking
docs, p.6
extend line by adding horizontal blanking
schedule updating P_VIRT_WIDTH if it changed FIXME: Does not come here?
schedule updating P_MT9X001_HORBLANK senosr register and shadow FIXME: Seems hor_blank is too high. is the width itself subtracted?
Now calculate P_PERIOD (extending it as needed)
calculate minimal virtual heigth for current window height
limit frame rate (using minimal period), but only in sync mode - async should be programmed to observe minimal period
schedule updating P_VIRT_HEIGHT if it changed
schedule updating P_PERIOD if it changed
schedule updating P_FP1000S if it changed
pixel clock, in Hz
schedule updating P_MT9X001_VERTBLANK sensor register and shadow
save changes to gains and sensor register shadows
Definition at line 908 of file mt9x001.c.
References dh, dv, height, MDF4, MT9D_TYP, MT9M_TYP, MT9P_TYP, MT9T_TYP, P_BIN_HOR, P_BIN_VERT, P_CLK_SENSOR, P_DCM_HOR, P_DCM_VERT, P_FP1000S, P_MT9X001_HEIGHT, P_MT9X001_HORBLANK, P_MT9X001_VERTBLANK, P_PERIOD, P_PERIOD_MIN, P_SENSOR_PIXH, P_SENSOR_REGS, P_TRIG, P_VIRT_HEIGHT, P_VIRT_KEEP, P_VIRT_WIDTH, framepars_t::pars, PARS_FRAMES, printk, sclk, sensor, setFramePars(), SETFRAMEPARS_SET, wh, width, ww, X313_I2C_ASAP, X313_I2C_FRAME0, and X3X3_I2C_SEND2.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_sensorregs | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
program sensor registers (probably just those that are manually set) NOTE: all modes but ASAP are limited to 64 registers/frame, no overflow checks are performed!
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to (or "-1" - ASAP) |
wrong frame
send all parameters marked as "needed to be processed" to the sensor, clear those flags mask out all non sensor pars
It will be the first for the frame (before automatic sensor changes). Add testing for programmed sensor and move vbalues to later frames (not here butin the pgm_functions)
Definition at line 1405 of file mt9x001.c.
References mask, MDF4, framepars_t::mod, framepars_t::mod32, P_SENSOR_NUMREGS, P_SENSOR_REGS, framepars_t::pars, PARS_FRAMES, printk, sensor, X313_I2C_ASAP, X313_I2C_FRAME0, and X3X3_I2C_SEND2.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_triggermode | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
program trigger mode as sensor-specific
sensor | pointer to sensor static parameters (capabilities) | |
thispars | pointer to sensor current parameters | |
prevpars | pointer to sensor previous parameters (not used here) | |
frame8 | short (hardware) frame number parameters should be applied to (or "-1" - ASAP) |
wrong frame
Definition at line 1382 of file mt9x001.c.
References MDF4, P_MT9X001_RMODE1, P_SENSOR_REGS, P_TRIG, framepars_t::pars, PARS_FRAMES, printk, sensor, setFramePar(), X313_I2C_ASAP, X313_I2C_FRAME0, and X3X3_I2C_SEND2.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_window | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
program sensor WOI and mirroring Only validating, changing related parameters/scheduling actions, no hardwaer programming here
As different sensors may produce "bad frames" for differnt WOI changes (i.e. MT9P001 seems to do fine with FLIP, but not WOI_WIDTH) pgm_window and pgm_window_safe will do the same - they will just be called with different latencies and with compressor stopped)
Definition at line 739 of file mt9x001.c.
References MDF4, mt9x001_pgm_window_common(), printk, and sensor.
Referenced by mt9x001_pgm_detectsensor().
int mt9x001_pgm_window_common | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) | [inline] |
Definition at line 749 of file mt9x001.c.
References bh, bv, d, dh, dv, flip, MDF4, MT9P_TYP, MT9T_TYP, P_BIN_HOR, P_BIN_VERT, P_DCM_HOR, P_DCM_VERT, P_FLIPH, P_FLIPV, P_MT9X001_CAM, P_MT9X001_COLSTART, P_MT9X001_HEIGHT, P_MT9X001_RAM, P_MT9X001_RMODE1, P_MT9X001_RMODE2, P_MT9X001_ROWSTART, P_MT9X001_WIDTH, P_OVERSIZE, P_SENSOR_PIXH, P_SENSOR_PIXV, P_SENSOR_REGS, P_WOI_LEFT, P_WOI_TOP, framepars_t::pars, PARS_FRAMES, printk, sensor, setFramePars(), SETFRAMEPARS_SET, wh, wl, wt, ww, X313_I2C_ASAP, X313_I2C_FRAME0, X313_MARGINS, and X3X3_I2C_SEND2.
Referenced by mt9x001_pgm_window(), and mt9x001_pgm_window_safe().
int mt9x001_pgm_window_safe | ( | struct sensor_t * | sensor, | |
struct framepars_t * | thispars, | |||
struct framepars_t * | prevpars, | |||
int | frame8 | |||
) |
Definition at line 743 of file mt9x001.c.
References MDF4, mt9x001_pgm_window_common(), printk, and sensor.
Referenced by mt9x001_pgm_detectsensor().
unsigned short mt9d001_inits[] [static] |
Initial value:
{ P_MT9X001_CALTHRESH , 0xa39d, P_MT9X001_CALCTRL, 0x8498 }
Definition at line 520 of file mt9x001.c.
Referenced by mt9x001_pgm_initsensor().
arch/cris/arch-v32/drivers/elphel/mt9x001.c:1031:mt9x001_pgm_exposure exposure=0x2710 Unable to handle kernel NULL pointer dereference at virtual address 00000000 Oops: 0000
Definition at line 361 of file mt9x001.c.
Referenced by mt9x001_pgm_detectsensor().
unsigned short mt9m001_inits[] [static] |
Initial value:
{ }
Definition at line 517 of file mt9x001.c.
Referenced by mt9x001_pgm_initsensor().
unsigned short mt9p001_inits[] [static] |
Initial value:
{ P_MT9X001_OUTCTRL, 0x2, P_MT9X001_7F , 0x0 }
Definition at line 529 of file mt9x001.c.
Referenced by mt9x001_pgm_initsensor().
unsigned short mt9t001_inits[] [static] |
Initial value:
{ }
Definition at line 525 of file mt9x001.c.
Referenced by mt9x001_pgm_initsensor().