Commit 66ec8f57 authored by Andrey Filippov's avatar Andrey Filippov

merged with framepars

parents 2677b54a cf73e112
...@@ -262,11 +262,14 @@ ...@@ -262,11 +262,14 @@
elphel393_sensor_i2c: elphel393-sensor-i2c@0 { elphel393_sensor_i2c: elphel393-sensor-i2c@0 {
compatible = "elphel,elphel393-sensor-i2c-1.00"; compatible = "elphel,elphel393-sensor-i2c-1.00";
/* Add known devices: name, slave address (7-bit), number of address bytes, number of data bytes, SCL frequency (kHz) */ /* Add known devices: name, slave address (7-bit), number of address bytes, number of data bytes, SCL frequency (kHz) */
elphel393-sensor-i2c,i2c_devices = "mt9f002 0x10 2 2 500", elphel393-sensor-i2c,i2c_devices = "mt9f002 0x10 2 2 500",
"mt9p006 0x48 1 2 500", "mt9p006 0x48 1 2 500",
"el10359 0x08 1 2 500", "el10359 0x08 1 2 500",
"el10359_32 0x08 1 4 500",
"pca9500_eeprom 0x50 1 1 100", "pca9500_eeprom 0x50 1 1 100",
"cy22393 0x69 1 1 100"; "sensor_eeprom 0x50 1 1 100",
"sensor_temp 0x18 1 2 100",
"cy22393 0x69 1 1 100";
} ; } ;
framepars_operations: elphel393-framepars@0 { framepars_operations: elphel393-framepars@0 {
...@@ -285,6 +288,10 @@ ...@@ -285,6 +288,10 @@
compatible = "elphel,elphel393-mt9x001-1.00"; compatible = "elphel,elphel393-mt9x001-1.00";
}; };
elphel393_clock10359:elphel393-clock10359@0{
compatible = "elphel,elphel393_clock10359-1.00";
};
klogger_393: klogger-393@0 { klogger_393: klogger-393@0 {
compatible = "elphel,klogger-393-1.00"; compatible = "elphel,klogger-393-1.00";
klogger-393,buffer_size = <1048576>; klogger-393,buffer_size = <1048576>;
......
...@@ -84,25 +84,25 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz ...@@ -84,25 +84,25 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz
unsigned int fpmx= CY22393_XTAL * (CY22393_PMAX + 6); unsigned int fpmx= CY22393_XTAL * (CY22393_PMAX + 6);
int divmn, divmx, err1,err, div,q,qmn,qmx,qmx1,fdv,p, e,fdvq; int divmn, divmx, err1,err, div,q,qmn,qmx,qmx1,fdv,p, e,fdvq;
pars->rslt=3; // other error pars->rslt=3; // other error
dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\r\n",f0,f,CY22393_OUTMAX); dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\n",f0,f,CY22393_OUTMAX);
f/=CY22393_SCALE; // to fit into 32-bit calculations f/=CY22393_SCALE; // to fit into 32-bit calculations
dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\r\n",f0,f,CY22393_OUTMAX); dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\n",f0,f,CY22393_OUTMAX);
if (f>CY22393_OUTMAX) { if (f>CY22393_OUTMAX) {
pars->rslt=2; pars->rslt=2;
dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\r\n",f0,f,CY22393_OUTMAX); dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\n",f0,f,CY22393_OUTMAX);
return pars->rslt; return pars->rslt;
} }
if (f <=0 ) { if (f <=0 ) {
pars->rslt=1; pars->rslt=1;
dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\r\n",f0,f,CY22393_OUTMAX); dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d\n",f0,f,CY22393_OUTMAX);
return pars->rslt; return pars->rslt;
} }
divmx=CY22393_PLLMAX/f; if (divmx > 127) divmx=127; // could not be <1 divmx=CY22393_PLLMAX/f; if (divmx > 127) divmx=127; // could not be <1
divmn=CY22393_PLLMIN/f; if (divmn < 1) divmn=1; divmn=CY22393_PLLMIN/f; if (divmn < 1) divmn=1;
if (divmn >127) { if (divmn >127) {
pars->rslt=1; pars->rslt=1;
dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d, divmn=%d\r\n",f0,f,CY22393_OUTMAX,divmn); dev_dbg(sdev, "f0=%d,f=%d, CY22393_OUTMAX=%d, divmn=%d\n",f0,f,CY22393_OUTMAX,divmn);
return pars->rslt; return pars->rslt;
} }
err1=f; err1=f;
...@@ -113,7 +113,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz ...@@ -113,7 +113,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz
qmn=fpmn/fdv-2; if (qmn < 0) qmn=0; qmn=fpmn/fdv-2; if (qmn < 0) qmn=0;
qmx=fpmx/fdv-2; if (qmx >255) qmx=255; qmx=fpmx/fdv-2; if (qmx >255) qmx=255;
// recalculate qmn to avoid same div*qmn as already tried with lover div // recalculate qmn to avoid same div*qmn as already tried with lover div
dev_dbg(sdev, "div=%d,qmn=%d, qmx=%d\r\n",div,qmn,qmx); dev_dbg(sdev, "div=%d,qmn=%d, qmx=%d\n",div,qmn,qmx);
if (div==1) qmx1=qmx; if (div==1) qmx1=qmx;
else if ((qmn*div) < qmx1) qmn=qmx1/div; else if ((qmn*div) < qmx1) qmn=qmx1/div;
for (q=qmn+2;q<=qmx+2; q++) { for (q=qmn+2;q<=qmx+2; q++) {
...@@ -127,10 +127,10 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz ...@@ -127,10 +127,10 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz
pars->dv=div; pars->dv=div;
err1=e/q/div; err1=e/q/div;
err=err1*div; err=err1*div;
dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d\r\n", (f0*p)/q/div, div,p, q, err1); dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d\n", (f0*p)/q/div, div,p, q, err1);
if (err1==0) { if (err1==0) {
pars->corr=(pars->p<226)?0:((pars->p<621)?1:((pars->p<829)?2:((pars->p<1038)?3:4))); pars->corr=(pars->p<226)?0:((pars->p<621)?1:((pars->p<829)?2:((pars->p<1038)?3:4)));
dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d, rslt=%d\r\n", dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d, rslt=%d\n",
(f0*(pars->p+6))/(pars->q+2)/pars->dv, (f0*(pars->p+6))/(pars->q+2)/pars->dv,
pars->dv, pars->dv,
(pars->p+6), (pars->p+6),
...@@ -142,7 +142,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz ...@@ -142,7 +142,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz
} }
} }
} }
dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d, rslt=%d\r\n", dev_dbg(sdev, "f=%d, div=%d, p=%d,q=%d, err1=%d, rslt=%d\n",
(f0*(pars->p+6))/(pars->q+2)/pars->dv, (f0*(pars->p+6))/(pars->q+2)/pars->dv,
pars->dv, pars->dv,
(pars->p+6), (pars->p+6),
...@@ -156,6 +156,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz ...@@ -156,6 +156,7 @@ int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz
int setCYField (int sensor_port, int reg_addr, int mask, int value) { int setCYField (int sensor_port, int reg_addr, int mask, int value) {
int error; int error;
int reg_data; int reg_data;
dev_dbg(sdev,"setCYField(%d, 0x%x, 0x%x,0x%x)\n",sensor_port, reg_addr, mask, value);
if ((error = x393_xi2c_read_reg(CLOCK_NAME, // device class name if ((error = x393_xi2c_read_reg(CLOCK_NAME, // device class name
sensor_port, // sensor port number sensor_port, // sensor port number
0, // slave address (7-bit) offset from the class defined slave address 0, // slave address (7-bit) offset from the class defined slave address
...@@ -165,6 +166,7 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) { ...@@ -165,6 +166,7 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) {
sensor_port, reg_addr, mask, value); sensor_port, reg_addr, mask, value);
return error; return error;
} }
dev_dbg(sdev,"setCYField(%d, 0x%x, 0x%x,0x%x)=>0x%x\n",sensor_port, reg_addr, mask, value,reg_data);
reg_data ^= (reg_data ^ value) & mask; reg_data ^= (reg_data ^ value) & mask;
if ((error = x393_xi2c_write_reg(CLOCK_NAME, // device class name if ((error = x393_xi2c_write_reg(CLOCK_NAME, // device class name
sensor_port, // sensor port number sensor_port, // sensor port number
...@@ -179,24 +181,45 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) { ...@@ -179,24 +181,45 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) {
} }
int x393_getClockFreq(int sensor_port, int nclock) { int x393_getClockFreq(int sensor_port, int nclock) {
if ((sensor_port < 0) || (sensor_port > 3) || (nclock < 0) || (nclock > 3))return -EINVAL; // bad clock number if ((sensor_port < 0) || (sensor_port > 3) || (nclock < 0) || (nclock > 3))return -EINVAL; // bad clock number
else { else {
return clock_frequency[(sensor_port << 2) || nclock]; dev_dbg(sdev, "clock_frequency[%d]\n",(sensor_port << 2) + nclock);
} return clock_frequency[(sensor_port << 2) + nclock];
}
} }
EXPORT_SYMBOL_GPL(x393_getClockFreq); EXPORT_SYMBOL_GPL(x393_getClockFreq);
int x393_setClockFreq(int sensor_port, int nclock, int freq) int x393_setClockFreq(int sensor_port, int nclock, int freq)
{ // freq now in Hz { // freq now in Hz
int err=0; int err=0;
int i,bp,bq,bdiv,pllc,fact;
t_pll_params pll_params;
sensor_port &= 3; sensor_port &= 3;
nclock &= 3; nclock &= 3;
t_pll_params pll_params;
int i,bp,bq,bdiv,pllc,fact;
bp=0; bq=0; bdiv=0; pllc= 0; // just to make gcc happy bp=0; bq=0; bdiv=0; pllc= 0; // just to make gcc happy
fact=0; fact=0;
dev_dbg(sdev, "setClockFreq(%d,%d,%d)\r\n",sensor_port,nclock,freq); dev_dbg(sdev, "setClockFreq(%d,%d,%d)\n",sensor_port,nclock,freq);
// Just temporary debug:
#if 1
for (i = 0; i< 24; i++) {
int reg_data;
// dev_dbg(sdev,"setCYField(%d, 0x%x, 0x%x,0x%x)\n",sensor_port, reg_addr, mask, value);
if ((err = x393_xi2c_read_reg(CLOCK_NAME, // device class name
sensor_port, // sensor port number
0, // slave address (7-bit) offset from the class defined slave address
i, // register address (width is defined by class)
&reg_data)) <0) { // pointer to a data receiver (read data width is defined by class)
dev_err(sdev,"x393_xi2c_read_reg(%d, 0, 0x%x, 0x%x) failed reading i2c register\n", sensor_port, i, reg_data);
break;
}
dev_err(sdev,"CY22393 port %d: [0x%x] => 0x%x\n", sensor_port, i, reg_data);
}
#endif
if ((freq!=0) && (nclock!=3) ){ if ((freq!=0) && (nclock!=3) ){
if ( (i=calc_pll_params (freq, &pll_params)) !=0) { if ( (i=calc_pll_params (freq, &pll_params)) !=0) {
dev_err(sdev, "bad frequency for clock %d - %d Hz, err=%d\n",nclock,freq,i); dev_err(sdev, "bad frequency for clock %d - %d Hz, err=%d\n",nclock,freq,i);
...@@ -255,7 +278,7 @@ int x393_setClockFreq(int sensor_port, int nclock, int freq) ...@@ -255,7 +278,7 @@ int x393_setClockFreq(int sensor_port, int nclock, int freq)
break; break;
case 3: case 3:
if ((freq!=0) && (freq!=CY22393_SCALE*CY22393_XTAL)) { if ((freq!=0) && (freq!=CY22393_SCALE*CY22393_XTAL)) {
dev_err(sdev, "Only frequency 0 (off) and %d Hz (xtal) are allowed for channel 3\r\n",CY22393_SCALE*CY22393_XTAL); dev_err(sdev, "Only frequency 0 (off) and %d Hz (xtal) are allowed for channel 3\n",CY22393_SCALE*CY22393_XTAL);
return -EINVAL; return -EINVAL;
} else { } else {
// int setCYField (sensor_port,int devfd, int addr, int mask, int value) O_RDWR // int setCYField (sensor_port,int devfd, int addr, int mask, int value) O_RDWR
...@@ -275,6 +298,7 @@ int x393_setClockFreq(int sensor_port, int nclock, int freq) ...@@ -275,6 +298,7 @@ int x393_setClockFreq(int sensor_port, int nclock, int freq)
return err; return err;
} }
clock_frequency[(sensor_port << 2) + nclock] = fact; clock_frequency[(sensor_port << 2) + nclock] = fact;
dev_dbg(sdev, "clock_frequency[%d]\n",(sensor_port << 2) + nclock);
return fact; return fact;
} }
EXPORT_SYMBOL_GPL(x393_setClockFreq); EXPORT_SYMBOL_GPL(x393_setClockFreq);
...@@ -400,7 +424,7 @@ static void elphel393_clock10359_init_of(struct platform_device *pdev) ...@@ -400,7 +424,7 @@ static void elphel393_clock10359_init_of(struct platform_device *pdev)
static int elphel393_clock10359_probe(struct platform_device *pdev) static int elphel393_clock10359_probe(struct platform_device *pdev)
{ {
sdev =&pdev->dev; sdev =&pdev->dev;
dev_dbg(&pdev->dev,"Probing elphel_clock10359\n"); dev_info(&pdev->dev,"Probing elphel_clock10359\n");
elphel393_clock10359_sysfs_register(pdev); elphel393_clock10359_sysfs_register(pdev);
dev_dbg(&pdev->dev,"elphel393_clock10359_sysfs_register() done\n"); dev_dbg(&pdev->dev,"elphel393_clock10359_sysfs_register() done\n");
......
...@@ -837,7 +837,7 @@ inline void _processParsSeq(int sensor_port, ///< sensor port ...@@ -837,7 +837,7 @@ inline void _processParsSeq(int sensor_port, ///< sensor port
{ {
unsigned long todo, mask, remain; unsigned long todo, mask, remain;
int job_ahead; // doing job "job_ahead" ahead of needed int job_ahead; // doing job "job_ahead" ahead of needed
int pars_ahead; // considering parameter "pars_ahead" of the (frame16+job_ahead) mod 8 int pars_ahead; // considering parameter "pars_ahead" of the (frame16+job_ahead) mod 16
int frame_proc; // current frame for which parameters are considered int frame_proc; // current frame for which parameters are considered
struct framepars_t * procpars; struct framepars_t * procpars;
struct framepars_t * prevpars; // maybe - drop calculation for each function, move it to pgm_* where needed? struct framepars_t * prevpars; // maybe - drop calculation for each function, move it to pgm_* where needed?
...@@ -968,7 +968,10 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16 ...@@ -968,7 +968,10 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16
dev_dbg(g_devfp_ptr,"port= %d (after second _processParsASAP), frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead); dev_dbg(g_devfp_ptr,"port= %d (after second _processParsASAP), frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead);
} }
dev_dbg(g_devfp_ptr,"port= %d (after second _processParsASAP), frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead); dev_dbg(g_devfp_ptr,"port= %d (after second _processParsASAP), frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead);
if (debug_flags) debug_flags--; if (debug_flags) {
dev_dbg(g_devfp_ptr,"debug_flags= %d \n", debug_flags);
debug_flags--;
}
} }
...@@ -1007,7 +1010,7 @@ int processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16, ...@@ -1007,7 +1010,7 @@ int processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16,
if (debug_flags) { if (debug_flags) {
MDP(DBGB_FPPT,sensor_port,"==from tasklet: frame16=%d, maxahead=%d\n", MDP(DBGB_FPPT,sensor_port,"==from tasklet: frame16=%d, maxahead=%d\n",
frame16, maxahead) frame16, maxahead)
dev_dbg(g_devfp_ptr,"==from tasklet: port= %d, frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead); dev_dbg(g_devfp_ptr,"==from tasklet: port= %d, frame16=%d, maxahead=%d now=0x%lx\n", sensor_port, frame16, maxahead, getThisFrameNumber(sensor_port));
} }
dev_dbg(g_devfp_ptr,"port= %d, frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead); dev_dbg(g_devfp_ptr,"port= %d, frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead);
...@@ -1021,13 +1024,12 @@ int processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16, ...@@ -1021,13 +1024,12 @@ int processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16,
if (debug_flags) { if (debug_flags) {
MDP(DBGB_FPPT,sensor_port,"==Done from tasklet: frame16=%d, maxahead=%d\n", MDP(DBGB_FPPT,sensor_port,"==Done from tasklet: frame16=%d, maxahead=%d\n",
frame16, maxahead) frame16, maxahead)
dev_dbg(g_devfp_ptr,"== Done from tasklet: port= %d, frame16=%d, maxahead=%d\n", sensor_port, frame16, maxahead); dev_dbg(g_devfp_ptr,"== Done from tasklet: port= %d, frame16=%d, maxahead=%d now=0x%lx\n", sensor_port, frame16, maxahead, getThisFrameNumber(sensor_port));
} }
return 0; return 0;
} }
#endif #endif
/** /**
* @brief schedule pgm_func to be executed for selected frame (frame16) * @brief schedule pgm_func to be executed for selected frame (frame16)
* @param sensor_port sensor port number (0..3) * @param sensor_port sensor port number (0..3)
......
...@@ -16,7 +16,7 @@ void init_framepars_ptr(int sensor_port); ...@@ -16,7 +16,7 @@ void init_framepars_ptr(int sensor_port);
int initSequencers (int sensor_port); ///Move to sensorcommon? currently it is used through frameparsall file (lseek) int initSequencers (int sensor_port); ///Move to sensorcommon? currently it is used through frameparsall file (lseek)
void initGlobalPars (int sensor_port); /// resets all global parameters but debug mask (if ELPHEL_DEBUG) void initGlobalPars (int sensor_port); /// resets all global parameters but debug mask (if ELPHEL_DEBUG)
int initMultiPars (int sensor_port); /// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called aftre/during sensor detection int initMultiPars (int sensor_port); /// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called aftre/during sensor detection
void initFramePars (int sensor_port); ///initialize all parameters, set thisFrameNumber to frame8 (read from hardware, usually 0 after resetting i2c and cmd_seq) void initFramePars (int sensor_port); ///initialize all parameters, set thisFrameNumber to frame16 (read from hardware, usually 0 after resetting i2c and cmd_seq)
void resetFrameNumber (int sensor_port, u32 aframe, int hreset); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow) void resetFrameNumber (int sensor_port, u32 aframe, int hreset); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow)
unsigned long get_imageParamsFrame(int sensor_port, int n, int frame); unsigned long get_imageParamsFrame(int sensor_port, int n, int frame);
......
...@@ -1219,7 +1219,7 @@ int mt9x001_pgm_limitfps (int sensor_port, ///< sensor port numb ...@@ -1219,7 +1219,7 @@ int mt9x001_pgm_limitfps (int sensor_port, ///< sensor port numb
{ {
struct frameparspair_t pars_to_update[16]; // maximum 7 registers updated (need to recount) struct frameparspair_t pars_to_update[16]; // maximum 7 registers updated (need to recount)
int nupdate=0; int nupdate=0;
int dh= thispars->pars[P_DCM_HOR]; int dh= thispars->pars[P_DCM_HOR]?thispars->pars[P_DCM_HOR]:1;
int ww= thispars->pars[P_SENSOR_PIXH] * dh; int ww= thispars->pars[P_SENSOR_PIXH] * dh;
int binning_cost = 0; int binning_cost = 0;
int width,i; int width,i;
...@@ -1989,8 +1989,8 @@ int mt9x001_pgm_triggermode (int sensor_port, ///< sensor p ...@@ -1989,8 +1989,8 @@ int mt9x001_pgm_triggermode (int sensor_port, ///< sensor p
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
newreg= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xfe7f) | // old value without snamshot and GRR bits newreg= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xfe7f) | // old value without snamshot and GRR bits
((thispars->pars[P_TRIG] & 4)?0x100:0) | // snapshot mode for P_TRIG==4 or 5 ((thispars->pars[P_TRIG] & 4)?0x100:0) | // snapshot mode for P_TRIG==4 or 20
((thispars->pars[P_TRIG] & 1)?0x80:0); // GRR mode for P_TRIG==5 (no effect for 1 ((thispars->pars[P_TRIG] & 0x10)?0x80:0); // GRR mode for P_TRIG==20
if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) { if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) {
// turn off triggered mode immediately, turn on later (or should made at least before changing camsync parameters) // turn off triggered mode immediately, turn on later (or should made at least before changing camsync parameters)
if (!(thispars->pars[P_TRIG] & 4)){ if (!(thispars->pars[P_TRIG] & 4)){
......
...@@ -213,15 +213,15 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use ...@@ -213,15 +213,15 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use
#ifdef NC353 // to hide old code #ifdef NC353 // to hide old code
#define MULTISENSOR_WRITE_I2C(sa,ra,v,sz) \ #define MULTISENSOR_WRITE_I2C(sa,ra,v,sz) \
{rslt |= multisensor_write_i2c((sa),(ra),(v),(sz)) ; \ {rslt |= multisensor_write_i2c((sa),(ra),(v),(sz)) ; \
dev_dbg(g_dev_ptr,"%s multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",__func__,(int)(sa),(int)(ra),(int)(v),(int)(sz),rslt);} dev_dbg(g_dev_ptr,"multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",(int)(sa),(int)(ra),(int)(v),(int)(sz),rslt);}
#define MULTISENSOR_WRITE_I2C16(ra,v) \ #define MULTISENSOR_WRITE_I2C16(ra,v) \
{rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(ra),(v),2) ; \ {rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(ra),(v),2) ; \
dev_dbg(g_dev_ptr,"%s multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",__func__,(int)(I2C359_SLAVEADDR),(int)(ra),(int)(v),2,rslt);} dev_dbg(g_dev_ptr,"multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",(int)(I2C359_SLAVEADDR),(int)(ra),(int)(v),2,rslt);}
#define MULTISENSOR_WRITE_I2C32(ra,v) \ #define MULTISENSOR_WRITE_I2C32(ra,v) \
{rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(I2C359_MSW),(v)>>16,2) ; \ {rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(I2C359_MSW),(v)>>16,2) ; \
dev_dbg(g_dev_ptr,"%s multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",__func__,(int)(I2C359_SLAVEADDR),I2C359_MSW,(int)(v)>>16,2,rslt); \ dev_dbg(g_dev_ptr,"multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",(int)(I2C359_SLAVEADDR),I2C359_MSW,(int)(v)>>16,2,rslt); \
rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(ra),(v) & 0xffff,2) ; \ rslt |= multisensor_write_i2c((I2C359_SLAVEADDR),(ra),(v) & 0xffff,2) ; \
dev_dbg(g_dev_ptr,"%s multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",__func__,(int)(I2C359_SLAVEADDR),(int)(ra),(int)(v)&0xffff,2,rslt); \ dev_dbg(g_dev_ptr,"multisensor_write_i2c(0x%x, 0x%x, 0x%x, %d) -> %d\n",(int)(I2C359_SLAVEADDR),(int)(ra),(int)(v)&0xffff,2,rslt); \
} }
#else #else
// using new access in immediate mode by class name // using new access in immediate mode by class name
...@@ -257,7 +257,7 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use ...@@ -257,7 +257,7 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use
{ pars_to_update[nupdate ].num= P_M10359_REGS+(r) ;\ { pars_to_update[nupdate ].num= P_M10359_REGS+(r) ;\
pars_to_update[nupdate++].val=(v);\ pars_to_update[nupdate++].val=(v);\
X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v)); \ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v)); \
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v));\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v));\
} }
#define SET_10359_PAR32(p,f,r,v) \ #define SET_10359_PAR32(p,f,r,v) \
...@@ -268,8 +268,8 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use ...@@ -268,8 +268,8 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use
X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (I2C359_MSW), (v)>>16); \ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (I2C359_MSW), (v)>>16); \
X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v) & 0xffff); \ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v) & 0xffff); \
local_irq_restore(flags); \ local_irq_restore(flags); \
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(I2C359_MSW),(int)(v)>>16);\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(I2C359_MSW),(int)(v)>>16);\
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v) & 0xffff);\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v) & 0xffff);\
} }
#define SET_10359_PAR(p, f,r,v) \ #define SET_10359_PAR(p, f,r,v) \
...@@ -285,7 +285,7 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use ...@@ -285,7 +285,7 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use
// same functions, but do not schedule updating parameter shadows, just send i2c // same functions, but do not schedule updating parameter shadows, just send i2c
#define SET_10359_REG16(p, f,r,v) \ #define SET_10359_REG16(p, f,r,v) \
{ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v)); \ { X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v)); \
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v));\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v));\
} }
#define SET_10359_REG32(p, f,r,v) \ #define SET_10359_REG32(p, f,r,v) \
...@@ -294,8 +294,8 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use ...@@ -294,8 +294,8 @@ int setup_i2c_pages(int ports) ///< bitmask of the sensor ports to use
X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (I2C359_MSW), (v)>>16); \ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (I2C359_MSW), (v)>>16); \
X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v) & 0xffff); \ X3X3_I2C_SEND2((p), (f), (I2C359_SLAVEADDR), (r), (v) & 0xffff); \
local_irq_restore(flags); \ local_irq_restore(flags); \
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(I2C359_MSW),(int)(v)>>16);\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(I2C359_MSW),(int)(v)>>16);\
dev_dbg(g_dev_ptr,"%s X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__,(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v) & 0xffff);\ dev_dbg(g_dev_ptr,"X3X3_I2C_SEND2(0x%x, 0x%x, 0x%x, 0x%x)\n",(int)(f),(int)(I2C359_SLAVEADDR),(int)(r),(int)(v) & 0xffff);\
} }
#define SET_10359_REG(p,f,r,v) \ #define SET_10359_REG(p,f,r,v) \
...@@ -320,6 +320,7 @@ int multisensor_read_i2c (int sensor_port, const char * class_name, in ...@@ -320,6 +320,7 @@ int multisensor_read_i2c (int sensor_port, const char * class_name, in
int multisensor_write_i2c (int sensor_port, const char * class_name,int sa7_offs, u32 reg_addr, u32 reg_data); int multisensor_write_i2c (int sensor_port, const char * class_name,int sa7_offs, u32 reg_addr, u32 reg_data);
int multisensor_pgm_multisens (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16); int multisensor_pgm_multisens (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int multisensor_pgm_sensorphase (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16); int multisensor_pgm_sensorphase (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int multisensor_pgm_sdram_phase (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16);
int multisensor_set_freq (int sensor_port, int first, struct framepars_t * thispars); int multisensor_set_freq (int sensor_port, int first, struct framepars_t * thispars);
int multisensor_set_phase_verify (int sensor_port, int reg_addr, int resetDCM, unsigned long newPhase, unsigned long oldPhase); int multisensor_set_phase_verify (int sensor_port, int reg_addr, int resetDCM, unsigned long newPhase, unsigned long oldPhase);
int multisensor_set_phase_recover (int sensor_port, int reg_addr, int resetDCM, unsigned long newPhase, unsigned long oldPhase); int multisensor_set_phase_recover (int sensor_port, int reg_addr, int resetDCM, unsigned long newPhase, unsigned long oldPhase);
...@@ -337,9 +338,10 @@ int multisensor_pgm_window_safe (int sensor_port, struct sensor_t * sensor, ...@@ -337,9 +338,10 @@ int multisensor_pgm_window_safe (int sensor_port, struct sensor_t * sensor,
int multisensor_pgm_window_common (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16) ; int multisensor_pgm_window_common (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16) ;
// These two parameters are copied from sensor // These two parameters are copied from sensor
static int multi_phases_initialized; static int multi_phases_initialized;
static struct sensorproc_t s_sensorproc_phys; // physical sensor parameters and functions to call static struct sensorproc_t s_sensorproc_phys; // physical sensor parameters and functions to call
struct sensorproc_t * sensorproc_phys = &s_sensorproc_phys; struct sensorproc_t * sensorproc_phys = &s_sensorproc_phys;
// test feature - reading i2c after certain writes to prevent FIFO over (should be unneded with FPGA status bit, just testing)
/** program sensor WOI and mirroring /** program sensor WOI and mirroring
* Validating, changing related parameters/scheduling actions, scheduling i2c commands * Validating, changing related parameters/scheduling actions, scheduling i2c commands
...@@ -354,7 +356,7 @@ int multisensor_pgm_window (int sensor_port, ///< sensor port ...@@ -354,7 +356,7 @@ int multisensor_pgm_window (int sensor_port, ///< sensor port
///< @return always 0 ///< @return always 0
{ {
int rslt; int rslt;
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
rslt = multisensor_pgm_window_common (sensor_port, sensor, thispars, prevpars, frame16); rslt = multisensor_pgm_window_common (sensor_port, sensor, thispars, prevpars, frame16);
return rslt; return rslt;
...@@ -373,7 +375,7 @@ int multisensor_pgm_window_safe (int sensor_port, ///< sensor port ...@@ -373,7 +375,7 @@ int multisensor_pgm_window_safe (int sensor_port, ///< sensor port
///< @return always 0 ///< @return always 0
{ {
int rslt; int rslt;
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
rslt = multisensor_pgm_window_common (sensor_port, sensor, thispars, prevpars, frame16); rslt = multisensor_pgm_window_common (sensor_port, sensor, thispars, prevpars, frame16);
return rslt; return rslt;
} }
...@@ -486,7 +488,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -486,7 +488,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
dev_dbg(g_dev_ptr,"frame16=%d\n",frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
if (composite && (!async)) { if (composite && (!async)) {
printk("*** ERROR (Should be disabled in multisensor_pgm_multisens() ) CANNOT USE COMPOSITE MODE WITH FREE RUNNING SENSOR ***\n"); dev_err(g_dev_ptr,"*** ERROR (Should be disabled in multisensor_pgm_multisens() ) CANNOT USE COMPOSITE MODE WITH FREE RUNNING SENSOR ***\n");
composite=0; composite=0;
SETFRAMEPARS_SET(P_MULTI_MODE,0); // Do we need to force anything here? If it was async->free transition? Or just TRIG mode should have all the dependencies of P_MULTI_MODE SETFRAMEPARS_SET(P_MULTI_MODE,0); // Do we need to force anything here? If it was async->free transition? Or just TRIG mode should have all the dependencies of P_MULTI_MODE
} }
...@@ -502,13 +504,17 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -502,13 +504,17 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
sFlipY[i]=flipY ^ (composite ?((thispars->pars[P_MULTI_FLIPV] & (1<<i))?1:0):0); // in single (non -composite) mode use just flipY sFlipY[i]=flipY ^ (composite ?((thispars->pars[P_MULTI_FLIPV] & (1<<i))?1:0):0); // in single (non -composite) mode use just flipY
} }
//sFlip* are now per-sensor absolute flips //sFlip* are now per-sensor absolute flips
dev_dbg(g_dev_ptr,"%s selected=%x flipX=%x flipY=%x sFlipX[0]=%x sFlipY[0]=%x sFlipX[1]=%x sFlipY[1]=%x sFlipX[2]=%x sFlipY[2]=%x\n",__func__, selected, flipX,flipY,sFlipX[0],sFlipY[0],sFlipX[1],sFlipY[1],sFlipX[2],sFlipY[2]); dev_dbg(g_dev_ptr,"selected=%x flipX=%x flipY=%x sFlipX[0]=%x sFlipY[0]=%x sFlipX[1]=%x sFlipY[1]=%x sFlipX[2]=%x sFlipY[2]=%x\n", selected, flipX,flipY,sFlipX[0],sFlipY[0],sFlipX[1],sFlipY[1],sFlipX[2],sFlipY[2]);
// calculations valid for individual and composite frames // calculations valid for individual and composite frames
styp = sensor->sensorType & 7; styp = sensor->sensorType & 7;
dh= thispars->pars[P_DCM_HOR]; dh= thispars->pars[P_DCM_HOR];
dv= thispars->pars[P_DCM_VERT]; dv= thispars->pars[P_DCM_VERT];
bh= thispars->pars[P_BIN_HOR]; bh= thispars->pars[P_BIN_HOR];
bv= thispars->pars[P_BIN_VERT]; bv= thispars->pars[P_BIN_VERT];
dh = dh?dh:1;
dv = dv?dv:1;
bh = bh?bh:1;
bv = bv?bv:1;
ww= thispars->pars[P_SENSOR_PIXH] * dh; ww= thispars->pars[P_SENSOR_PIXH] * dh;
// SETFRAMEPARS_SET(P_SENSOR_PIXV, height+(2 * COLOR_MARGINS)); // full height for the sensor (after decimation), including margins // SETFRAMEPARS_SET(P_SENSOR_PIXV, height+(2 * COLOR_MARGINS)); // full height for the sensor (after decimation), including margins
wh= thispars->pars[P_SENSOR_PIXV] * dv; // number of scan lines read from the sensor multipled by decimation wh= thispars->pars[P_SENSOR_PIXV] * dv; // number of scan lines read from the sensor multipled by decimation
...@@ -528,7 +534,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -528,7 +534,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
wt = thispars->pars[P_WOI_TOP]; wt = thispars->pars[P_WOI_TOP];
// flip margins for mirrored images (except oversized, not to rely on sensor->clearWidth/sensor->clearHeight // flip margins for mirrored images (except oversized, not to rely on sensor->clearWidth/sensor->clearHeight
//------------------------- //-------------------------
dev_dbg(g_dev_ptr,"%s dv=0x%x dh=0x%x ww=0x%x wh=0x%x wl=0x%x wt=0x%x \n",__func__,dv,dh,ww,wh,wl,wt); dev_dbg(g_dev_ptr,"dv=0x%x dh=0x%x ww=0x%x wh=0x%x wl=0x%x wt=0x%x \n",dv,dh,ww,wh,wl,wt);
memcpy(wois, &(thispars->pars[P_MULTI_WOI]), sizeof(wois)); // copy WOI parameters for 3 sensors memcpy(wois, &(thispars->pars[P_MULTI_WOI]), sizeof(wois)); // copy WOI parameters for 3 sensors
if (composite && flipY) { // reverse sequence if (composite && flipY) { // reverse sequence
...@@ -596,7 +602,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -596,7 +602,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
} }
} }
for (i=0; (v=SENSOR_IN_SEQ(i,sequence))>=0;i++) active |= (1<<v); for (i=0; (v=SENSOR_IN_SEQ(i,sequence))>=0;i++) active |= (1<<v);
dev_dbg(g_dev_ptr,"%s height1=0x%x height2=0x%x height3=0x%x\n",__func__,height1, height2, height3); dev_dbg(g_dev_ptr,"height1=0x%x height2=0x%x height3=0x%x\n",height1, height2, height3);
...@@ -613,19 +619,19 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -613,19 +619,19 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
} }
} }
// multiFlip* are set in the sub-frame sequence (accounting for the global FLIP_V, bit 0 - top subframe,1 - middle, 2 - last // multiFlip* are set in the sub-frame sequence (accounting for the global FLIP_V, bit 0 - top subframe,1 - middle, 2 - last
dev_dbg(g_dev_ptr,"%s multiFlipX=0x%x multiFlipY=0x%x\n",__func__,multiFlipX, multiFlipY); dev_dbg(g_dev_ptr,"multiFlipX=0x%x multiFlipY=0x%x\n",multiFlipX, multiFlipY);
// modify - multiFlipX,multiFlipY applies to sensors, not frames ???? No, they apply to sub-frames // modify - multiFlipX,multiFlipY applies to sensors, not frames ???? No, they apply to sub-frames
relFlipX= (multiFlipX ^ (multiFlipX>>1))& 3; relFlipX= (multiFlipX ^ (multiFlipX>>1))& 3;
relFlipY= (multiFlipY ^ (multiFlipY>>1))& 3; relFlipY= (multiFlipY ^ (multiFlipY>>1))& 3;
dev_dbg(g_dev_ptr,"%s relFlipX=0x%x relFlipY=0x%x\n",__func__,relFlipX, relFlipY); dev_dbg(g_dev_ptr,"relFlipX=0x%x relFlipY=0x%x\n",relFlipX, relFlipY);
if (relFlipY & 1) vblank2+=dv; if (relFlipY & 1) vblank2+=dv;
if (relFlipY & 2) vblank3+=((vblank3>=dv) && (vblank2>vblank3))?-dv:dv; // Keep the total height constant, if possible. If not possible - increase if (relFlipY & 2) vblank3+=((vblank3>=dv) && (vblank2>vblank3))?-dv:dv; // Keep the total height constant, if possible. If not possible - increase
hactDelay=(relFlipX ^ (relFlipX << 1)) & 3; hactDelay=(relFlipX ^ (relFlipX << 1)) & 3;
dev_dbg(g_dev_ptr,"%s hactDelay=0x%x vblank2=0x%x, vblank3=0x%x\n",__func__,hactDelay, vblank2, vblank3); dev_dbg(g_dev_ptr,"hactDelay=0x%x vblank2=0x%x, vblank3=0x%x\n",hactDelay, vblank2, vblank3);
// Apply height1, height2, height3 // Apply height1, height2, height3
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]=height1; // always on,>= other frame heights wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]=height1; // always on,>= other frame heights
if ((SENSOR_IN_SEQ(1,sequence)>=0) && (SENSOR_IN_SEQ(1,sequence)!=SENSOR_IN_SEQ(0,sequence))) { if ((SENSOR_IN_SEQ(1,sequence)>=0) && (SENSOR_IN_SEQ(1,sequence)!=SENSOR_IN_SEQ(0,sequence))) {
...@@ -649,10 +655,10 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -649,10 +655,10 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+0]=ww; // all channels - same width, include margins (before decimation) wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+0]=ww; // all channels - same width, include margins (before decimation)
wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+1]=ww; wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+1]=ww;
wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+2]=ww; wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+2]=ww;
dev_dbg(g_dev_ptr,"%s wois[LEFT1]=0x%lx, wois[LEFT2]=0x%lx, wois[LEFT3]=0x%lx\n",__func__, wois[(P_MULTI_LEFT1-P_MULTI_WOI)+0],wois[(P_MULTI_LEFT1-P_MULTI_WOI)+1],wois[(P_MULTI_LEFT1-P_MULTI_WOI)+2] ); dev_dbg(g_dev_ptr,"wois[LEFT1]=0x%lx, wois[LEFT2]=0x%lx, wois[LEFT3]=0x%lx\n", wois[(P_MULTI_LEFT1-P_MULTI_WOI)+0],wois[(P_MULTI_LEFT1-P_MULTI_WOI)+1],wois[(P_MULTI_LEFT1-P_MULTI_WOI)+2] );
dev_dbg(g_dev_ptr,"%s wois[WIDTH1]=0x%lx\n",__func__, wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+0] ); dev_dbg(g_dev_ptr,"wois[WIDTH1]=0x%lx\n", wois[(P_MULTI_WIDTH1-P_MULTI_WOI)+0] );
dev_dbg(g_dev_ptr,"%s wois[TOP1]=0x%lx, wois[TOP2]=0x%lx, wois[TOP3]=0x%lx\n",__func__, wois[(P_MULTI_TOP1-P_MULTI_WOI)+0],wois[(P_MULTI_TOP1-P_MULTI_WOI)+1],wois[(P_MULTI_TOP1-P_MULTI_WOI)+2] ); dev_dbg(g_dev_ptr,"wois[TOP1]=0x%lx, wois[TOP2]=0x%lx, wois[TOP3]=0x%lx\n", wois[(P_MULTI_TOP1-P_MULTI_WOI)+0],wois[(P_MULTI_TOP1-P_MULTI_WOI)+1],wois[(P_MULTI_TOP1-P_MULTI_WOI)+2] );
dev_dbg(g_dev_ptr,"%s wois[HEIGHT1]=0x%lx, wois[HEIGHT2]=0x%lx, wois[HEIGHT3]=0x%lx\n",__func__, wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0],wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1],wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] ); dev_dbg(g_dev_ptr,"wois[HEIGHT1]=0x%lx, wois[HEIGHT2]=0x%lx, wois[HEIGHT3]=0x%lx\n", wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+0],wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+1],wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+2] );
// TODO: Apply required height to the channels. If nothing but the direct channel is needed - apply it to sensor parameters // TODO: Apply required height to the channels. If nothing but the direct channel is needed - apply it to sensor parameters
...@@ -660,14 +666,14 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -660,14 +666,14 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
// Modify first sensor height even if it is increased to include part of the gap and minHeight // Modify first sensor height even if it is increased to include part of the gap and minHeight
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]= wh; wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]= wh;
sequence &= 3; // turn off frames 2, 3 sequence &= 3; // turn off frames 2, 3
dev_dbg(g_dev_ptr,"%s sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",__func__,sequence, height1, vblank2, height2, vblank3 ,height3 ); dev_dbg(g_dev_ptr,"sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",sequence, height1, vblank2, height2, vblank3 ,height3 );
} else if ((wt+wh-height1-vblank2) < (height2+vblank3+(sensor->minHeight*dv))) { // Only first 2 sensors are needed - reduce second frame (10359, not the sensor) } else if ((wt+wh-height1-vblank2) < (height2+vblank3+(sensor->minHeight*dv))) { // Only first 2 sensors are needed - reduce second frame (10359, not the sensor)
height2=wh+wt-height1-vblank2; // only 10359, not the sensor height2=wh+wt-height1-vblank2; // only 10359, not the sensor
sequence &= 0xf; // turn off frame 3 sequence &= 0xf; // turn off frame 3
dev_dbg(g_dev_ptr,"%s sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",__func__,sequence, height1, vblank2, height2, vblank3 ,height3 ); dev_dbg(g_dev_ptr,"sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",sequence, height1, vblank2, height2, vblank3 ,height3 );
} else { // all 3 sensors needed, adjust height3 to make sure 10359 sends out exactly wh/dv lines (vblank* could be adjusted to compensate for Bayer when flipping) } else { // all 3 sensors needed, adjust height3 to make sure 10359 sends out exactly wh/dv lines (vblank* could be adjusted to compensate for Bayer when flipping)
height3=wh+wt-height1-vblank2-height2-vblank3; height3=wh+wt-height1-vblank2-height2-vblank3;
dev_dbg(g_dev_ptr,"%s sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",__func__,sequence, height1, vblank2, height2, vblank3 ,height3 ); dev_dbg(g_dev_ptr,"sequence=%x height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",sequence, height1, vblank2, height2, vblank3 ,height3 );
} }
// zero out unused frames/blanks before them // zero out unused frames/blanks before them
...@@ -687,7 +693,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -687,7 +693,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
vblank3/=dv; vblank3/=dv;
height3/=dv; height3/=dv;
} }
dev_dbg(g_dev_ptr,"%s height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",__func__,height1, vblank2, height2, vblank3 ,height3 ); dev_dbg(g_dev_ptr,"height1=0x%x vblank2=0x%x height2=0x%x vblank3=0x%x height3=0x%x \n",height1, vblank2, height2, vblank3 ,height3 );
// un-apply dh from ww - number of pixels to be read in a line in frames2,3 // un-apply dh from ww - number of pixels to be read in a line in frames2,3
if (dh>1) ww/=dh; if (dh>1) ww/=dh;
w359=ww; w359=ww;
...@@ -698,7 +704,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p ...@@ -698,7 +704,7 @@ int multisensor_pgm_window_common (int sensor_port, ///< sensor p
((multiFlipY & 1)<<1) | ((multiFlipY & 2) << 2) | ((multiFlipY & 4) << 3) | 0x40; // 0x40 as a composite frame mark (test with &0xc0!=0 - future) ((multiFlipY & 1)<<1) | ((multiFlipY & 2) << 2) | ((multiFlipY & 4) << 3) | 0x40; // 0x40 as a composite frame mark (test with &0xc0!=0 - future)
if (flipX) multi_mode_flips ^= 0x15; if (flipX) multi_mode_flips ^= 0x15;
if (flipY) multi_mode_flips ^= 0x2a; if (flipY) multi_mode_flips ^= 0x2a;
dev_dbg(g_dev_ptr,"%s sequence=0x%x flipX=%x flipY=%x multi_mode_flips=0x%x \n",__func__,sequence,flipX,flipY,multi_mode_flips ); dev_dbg(g_dev_ptr,"sequence=0x%x flipX=%x flipY=%x multi_mode_flips=0x%x \n",sequence,flipX,flipY,multi_mode_flips );
SETFRAMEPARS_COND(P_MULTI_MODE_FLIPS, multi_mode_flips); SETFRAMEPARS_COND(P_MULTI_MODE_FLIPS, multi_mode_flips);
// subtract (2 * COLOR_MARGINS) from the first and last frame // subtract (2 * COLOR_MARGINS) from the first and last frame
...@@ -902,7 +908,7 @@ int multisensor_write_i2c(unsigned char theSlave, unsigned char theRegister, uns ...@@ -902,7 +908,7 @@ int multisensor_write_i2c(unsigned char theSlave, unsigned char theRegister, uns
return 0; return 0;
} }
#else #else
/** Write (2 bytes) to 10359 board or sensor*/ /** Write (2 bytes) to 10359 board or sensor in ASAP mode*/
int multisensor_write_i2c(int sensor_port,///< sensor port number int multisensor_write_i2c(int sensor_port,///< sensor port number
const char * class_name, ///< device class name ("el10359", "mt9p006") const char * class_name, ///< device class name ("el10359", "mt9p006")
int sa7_offs, ///< 0 for 10359 and sensor broadcast, 2/4/6 for sensor channels int sa7_offs, ///< 0 for 10359 and sensor broadcast, 2/4/6 for sensor channels
...@@ -910,14 +916,56 @@ int multisensor_write_i2c(int sensor_port,///< sensor port number ...@@ -910,14 +916,56 @@ int multisensor_write_i2c(int sensor_port,///< sensor port number
u32 reg_data) ///< data to send (2 bytes) u32 reg_data) ///< data to send (2 bytes)
///< @return 0: success, negative - error ///< @return 0: success, negative - error
{ {
return x393_xi2c_write_reg(class_name, // device class name int rslt;
sensor_port, // sensor port number inc_unbalanced_writes(sensor_port);
sa7_offs, // slave address (7-bit) offset from the class defined slave address rslt = x393_xi2c_write_reg(class_name, // device class name
reg_addr, // register address (width is defined by class) sensor_port, // sensor port number
reg_data); // data to write (width is defined by class) sa7_offs, // slave address (7-bit) offset from the class defined slave address
reg_addr, // register address (width is defined by class)
reg_data); // data to write (width is defined by class)
if (rslt <0) return rslt;
if (check_unbalanced_writes(sensor_port)){
unsigned long bitstream_version;
// X3X3_I2C_RCV4(sensor_port, I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version);
X3X3_I2C_RCV2(sensor_port, I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version); // just 2 bytes, not 4
dev_dbg(g_dev_ptr,"Exceeded number of unbalanced writes on port %d: (%d > %d), reading i2c, got 0x%lx\n",sensor_port, get_unbalanced_writes(sensor_port) ,i2c_get_max_unbalanced_writes(),bitstream_version);
}
// wait for the write buffer to have some room
if (!x393_xi2c_ready_wr (sensor_port)){
dev_dbg(g_dev_ptr,"Had to wait for the i2c sequencer while multisensor_write_i2c(%d, %s, 0x%x, 0x%x, 0x%x)\n",
sensor_port, class_name, sa7_offs,reg_addr, reg_data);
return x393_xi2c_wait_wr(sensor_port);
}
return 0;
} }
#endif #endif
/*
* unsigned long bitstream_version;
unsigned long sensor_id[MAX_SENSORS];
int rslt=0; // or-ed by MULTISENSOR_WRITE_I2C(sa,ra,v,sz)
int i;
int this_sensor_type;
long * multiOutDelay;
// .hact_delay = -2500, // -2.5ns delay in ps
// .sensorDelay = 2460, // Delay from sensor clock at FPGA output to pixel data transition (FPGA input), short cable (ps)
multi_unitialized=0; // reset this static variable - it will prevent copying individual flips to multiple until composite mode is used
dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
GLOBALPARS(sensor_port,G_SENS_AVAIL)=0; // no 10359A board present
if (frame16 >= 0) return -1; // can only work in ASAP mode
if (thispars->pars[P_SENSOR]) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0)
#ifdef NC353
dev_dbg(g_dev_ptr,"Probing 10359 board, i2c bitdelays=0x%08x, hardware_i2c_running=%d\n",i2c_delays(0),i2s_running());
if (multisensor_read_i2c(I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version, 4)<0) return -1;
#else
if (X3X3_I2C_RCV4(sensor_port, I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version)<0) return -1;
#endif
*
unbalanced_writes[sensor_port]=0;
// int unbalanced_writes [SENSOR_PORTS];
// #define MAX_UNBALANCED_WRITES 32
*/
static int multi_unitialized=0; ///< temporary hack to resolve race between individual and multi_ flips at startup static int multi_unitialized=0; ///< temporary hack to resolve race between individual and multi_ flips at startup
...@@ -953,17 +1001,22 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -953,17 +1001,22 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
int rslt=0; // or-ed by MULTISENSOR_WRITE_I2C(sa,ra,v,sz) int rslt=0; // or-ed by MULTISENSOR_WRITE_I2C(sa,ra,v,sz)
int i; int i;
int this_sensor_type; int this_sensor_type;
long * multiOutDelay; long * multiOutDelay;
x393_sens_mode_t sens_mode = {.d32=0}; // to disable senosr channel and prevent SoF pulses while 10359 memory is being trained
sens_mode.chn_en = 0;
sens_mode.chn_en_set = 1;
X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mode, sens_mode);
dev_dbg(g_dev_ptr,"{%d}@0x%lx: X393_SEQ_SEND1(0x%x, 0x%x, x393_sens_mode, 0x%x) disabling SoF - init_sesnor will reenable: 0x%x\n",
sensor_port, getThisFrameNumber(sensor_port), sensor_port, frame16, sens_mode.d32, getHardFrameNumber(sensor_port,0));
// .hact_delay = -2500, // -2.5ns delay in ps // .hact_delay = -2500, // -2.5ns delay in ps
// .sensorDelay = 2460, // Delay from sensor clock at FPGA output to pixel data transition (FPGA input), short cable (ps) // .sensorDelay = 2460, // Delay from sensor clock at FPGA output to pixel data transition (FPGA input), short cable (ps)
multi_unitialized=0; // reset this static variable - it will prevent copying individual flips to multiple until composite mode is used multi_unitialized=0; // reset this static variable - it will prevent copying individual flips to multiple until composite mode is used
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
GLOBALPARS(sensor_port,G_SENS_AVAIL)=0; // no 10359A board present GLOBALPARS(sensor_port,G_SENS_AVAIL)=0; // no 10359A board present
if (frame16 >= 0) return -1; // can only work in ASAP mode if (frame16 >= 0) return -1; // can only work in ASAP mode
if (thispars->pars[P_SENSOR]) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0) if (thispars->pars[P_SENSOR]) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0)
#ifdef NC353 #ifdef NC353
dev_dbg(g_dev_ptr,"%s Probing 10359 board, i2c bitdelays=0x%08x, hardware_i2c_running=%d\n",__func__,i2c_delays(0),i2s_running()); dev_dbg(g_dev_ptr,"Probing 10359 board, i2c bitdelays=0x%08x, hardware_i2c_running=%d\n",i2c_delays(0),i2s_running());
if (multisensor_read_i2c(I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version, 4)<0) return -1; if (multisensor_read_i2c(I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version, 4)<0) return -1;
#else #else
if (X3X3_I2C_RCV4(sensor_port, I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version)<0) return -1; if (X3X3_I2C_RCV4(sensor_port, I2C359_SLAVEADDR, I2C359_VERSION, &bitstream_version)<0) return -1;
...@@ -975,18 +1028,18 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -975,18 +1028,18 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
add_sensor_proc(sensor_port,onchange_sensorphase, &multisensor_pgm_sensorphase); // set clock/phase for the 10359A add_sensor_proc(sensor_port,onchange_sensorphase, &multisensor_pgm_sensorphase); // set clock/phase for the 10359A
if ((((bitstream_version ^ I2C359_MINVERSION) & 0xffff0000)!=0) || ((bitstream_version & 0xffff) < (I2C359_MINVERSION & 0xffff))) { if ((((bitstream_version ^ I2C359_MINVERSION) & 0xffff0000)!=0) || ((bitstream_version & 0xffff) < (I2C359_MINVERSION & 0xffff))) {
printk ("invalid 10359 bitstream version, found 0x%08lx, required >= 0x%08x\n",bitstream_version, I2C359_MINVERSION ); dev_err(g_dev_ptr,"invalid 10359 bitstream version, found 0x%08lx, required >= 0x%08x\n",bitstream_version, I2C359_MINVERSION );
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType);
return -1; return -1;
} }
printk("10359 bitstream version =0x%08lx\n",bitstream_version); dev_dbg(g_dev_ptr,"10359 bitstream version =0x%08lx\n",bitstream_version);
// now set sensor clock in both system board and 10359A to 96MHz - currently we support only 5MPix in thias mode // now set sensor clock in both system board and 10359A to 96MHz - currently we support only 5MPix in thias mode
#ifdef NC353 #ifdef NC353
setFramePar(sensor_port, thispars, P_CLK_FPGA, getClockFreq(0)); // just in case - read the actual fpga clock frequency and store it (no actions) setFramePar(sensor_port, thispars, P_CLK_FPGA, getClockFreq(0)); // just in case - read the actual fpga clock frequency and store it (no actions)
setFramePar(sensor_port, thispars, P_CLK_SENSOR, 96000000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, 96000000);
setClockFreq(sensor_port, 1, thispars->pars[P_CLK_SENSOR]); setClockFreq(sensor_port, 1, thispars->pars[P_CLK_SENSOR]);
#endif #endif
printk("10353 sensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]); dev_info(g_dev_ptr,"10353 sensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]);
udelay (100);// 0.0001 sec to stabilize clocks udelay (100);// 0.0001 sec to stabilize clocks
// X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset // X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset
...@@ -998,9 +1051,13 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -998,9 +1051,13 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
// reset system and SDRAM DCMs on 10359 // reset system and SDRAM DCMs on 10359
MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SYSTEM, I2C359_DCM_RESET | I2C359_DCM_RESET90); MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SYSTEM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
rslt=0;
#ifdef ADJUST_SDRAM_AT_SENSORPHASE
MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90); MULTISENSOR_WRITE_I2C16(sensor_port,I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
rslt=0; #endif
// TODO: read other? // TODO: read other?
// MULTISENSOR_WRITE_I2C16_SHADOW(I2C359_I2CMUX, I2C359_I2CMUX_2MEM); // MULTISENSOR_WRITE_I2C16_SHADOW(I2C359_I2CMUX, I2C359_I2CMUX_2MEM);
...@@ -1018,11 +1075,16 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1018,11 +1075,16 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
} }
#endif #endif
rslt=multisensor_set_freq (sensor_port, 1, thispars); // first time (1) rslt=multisensor_set_freq (sensor_port, 1, thispars); // first time (1)
if (rslt>0) printk("10359A sensor clock set to %d\n", rslt); if (rslt>0) dev_info(g_dev_ptr,"10359A sensor clock set to %d\n", rslt);
else if (rslt==0) printk("10359A sensors are using 10353 system clock, as set in configuration\n"); else if (rslt==0) dev_info(g_dev_ptr,"10359A sensors are using 10353 system clock, as set in configuration\n");
else printk("10359 sensor clock failure, will use system clock from 10353 board\n"); else dev_info(g_dev_ptr,"10359 sensor clock failure, will use system clock from 10353 board\n");
#ifndef ADJUST_SDRAM_AT_SENSORPHASE
rslt = multisensor_pgm_sdram_phase (sensor_port, sensor, thispars, prevpars, frame16);
#endif
// Try to read chip version from each of the 3 possible sensors // Try to read chip version from each of the 3 possible sensors
printk("removing MRST from the sensor\n"); dev_info(g_dev_ptr,"removing MRST from the sensor\n");
// //
sensio_ctl.d32 = 0; sensio_ctl.d32 = 0;
sensio_ctl.mrst = 1; sensio_ctl.mrst = 1;
...@@ -1036,9 +1098,10 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1036,9 +1098,10 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
udelay (100); udelay (100);
GLOBALPARS(sensor_port,G_SENS_AVAIL) |= 1<< (GLOBALPARS(sensor_port,G_SENS_AVAIL)); // temporary to indicate sensor detection functions that they need to initialize multisensor registers GLOBALPARS(sensor_port,G_SENS_AVAIL) |= 1<< (GLOBALPARS(sensor_port,G_SENS_AVAIL)); // temporary to indicate sensor detection functions that they need to initialize multisensor registers
for (i=0;i<MAX_SENSORS;i++) { // for (i=0;i<MAX_SENSORS;i++) {
for (i=0;i<3;i++) { // 10359 only supports 3 sesnors, not 4
#ifdef NC353 #ifdef NC353
dev_dbg(g_dev_ptr,"%s Probing sensor port %d, i2c bitdelays=0x%08x\n",__func__,i,i2c_delays(0)); dev_dbg(g_dev_ptr,"Probing sensor port %d, i2c bitdelays=0x%08x\n",i,i2c_delays(0));
rslt= multisensor_read_i2c(sensor_port, rslt= multisensor_read_i2c(sensor_port,
MT9P001_I2C_ADDR + ((i+1) * I2C359_INC), MT9P001_I2C_ADDR + ((i+1) * I2C359_INC),
P_MT9X001_CHIPVER, P_MT9X001_CHIPVER,
...@@ -1050,35 +1113,37 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1050,35 +1113,37 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
P_MT9X001_CHIPVER, P_MT9X001_CHIPVER,
&sensor_id[i]); &sensor_id[i]);
#endif #endif
// dev_dbg(g_dev_ptr,"%s Probing sensor port %d, i2c bitdelays=0x%08x, rslt=0x%x\n",__func__,i,i2c_delays(0),rslt); // dev_dbg(g_dev_ptr,"Probing sensor port %d, i2c bitdelays=0x%08x, rslt=0x%x\n",i,i2c_delays(0),rslt);
if (rslt==0) { if (rslt==0) {
if (((sensor_id[i] ^ MT9P001_PARTID) & MT9X001_PARTIDMASK)==0) { if (((sensor_id[i] ^ MT9P001_PARTID) & MT9X001_PARTIDMASK)==0) {
printk("Found MT9P001 2592x1944 sensor on 10359A port %d, chip ID=%lx\n",(i+1), sensor_id[i]); dev_info(g_dev_ptr,"Found MT9P001 2592x1944 sensor on 10359A port %d, chip ID=%lx\n",(i+1), sensor_id[i]);
GLOBALPARS(sensor_port,G_SENS_AVAIL) |= 1<<i; GLOBALPARS(sensor_port,G_SENS_AVAIL) |= 1<<i;
} else if (sensor_id[i] == 0xffff){
sensor_id[i]=0;
} else { } else {
printk("Found UNSUPPORTED sensor on port %d, chip ID=0x%lx\n",(i+1),sensor_id[i]); dev_warn(g_dev_ptr,"Found UNSUPPORTED sensor on port %d, chip ID=0x%lx\n",(i+1),sensor_id[i]);
} }
} else sensor_id[i]=0; } else sensor_id[i]=0;
} }
GLOBALPARS(sensor_port,G_SENS_AVAIL) &= (1<< (GLOBALPARS(sensor_port,G_SENS_AVAIL)))-1; // remove flag used to indicate sensor detection functions that they need to initialize multisesnor registers GLOBALPARS(sensor_port,G_SENS_AVAIL) &= (1<< (GLOBALPARS(sensor_port,G_SENS_AVAIL)))-1; // remove flag used to indicate sensor detection functions that they need to initialize multisesnor registers
if (GLOBALPARS(sensor_port,G_SENS_AVAIL)==0) { if (GLOBALPARS(sensor_port,G_SENS_AVAIL)==0) {
printk ("No supported sensors connected to 10359A board\n"); dev_warn(g_dev_ptr,"No supported sensors connected to 10359A board\n");
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType);
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
return 0; return 0;
} }
printk ("Setting internal HACT generation\n"); dev_info(g_dev_ptr,"Setting internal HACT generation\n");
MULTISENSOR_WRITE_I2C16_SHADOW(sensor_port, I2C359_HACT_MODE, 7); MULTISENSOR_WRITE_I2C16_SHADOW(sensor_port, I2C359_HACT_MODE, 7);
// At least one MT9P0X1 sensor found, initializing them in broadcast mode (will still need to modify phases - both 10353 and 10359 // At least one MT9P0X1 sensor found, initializing them in broadcast mode (will still need to modify phases - both 10353 and 10359
this_sensor_type=mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type this_sensor_type=mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type
// for (i=0;i<8;i++) { // for (i=0;i<8;i++) {
// dev_dbg(g_dev_ptr,"%s i=%d, m=0x%lx\n",__func__,i,GLOBALPARS(G_MULTI_REGSM+i)); // dev_dbg(g_dev_ptr,"i=%d, m=0x%lx\n",i,GLOBALPARS(G_MULTI_REGSM+i));
// } // }
initMultiPars(sensor_port); // this time the registors that need to have individual shadows are known, initialize the corresponding data structures initMultiPars(sensor_port); // this time the registors that need to have individual shadows are known, initialize the corresponding data structures
// memcpy(psensor, sensor, sizeof(struct sensor_t)); // copy physical sensor definitions to the save area (so some can be replaced by modified ones) // memcpy(psensor, sensor, sizeof(struct sensor_t)); // copy physical sensor definitions to the save area (so some can be replaced by modified ones)
// dev_dbg(g_dev_ptr,"%s before: sensorproc_phys->sensor.sensorDelay=0x%x\n",__func__, sensorproc_phys->sensor.sensorDelay); // dev_dbg(g_dev_ptr,"before: sensorproc_phys->sensor.sensorDelay=0x%x\n", sensorproc_phys->sensor.sensorDelay);
copy_sensorproc(sensor_port, sensorproc_phys); // save physical sensor functions copy_sensorproc(sensor_port, sensorproc_phys); // save physical sensor functions
// dev_dbg(g_dev_ptr,"%s after: sensorproc_phys->sensor.sensorDelay=0x%x\n",__func__, sensorproc_phys->sensor.sensorDelay); // dev_dbg(g_dev_ptr,"after: sensorproc_phys->sensor.sensorDelay=0x%x\n", sensorproc_phys->sensor.sensorDelay);
// Now calculate phases, swap ones from the sensor // Now calculate phases, swap ones from the sensor
multiOutDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_OUT); multiOutDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_OUT);
...@@ -1086,7 +1151,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1086,7 +1151,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
sensor->hact_delay=0; // No hact delay on 10359 output sensor->hact_delay=0; // No hact delay on 10359 output
sensor->sensorDelay=multiOutDelay[0]; sensor->sensorDelay=multiOutDelay[0];
dev_dbg(g_dev_ptr,"%s replaced: sensor->sensorDelay=0x%x\n",__func__, sensor->sensorDelay); dev_dbg(g_dev_ptr,"replaced: sensor->sensorDelay=0x%x\n", sensor->sensorDelay);
//sensorproc_phys->sensor //sensorproc_phys->sensor
/* /*
Now overwrite sensor functions with it's own (originals (physical sensor ones) are already copied to the local structure Now overwrite sensor functions with it's own (originals (physical sensor ones) are already copied to the local structure
...@@ -1171,6 +1236,7 @@ Now overwrite sensor functions with it's own (originals (physical sensor ones) a ...@@ -1171,6 +1236,7 @@ Now overwrite sensor functions with it's own (originals (physical sensor ones) a
CCAM_ENDFRAMES_EN ; // Enable ending frame being compressed if no more data will be available (frame ended before specified number of blocks compressed) CCAM_ENDFRAMES_EN ; // Enable ending frame being compressed if no more data will be available (frame ended before specified number of blocks compressed)
#endif #endif
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
dev_dbg(g_dev_ptr,"Done with multisensor_pgm_detectsensor thisFframe= 0x%lx hard frame = 0x%x\n", getThisFrameNumber(sensor_port), getHardFrameNumber(sensor_port,0));
return this_sensor_type; return this_sensor_type;
} }
...@@ -1218,20 +1284,20 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1218,20 +1284,20 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
int new_sensor=selected-1; // >=0 int new_sensor=selected-1; // >=0
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
if (!sensor_mask) sensor_mask=GLOBALPARS(sensor_port, G_SENS_AVAIL) ;// if none sensors were enabled - enable all what is available (same as with WOI size) if (!sensor_mask) sensor_mask=GLOBALPARS(sensor_port, G_SENS_AVAIL) ;// if none sensors were enabled - enable all what is available (same as with WOI size)
if (composite && (!async)) { if (composite && (!async)) {
printk("*** CANNOT USE COMPOSITE MODE WITH FREE RUNNING SENSOR ***\n"); dev_err(g_dev_ptr,"*** CANNOT USE COMPOSITE MODE WITH FREE RUNNING SENSOR ***\n");
composite=0; composite=0;
SETFRAMEPARS_SET(P_MULTI_MODE,0); // Do we need to force anything here? If it was async->free transition? Or just TRIG mode should have all the dependencies of P_MULTI_MODE SETFRAMEPARS_SET(P_MULTI_MODE,0); // Do we need to force anything here? If it was async->free transition? Or just TRIG mode should have all the dependencies of P_MULTI_MODE
} }
// TODO: recalculate sequence when MULTISENS_EN is chnaged (tried 5 - did not modify sequence, showed first frame only) // TODO: recalculate sequence when MULTISENS_EN is chnaged (tried 5 - did not modify sequence, showed first frame only)
// Here - only recalculate SENSOR_HEIGHT, skipping disabled sensors. in multisensor_pgm_window() will need to skip disabled also // Here - only recalculate SENSOR_HEIGHT, skipping disabled sensors. in multisensor_pgm_window() will need to skip disabled also
// No above is not really needed, sequence+enable can be handled by application software // No above is not really needed, sequence+enable can be handled by application software
dev_dbg(g_dev_ptr,"%s composite=0x%x\n",__func__,composite); dev_dbg(g_dev_ptr,"composite=0x%x\n",composite);
dev_dbg(g_dev_ptr,"%s sequence=0x%x\n",__func__, sequence); dev_dbg(g_dev_ptr,"sequence=0x%x\n", sequence);
// if sequence is zero, put "1-2-3" // if sequence is zero, put "1-2-3"
if (sequence==0) { if (sequence==0) {
j=1; j=1;
...@@ -1262,9 +1328,9 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1262,9 +1328,9 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
} }
if ((selected==0) || !((1 << (selected-1)) & GLOBALPARS(sensor_port, G_SENS_AVAIL))) selected=sequence & 3; // if not set or invalid - set to first in sequence if ((selected==0) || !((1 << (selected-1)) & GLOBALPARS(sensor_port, G_SENS_AVAIL))) selected=sequence & 3; // if not set or invalid - set to first in sequence
dev_dbg(g_dev_ptr,"%s selected=0x%x, thispars->pars[P_MULTI_SELECTED]=0x%x\n",__func__, selected, (int) thispars->pars[P_MULTI_SELECTED]); dev_dbg(g_dev_ptr,"selected=0x%x, thispars->pars[P_MULTI_SELECTED]=0x%x\n", selected, (int) thispars->pars[P_MULTI_SELECTED]);
dev_dbg(g_dev_ptr,"%s sequence=0x%x\n",__func__, sequence); dev_dbg(g_dev_ptr,"sequence=0x%x\n", sequence);
dev_dbg(g_dev_ptr,"%s sensor_mask=0x%x\n",__func__, sensor_mask); dev_dbg(g_dev_ptr,"sensor_mask=0x%x\n", sensor_mask);
SETFRAMEPARS_COND(P_MULTI_SELECTED, selected); SETFRAMEPARS_COND(P_MULTI_SELECTED, selected);
SETFRAMEPARS_COND(P_MULTI_SEQUENCE, sequence); SETFRAMEPARS_COND(P_MULTI_SEQUENCE, sequence);
SETFRAMEPARS_COND(P_MULTISENS_EN, sensor_mask); SETFRAMEPARS_COND(P_MULTISENS_EN, sensor_mask);
...@@ -1274,14 +1340,14 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1274,14 +1340,14 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
// int old_sensor=prev_selected-1; // may be <0 // int old_sensor=prev_selected-1; // may be <0
// int new_sensor=selected-1; // >=0 // int new_sensor=selected-1; // >=0
if (multi_unitialized && (!prev_composite) && (old_sensor>=0)) { // was single-sensor mode, copy P_WOI_* to individual sensor WOI and FLIPS if (multi_unitialized && (!prev_composite) && (old_sensor>=0)) { // was single-sensor mode, copy P_WOI_* to individual sensor WOI and FLIPS
dev_dbg(g_dev_ptr,"%s multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n",__func__, multi_unitialized, old_sensor, multi_fliph,multi_flipv); dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized, old_sensor, multi_fliph,multi_flipv);
wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_WIDTH]; wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_WIDTH];
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_HEIGHT]; wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_HEIGHT];
wois[(P_MULTI_LEFT1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_LEFT]; wois[(P_MULTI_LEFT1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_LEFT];
wois[(P_MULTI_TOP1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_TOP]; wois[(P_MULTI_TOP1- P_MULTI_WOI)+old_sensor]= prevpars->pars[P_WOI_TOP];
multi_fliph= (multi_fliph & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPH] & 1) << old_sensor); multi_fliph= (multi_fliph & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPH] & 1) << old_sensor);
multi_flipv= (multi_flipv & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPV] & 1) << old_sensor); multi_flipv= (multi_flipv & (~(1<<old_sensor))) | ((prevpars->pars[P_FLIPV] & 1) << old_sensor);
dev_dbg(g_dev_ptr,"%s multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n",__func__, multi_unitialized, old_sensor, multi_fliph,multi_flipv); dev_dbg(g_dev_ptr,"multi_unitialized=%d old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", multi_unitialized, old_sensor, multi_fliph,multi_flipv);
} }
if (multi_unitialized && (!composite) && (prev_composite || ((new_sensor>=0) && (old_sensor!=new_sensor)))) { // now single-sensor mode, set P_WOI* from saved parameters if (multi_unitialized && (!composite) && (prev_composite || ((new_sensor>=0) && (old_sensor!=new_sensor)))) { // now single-sensor mode, set P_WOI* from saved parameters
if ((wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+new_sensor]==0) || (wois[(P_MULTI_HEIGHT1- P_MULTI_WOI)+new_sensor]==0)) { if ((wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+new_sensor]==0) || (wois[(P_MULTI_HEIGHT1- P_MULTI_WOI)+new_sensor]==0)) {
...@@ -1295,7 +1361,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1295,7 +1361,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
wois[(P_MULTI_LEFT1- P_MULTI_WOI)+new_sensor]= 0; wois[(P_MULTI_LEFT1- P_MULTI_WOI)+new_sensor]= 0;
wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor]= 0; wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor]= 0;
multi_fliph= (multi_fliph & (~(1<<new_sensor))); // =0 multi_fliph= (multi_fliph & (~(1<<new_sensor))); // =0
dev_dbg(g_dev_ptr,"%s new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n",__func__, new_sensor, old_sensor, multi_fliph,multi_flipv); dev_dbg(g_dev_ptr,"new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", new_sensor, old_sensor, multi_fliph,multi_flipv);
multi_flipv= (multi_flipv & (~(1<<new_sensor))); // =0 multi_flipv= (multi_flipv & (~(1<<new_sensor))); // =0
} else { // was one single channel, now the different (not initialized window) one - copy window parameters } else { // was one single channel, now the different (not initialized window) one - copy window parameters
wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+new_sensor]= prevpars->pars[P_WOI_WIDTH]; wois[(P_MULTI_WIDTH1- P_MULTI_WOI)+new_sensor]= prevpars->pars[P_WOI_WIDTH];
...@@ -1304,7 +1370,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1304,7 +1370,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor]= prevpars->pars[P_WOI_TOP]; wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor]= prevpars->pars[P_WOI_TOP];
multi_fliph= (multi_fliph & (~(1<<new_sensor))) | ((prevpars->pars[P_FLIPH] & 1) << new_sensor); multi_fliph= (multi_fliph & (~(1<<new_sensor))) | ((prevpars->pars[P_FLIPH] & 1) << new_sensor);
multi_flipv= (multi_flipv & (~(1<<new_sensor))) | ((prevpars->pars[P_FLIPV] & 1) << new_sensor); multi_flipv= (multi_flipv & (~(1<<new_sensor))) | ((prevpars->pars[P_FLIPV] & 1) << new_sensor);
dev_dbg(g_dev_ptr,"%s new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n",__func__, new_sensor, old_sensor, multi_fliph,multi_flipv); dev_dbg(g_dev_ptr,"new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", new_sensor, old_sensor, multi_fliph,multi_flipv);
} }
} }
// saved sensor WOI are OK (or just fixed), use them // saved sensor WOI are OK (or just fixed), use them
...@@ -1314,7 +1380,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1314,7 +1380,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
SETFRAMEPARS_COND(P_WOI_TOP, wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor] ); SETFRAMEPARS_COND(P_WOI_TOP, wois[(P_MULTI_TOP1- P_MULTI_WOI)+new_sensor] );
SETFRAMEPARS_COND(P_FLIPH, (multi_fliph>>new_sensor) & 1); SETFRAMEPARS_COND(P_FLIPH, (multi_fliph>>new_sensor) & 1);
SETFRAMEPARS_COND(P_FLIPV, (multi_flipv>>new_sensor) & 1); SETFRAMEPARS_COND(P_FLIPV, (multi_flipv>>new_sensor) & 1);
dev_dbg(g_dev_ptr,"%s new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n",__func__, new_sensor, old_sensor, multi_fliph,multi_flipv); dev_dbg(g_dev_ptr,"new_sensor=%x old_sensor=%x, multi_fliph=%x multi_flipv=%x\n", new_sensor, old_sensor, multi_fliph,multi_flipv);
} }
// Validate hights for all enabled channels (OK to skip disabled here) // Validate hights for all enabled channels (OK to skip disabled here)
oversize=thispars->pars[P_OVERSIZE]; oversize=thispars->pars[P_OVERSIZE];
...@@ -1330,30 +1396,30 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1330,30 +1396,30 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
else if ((!oversize) && (height1 > sensor->imageHeight)) height1=sensor->imageHeight; // use clearHeight here? else if ((!oversize) && (height1 > sensor->imageHeight)) height1=sensor->imageHeight; // use clearHeight here?
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]=height1; wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(0,sequence)]=height1;
total_height=height1; total_height=height1;
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
// is there frame 2 enabled? // is there frame 2 enabled?
multi_frame=0; multi_frame=0;
if (composite && SENSOR_IN_SEQ_EN(1,sequence,sensor_mask)) { // specified in sequence is enabled if (composite && SENSOR_IN_SEQ_EN(1,sequence,sensor_mask)) { // specified in sequence is enabled
multi_frame=1; multi_frame=1;
total_height+=(vblank+(2 * COLOR_MARGINS))*dv; total_height+=(vblank+(2 * COLOR_MARGINS))*dv;
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
if (!height2) height2=sensor->imageHeight; if (!height2) height2=sensor->imageHeight;
if (height2 < sensor->minHeight) height2=sensor->minHeight; if (height2 < sensor->minHeight) height2=sensor->minHeight;
else if (height2 > sensor->arrayHeight) height2=sensor->arrayHeight; else if (height2 > sensor->arrayHeight) height2=sensor->arrayHeight;
else if ((!oversize) && (height2 > sensor->imageHeight)) height2=sensor->imageHeight; // use clearHeight here? else if ((!oversize) && (height2 > sensor->imageHeight)) height2=sensor->imageHeight; // use clearHeight here?
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(1,sequence)]=height2; wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(1,sequence)]=height2;
total_height+=height2; total_height+=height2;
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
if (SENSOR_IN_SEQ_EN(2,sequence,sensor_mask)) { if (SENSOR_IN_SEQ_EN(2,sequence,sensor_mask)) {
total_height+=(vblank+(2 * COLOR_MARGINS))*dv; total_height+=(vblank+(2 * COLOR_MARGINS))*dv;
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
if (!height3) height3=sensor->imageHeight; if (!height3) height3=sensor->imageHeight;
if (height3 < sensor->minHeight) height3=sensor->minHeight; if (height3 < sensor->minHeight) height3=sensor->minHeight;
else if (height3 > sensor->arrayHeight) height3=sensor->arrayHeight; else if (height3 > sensor->arrayHeight) height3=sensor->arrayHeight;
else if ((!oversize) && (height2 > sensor->imageHeight)) height3=sensor->imageHeight; // use clearHeight here? else if ((!oversize) && (height2 > sensor->imageHeight)) height3=sensor->imageHeight; // use clearHeight here?
wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(2,sequence)]=height3; wois[(P_MULTI_HEIGHT1-P_MULTI_WOI)+SENSOR_IN_SEQ(2,sequence)]=height3;
total_height+=height3; total_height+=height3;
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
} }
} }
if (composite) { if (composite) {
...@@ -1393,7 +1459,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n ...@@ -1393,7 +1459,7 @@ int multisensor_pgm_multisens (int sensor_port, ///< sensor port n
} }
SETFRAMEPARS_COND(P_MULTI_FLIPH, multi_fliph); SETFRAMEPARS_COND(P_MULTI_FLIPH, multi_fliph);
SETFRAMEPARS_COND(P_MULTI_FLIPV, multi_flipv); SETFRAMEPARS_COND(P_MULTI_FLIPV, multi_flipv);
dev_dbg(g_dev_ptr,"%s total_height=0x%x\n",__func__,total_height); dev_dbg(g_dev_ptr,"total_height=0x%x\n",total_height);
SETFRAMEPARS_COND(P_SENSOR_HEIGHT, total_height); SETFRAMEPARS_COND(P_SENSOR_HEIGHT, total_height);
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes, schedule functions if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes, schedule functions
...@@ -1414,10 +1480,10 @@ int calcThisPhase(int clk_period, ///< cklock period (Hz) ...@@ -1414,10 +1480,10 @@ int calcThisPhase(int clk_period, ///< cklock period (Hz)
{ {
int px_delay=-(clk_period/2 - FPGADelay- cableDelay - sensorDelay) ; // static int sensorDelay int px_delay=-(clk_period/2 - FPGADelay- cableDelay - sensorDelay) ; // static int sensorDelay
int px_delay90=(4*px_delay+clk_period/2)/clk_period; int px_delay90=(4*px_delay+clk_period/2)/clk_period;
MDF16(printk ("cableDelay1=%ld, FPGADelay1=%ld, clk_period=%d\r\n",cableDelay, FPGADelay, clk_period)); MDF16(printk ("cableDelay1=%ld, FPGADelay1=%ld, clk_period=%d\n",cableDelay, FPGADelay, clk_period));
MDF16(printk ("px_delay1=%d\r\n",px_delay)); MDF16(printk ("px_delay1=%d\n",px_delay));
px_delay -= (px_delay90*clk_period)/4; // -clk_period/8<= now px_delay <= +clk_period/8 px_delay -= (px_delay90*clk_period)/4; // -clk_period/8<= now px_delay <= +clk_period/8
MDF16(printk ("px_delay=%d, px_delay90=%d\r\n",px_delay,px_delay90)); MDF16(printk ("px_delay=%d, px_delay90=%d\n",px_delay,px_delay90));
px_delay/= FPGA_DCM_STEP; // in DCM steps px_delay/= FPGA_DCM_STEP; // in DCM steps
return (px_delay & 0xffff) | ((px_delay90 & 3) <<16) | 0x80000; return (px_delay & 0xffff) | ((px_delay90 & 3) <<16) | 0x80000;
} }
...@@ -1438,90 +1504,96 @@ int multisensor_pgm_sensorphase(int sensor_port, ///< sensor port ...@@ -1438,90 +1504,96 @@ int multisensor_pgm_sensorphase(int sensor_port, ///< sensor port
long * cableDelay; long * cableDelay;
long * FPGADelay; long * FPGADelay;
int clk_period; int clk_period;
long sdram_chen=thispars->pars[P_M10359_REGS+I2C359_SDRAM_CHEN]; // long sdram_chen=thispars->pars[P_M10359_REGS+I2C359_SDRAM_CHEN];
int adjustSDRAMNeed=0; // int adjustSDRAMNeed=0;
int thisPhaseSDRAM=thispars->pars[P_MULTI_PHASE_SDRAM]; // int thisPhaseSDRAM=thispars->pars[P_MULTI_PHASE_SDRAM];
int thisPhase1= thispars->pars[P_MULTI_PHASE1]; int thisPhase1= thispars->pars[P_MULTI_PHASE1];
int thisPhase2= thispars->pars[P_MULTI_PHASE2]; int thisPhase2= thispars->pars[P_MULTI_PHASE2];
int thisPhase3= thispars->pars[P_MULTI_PHASE3]; int thisPhase3= thispars->pars[P_MULTI_PHASE3];
unsigned long sensor_clk = 90000000; // just deafult if not yet set up
uint64_t ull_result = 1000000000000LL; uint64_t ull_result = 1000000000000LL;
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
if (frame16 >= 0) return -1; // can only work in ASAP mode if (frame16 >= 0) return -1; // can only work in ASAP mode
//changed (just set) clock frequency initiates calculation of phase settings //changed (just set) clock frequency initiates calculation of phase settings
if (!multi_phases_initialized || (thispars->pars[P_CLK_SENSOR] != prevpars->pars[P_CLK_SENSOR])) { // system clock is already set to the new frequency if (!multi_phases_initialized || (thispars->pars[P_CLK_SENSOR] != prevpars->pars[P_CLK_SENSOR])) { // system clock is already set to the new frequency
if (thispars->pars[P_CLK_SENSOR] == prevpars->pars[P_CLK_SENSOR]) { if (thispars->pars[P_CLK_SENSOR] == prevpars->pars[P_CLK_SENSOR]) {
printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); printk ("WARNING: ((thispars->pars[P_CLK_SENSOR] == prevpars->pars[P_CLK_SENSOR])) but multi_phases_initialized is not yet set (re-init?)\n"); dev_warn(g_dev_ptr,"WARNING: ((thispars->pars[P_CLK_SENSOR] == prevpars->pars[P_CLK_SENSOR])) but multi_phases_initialized is not yet set (re-init?)\n");
} }
multisensor_set_freq (sensor_port, 0, thispars); // not the first time. Assuming no clock chip if clock4 is not set multisensor_set_freq (sensor_port, 0, thispars); // not the first time. Assuming no clock chip if clock4 is not set
reset=1; reset=1;
// TODO: put here calculation of the sensor phases in 10359 from bitstream data and clock rate // TODO: put here calculation of the sensor phases in 10359 from bitstream data and clock rate
// clk_period= 1000000000000.0f/thispars->pars[P_CLK_SENSOR]; // period in ps // clk_period= 1000000000000.0f/thispars->pars[P_CLK_SENSOR]; // period in ps
if (!thispars->pars[P_CLK_SENSOR]){
dev_warn(g_dev_ptr,"Sensor clock is not set, using default 0x%lx\n",sensor_clk);
} else {
sensor_clk = thispars->pars[P_CLK_SENSOR];
}
do_div(ull_result,thispars->pars[P_CLK_SENSOR]); do_div(ull_result,thispars->pars[P_CLK_SENSOR]);
clk_period= ull_result; clk_period= ull_result;
// Now for each of 3 sensor ports of the 10359 // Now for each of 3 sensor ports of the 10359
cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C1); cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C1);
FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P1); FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P1);
thisPhase1=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000; thisPhase1=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000;
dev_dbg(g_dev_ptr,"%s cableDelay1=0x%lx FPGADelay1= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase1=0x%x\n",__func__,cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase1); dev_dbg(g_dev_ptr,"cableDelay1=0x%lx FPGADelay1= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase1=0x%x\n",cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase1);
cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C2); cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C2);
FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P2); FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P2);
thisPhase2=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000; thisPhase2=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000;
dev_dbg(g_dev_ptr,"%s cableDelay2=0x%lx FPGADelay2= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase3=0x%x\n",__func__,cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase2); dev_dbg(g_dev_ptr,"cableDelay2=0x%lx FPGADelay2= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase3=0x%x\n",cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase2);
cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C3); cableDelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_C3);
FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P3); FPGADelay= (long *) &GLOBALPARS(sensor_port, G_DLY359_P3);
thisPhase3=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000; thisPhase3=calcThisPhase(clk_period, FPGADelay[0], cableDelay[0], sensorproc_phys->sensor.sensorDelay) | 0x80000;
dev_dbg(g_dev_ptr,"%s cableDelay3=0x%lx FPGADelay3= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase3=0x%x\n",__func__,cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase3); dev_dbg(g_dev_ptr,"cableDelay3=0x%lx FPGADelay3= 0x%lx sensorproc_phys->sensor.sensorDelay=0x%x, thisPhase3=0x%x\n",cableDelay[0] ,FPGADelay[0], sensorproc_phys->sensor.sensorDelay,thisPhase3);
// TODO: calculate SDRAM phase here too. // TODO: calculate SDRAM phase here too.
adjustSDRAMNeed=1; // adjustSDRAMNeed=1;
multi_phases_initialized=1; multi_phases_initialized=1;
} }
if (reset) { if (reset) {
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SYSTEM, I2C359_DCM_RESET | I2C359_DCM_RESET90); MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SYSTEM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90); // MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM // multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
} }
#ifdef ADJUST_SDRAM_AT_SENSORPHASE
if ((thisPhaseSDRAM != prevpars->pars[P_MULTI_PHASE_SDRAM]) || adjustSDRAMNeed) { if ((thisPhaseSDRAM != prevpars->pars[P_MULTI_PHASE_SDRAM]) || adjustSDRAMNeed) {
if (adjustSDRAMNeed || (thisPhaseSDRAM & 0x200000)) { // at boot, after frequency change or manually requested (0x200000) if (adjustSDRAMNeed || (thisPhaseSDRAM & 0x200000)) { // at boot, after frequency change or manually requested (0x200000)
thisPhaseSDRAM=multisensor_adjustSDRAM (sensor_port, FPGA_DCM_RANGE); thisPhaseSDRAM=multisensor_adjustSDRAM (sensor_port, FPGA_DCM_RANGE);
if (thisPhaseSDRAM>=0) { if (thisPhaseSDRAM>=0) {
SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, thisPhaseSDRAM); SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, thisPhaseSDRAM);
printk("10359 SDRAM clock phase is set to %d/%s%d\n", dev_info(g_dev_ptr,"10359 SDRAM clock phase is set to %d/%s%d\n",
90*((thisPhaseSDRAM>>16) & 3), 90*((thisPhaseSDRAM>>16) & 3),
(thisPhaseSDRAM & 0x8000)?"-":"+", (thisPhaseSDRAM & 0x8000)?"-":"+",
(thisPhaseSDRAM & 0x8000)?(0x10000-(thisPhaseSDRAM & 0xffff)):(thisPhaseSDRAM & 0xffff)); (thisPhaseSDRAM & 0x8000)?(0x10000-(thisPhaseSDRAM & 0xffff)):(thisPhaseSDRAM & 0xffff));
} else { } else {
printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); dev_warn (g_dev_ptr,"**** ERROR adjusting SDRAM clock phase in %s:%d:%s, result=0x%x\n",__FILE__,__LINE__,__FUNCTION__,thisPhaseSDRAM);
printk ("**** ERROR adjusting SDRAM clock phase in %s:%d:%s, result=0x%x\n",__FILE__,__LINE__,__FUNCTION__,thisPhaseSDRAM); }
}
} else {
resetThisDCM=reset || (thisPhaseSDRAM & 0x80000);
rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SDRAM, resetThisDCM, thisPhaseSDRAM, prevpars->pars[P_MULTI_PHASE_SDRAM]);
if ((rslt>=0) && (rslt != thisPhaseSDRAM)) SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, rslt);
if (resetThisDCM) {
dev_dbg(g_dev_ptr,"%s re-initializing SDRAM on 10359 after DCM reset\n",__func__);
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
}
// Test memory phase here
printk ("\nMULTI_PHASE_SDRAM=%01x %04x\n", (rslt>>16), rslt & 0xffff);
if (thisPhaseSDRAM & 0x100000) {
for (rslt=0;rslt<16;rslt++) {
multisensor_memphase_debug(sensor_port, -1);
}
} else { } else {
multisensor_memphase_debug(sensor_port, 1); resetThisDCM=reset || (thisPhaseSDRAM & 0x80000);
rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SDRAM, resetThisDCM, thisPhaseSDRAM, prevpars->pars[P_MULTI_PHASE_SDRAM]);
if ((rslt>=0) && (rslt != thisPhaseSDRAM)) SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, rslt);
if (resetThisDCM) {
dev_dbg(g_dev_ptr,"re-initializing SDRAM on 10359 after DCM reset\n");
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
}
// Test memory phase here
dev_dbg(g_dev_ptr,"\nMULTI_PHASE_SDRAM=%01x %04x\n", (rslt>>16), rslt & 0xffff);
if (thisPhaseSDRAM & 0x100000) {
for (rslt=0;rslt<16;rslt++) {
multisensor_memphase_debug(sensor_port, -1);
}
} else {
multisensor_memphase_debug(sensor_port, 1);
#if 0 #if 0
printk ("\n"); printk ("\n");
multisensor_memphase_debug(0); multisensor_memphase_debug(0);
printk ("\n"); printk ("\n");
multisensor_memphase_debug(0); multisensor_memphase_debug(0);
#endif #endif
} }
} }
} }
#endif
if (thisPhase1 != prevpars->pars[P_MULTI_PHASE1]) { if (thisPhase1 != prevpars->pars[P_MULTI_PHASE1]) {
resetThisDCM=reset || (thisPhase1 & 0x80000); resetThisDCM=reset || (thisPhase1 & 0x80000);
rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SENSOR1, resetThisDCM, thisPhase1, prevpars->pars[P_MULTI_PHASE1]); rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SENSOR1, resetThisDCM, thisPhase1, prevpars->pars[P_MULTI_PHASE1]);
...@@ -1539,11 +1611,76 @@ int multisensor_pgm_sensorphase(int sensor_port, ///< sensor port ...@@ -1539,11 +1611,76 @@ int multisensor_pgm_sensorphase(int sensor_port, ///< sensor port
rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SENSOR3, resetThisDCM, thisPhase3, prevpars->pars[P_MULTI_PHASE3]); rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SENSOR3, resetThisDCM, thisPhase3, prevpars->pars[P_MULTI_PHASE3]);
if ((rslt>=0) && (rslt != thisPhase3)) SETFRAMEPARS_SET(P_MULTI_PHASE3, rslt); if ((rslt>=0) && (rslt != thisPhase3)) SETFRAMEPARS_SET(P_MULTI_PHASE3, rslt);
} }
MULTISENSOR_WRITE_I2C32_SHADOW(sensor_port, I2C359_SDRAM_CHEN, sdram_chen); // Restore 10359 SDRAM channels enable // MULTISENSOR_WRITE_I2C32_SHADOW(sensor_port, I2C359_SDRAM_CHEN, sdram_chen); // Restore 10359 SDRAM channels enable
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes, schedule functions if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0; return 0;
} }
/** Adjust SDRAM phase - should be done when sensor is stopped, it is a long procedure*/
int multisensor_pgm_sdram_phase(int sensor_port, ///< sensor port number (0..3)
struct sensor_t * sensor, ///< sensor static parameters (capabilities)
struct framepars_t * thispars, ///< sensor current parameters
struct framepars_t * prevpars, ///< sensor previous parameters (not used here)
int frame16) ///< 4-bit (hardware) frame number parameters should
///< be applied to, negative - ASAP
///< @return always 0
{
long sdram_chen=thispars->pars[P_M10359_REGS+I2C359_SDRAM_CHEN];
int adjustSDRAMNeed=0;
int thisPhaseSDRAM=thispars->pars[P_MULTI_PHASE_SDRAM];
int reset = 1; // always reset
int resetThisDCM;
int rslt=0;
struct frameparspair_t pars_to_update[6]; // ??? needed, increase if more entries will be added
int nupdate=0;
if (reset) {
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SDRAM, I2C359_DCM_RESET | I2C359_DCM_RESET90);
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
}
if ((thisPhaseSDRAM != prevpars->pars[P_MULTI_PHASE_SDRAM]) || adjustSDRAMNeed) {
if (adjustSDRAMNeed || (thisPhaseSDRAM & 0x200000)) { // at boot, after frequency change or manually requested (0x200000)
thisPhaseSDRAM=multisensor_adjustSDRAM (sensor_port, FPGA_DCM_RANGE);
if (thisPhaseSDRAM>=0) {
SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, thisPhaseSDRAM);
dev_info(g_dev_ptr,"10359 SDRAM clock phase is set to %d/%s%d\n",
90*((thisPhaseSDRAM>>16) & 3),
(thisPhaseSDRAM & 0x8000)?"-":"+",
(thisPhaseSDRAM & 0x8000)?(0x10000-(thisPhaseSDRAM & 0xffff)):(thisPhaseSDRAM & 0xffff));
} else {
dev_warn (g_dev_ptr,"**** ERROR adjusting SDRAM clock phase in %s:%d:%s, result=0x%x\n",__FILE__,__LINE__,__FUNCTION__,thisPhaseSDRAM);
}
} else {
resetThisDCM=reset || (thisPhaseSDRAM & 0x80000);
rslt= multisensor_set_phase (sensor_port, I2C359_DCM_SDRAM, resetThisDCM, thisPhaseSDRAM, prevpars->pars[P_MULTI_PHASE_SDRAM]);
if ((rslt>=0) && (rslt != thisPhaseSDRAM)) SETFRAMEPARS_SET(P_MULTI_PHASE_SDRAM, rslt);
if (resetThisDCM) {
dev_dbg(g_dev_ptr,"re-initializing SDRAM on 10359 after DCM reset\n");
multisensor_initSDRAM(sensor_port, thispars); // init 10359 SDRAM
}
// Test memory phase here
dev_dbg(g_dev_ptr,"\nMULTI_PHASE_SDRAM=%01x %04x\n", (rslt>>16), rslt & 0xffff);
if (thisPhaseSDRAM & 0x100000) {
for (rslt=0;rslt<16;rslt++) {
multisensor_memphase_debug(sensor_port, -1);
}
} else {
multisensor_memphase_debug(sensor_port, 1);
#if 0
printk ("\n");
multisensor_memphase_debug(0);
printk ("\n");
multisensor_memphase_debug(0);
#endif
}
}
}
MULTISENSOR_WRITE_I2C32_SHADOW(sensor_port, I2C359_SDRAM_CHEN, sdram_chen); // Restore 10359 SDRAM channels enable
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0;
}
/** Set 10359A clock frequency (take care of 10359-0) */ /** Set 10359A clock frequency (take care of 10359-0) */
int multisensor_set_freq (int sensor_port, ///< sensor port number (0..3) int multisensor_set_freq (int sensor_port, ///< sensor port number (0..3)
...@@ -1557,21 +1694,26 @@ int multisensor_set_freq (int sensor_port, ///< sensor port numb ...@@ -1557,21 +1694,26 @@ int multisensor_set_freq (int sensor_port, ///< sensor port numb
int rslt=0; int rslt=0;
int i; int i;
int was_sensor_freq=0; int was_sensor_freq=0;
if (!(GLOBALPARS(sensor_port, G_MULTI_CFG) && (1<<G_MULTI_CFG_SYSCLK))) { // skip local clock if disabled in configuration int clock_src= (GLOBALPARS(sensor_port, G_MULTI_CFG) && (1<<G_MULTI_CFG_SYSCLK))?I2C359_CLKSRC_SYSTEM:I2C359_CLKSRC_LOCAL;
// was_sensor_freq=getClockFreq(I2C359_CLK_NUMBER); was_sensor_freq=x393_getClockFreq(sensor_port, I2C359_CLK_NUMBER & 3); // clock 0
was_sensor_freq=x393_getClockFreq(sensor_port, I2C359_CLK_NUMBER & 3); // clock 0 dev_dbg(g_dev_ptr,"GLOBALPARS(%d, G_MULTI_CFG) = 0x%lx, was_sensor_freq=%d\n",sensor_port, GLOBALPARS(sensor_port, G_MULTI_CFG),was_sensor_freq);
if (first || (was_sensor_freq !=0)) { // Otherwise it is likely rev 0 - no clock if (first || (was_sensor_freq !=0)) { // Otherwise it is likely rev 0 - no clock
// was_sensor_freq=getClockFreq(1); // was_sensor_freq=getClockFreq(1);
was_sensor_freq=90000000; // TODO: Find out how to read actual clock frequency for sensor ports was_sensor_freq=90000000; // TODO: Find out how to read actual clock frequency for sensor ports
// i=setClockFreq(I2C359_CLK_NUMBER, was_sensor_freq); // i=setClockFreq(I2C359_CLK_NUMBER, was_sensor_freq);
i=x393_setClockFreq(sensor_port, I2C359_CLK_NUMBER & 3, was_sensor_freq);
// CY22393 probably has insufficient voltage to operate, bypassing it completely
if (clock_src == I2C359_CLKSRC_LOCAL) {
i=x393_setClockFreq(sensor_port, I2C359_CLK_NUMBER & 3, was_sensor_freq);
} else {
i=was_sensor_freq;
}
if (i>0) { if (i>0) {
MULTISENSOR_WRITE_I2C16_SHADOW(sensor_port, I2C359_CLKSRC, I2C359_CLKSRC_LOCAL); MULTISENSOR_WRITE_I2C16_SHADOW(sensor_port, I2C359_CLKSRC, clock_src);
mdelay (50); // 0.05 sec to stabilize clocks - will miss multiple frames mdelay (50); // 0.05 sec to stabilize clocks - will miss multiple frames
} else { } else {
was_sensor_freq=-1; // error was_sensor_freq=-1; // error
} }
}
} }
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SENSOR1, I2C359_DCM_RESET | I2C359_DCM_RESET90 | I2C359_DCM_HACT_RESET); MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SENSOR1, I2C359_DCM_RESET | I2C359_DCM_RESET90 | I2C359_DCM_HACT_RESET);
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SENSOR2, I2C359_DCM_RESET | I2C359_DCM_RESET90 | I2C359_DCM_HACT_RESET); MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_DCM_SENSOR2, I2C359_DCM_RESET | I2C359_DCM_RESET90 | I2C359_DCM_HACT_RESET);
...@@ -1673,7 +1815,7 @@ int multisensor_set_phase_recover(int sensor_port, ///< sensor port nu ...@@ -1673,7 +1815,7 @@ int multisensor_set_phase_recover(int sensor_port, ///< sensor port nu
else goodPhase = newPhase; else goodPhase = newPhase;
} }
rslt=goodPhase; rslt=goodPhase;
dev_dbg(g_dev_ptr,"%s Reduced NewPhase, goodPhase= 0x%lx oldPhase= 0x%lx\r\n",__func__, goodPhase, oldPhase ); dev_dbg(g_dev_ptr,"Reduced NewPhase, goodPhase= 0x%lx oldPhase= 0x%lx\n", goodPhase, oldPhase );
} }
return rslt; return rslt;
} }
...@@ -1689,48 +1831,48 @@ int multisensor_set_phase (int sensor_port, ///< sensor port number (0 ...@@ -1689,48 +1831,48 @@ int multisensor_set_phase (int sensor_port, ///< sensor port number (0
///< @return >= 0 - OK (returns new combined phase), ///< @return >= 0 - OK (returns new combined phase),
///< - -1 - no communication with 10359 ///< - -1 - no communication with 10359
{ {
int old_phase; int old_phase;
int old_phase90; int old_phase90;
int phase; int phase;
int phase90; int phase90;
int diff_phase; int diff_phase;
int diff_phase90; int diff_phase90;
int rslt=0; int rslt=0;
int i; int i;
MDF24(printk("reg_addr=0x%x resetDCM=%d newPhase90=0x%lx newPhase= 0x%lx oldPhase= 0x%lx\r\n",\ MDF24(printk("reg_addr=0x%x resetDCM=%d newPhase90=0x%lx newPhase= 0x%lx oldPhase= 0x%lx\n",\
reg_addr, resetDCM, newPhase>>16, newPhase & 0xffff, oldPhase )); reg_addr, resetDCM, newPhase>>16, newPhase & 0xffff, oldPhase ));
if (resetDCM || (newPhase & 0x8000)) { if (resetDCM || (newPhase & 0x8000)) {
MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_RESET | I2C359_DCM_RESET90); MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_RESET | I2C359_DCM_RESET90);
oldPhase=0; oldPhase=0;
} }
if (newPhase!=oldPhase) { if (newPhase!=oldPhase) {
dev_dbg(g_dev_ptr,"%s newPhase= 0x%lx oldPhase= 0x%lx\r\n",__func__, newPhase, oldPhase ); dev_dbg(g_dev_ptr,"newPhase= 0x%lx oldPhase= 0x%lx\n", newPhase, oldPhase );
old_phase= oldPhase & 0xffff; if (old_phase>=0x8000) old_phase-=0x10000; // make it signed old_phase= oldPhase & 0xffff; if (old_phase>=0x8000) old_phase-=0x10000; // make it signed
old_phase90= (oldPhase >> 16) & 3; old_phase90= (oldPhase >> 16) & 3;
if ((old_phase > 255) || (old_phase < -255)) { if ((old_phase > 255) || (old_phase < -255)) {
MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_RESET | I2C359_DCM_RESET90); MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_RESET | I2C359_DCM_RESET90);
old_phase= 0; old_phase= 0;
old_phase90= 0; old_phase90= 0;
} }
phase= newPhase & 0xffff; if (phase>= 0x8000) phase-= 0x10000; // make it signed phase= newPhase & 0xffff; if (phase>= 0x8000) phase-= 0x10000; // make it signed
phase90=(newPhase >> 16) & 3; phase90=(newPhase >> 16) & 3;
if (phase > 255) phase= 255; if (phase > 255) phase= 255;
else if (phase < -255) phase= -255; else if (phase < -255) phase= -255;
diff_phase= phase- old_phase; diff_phase= phase- old_phase;
diff_phase90=phase90-old_phase90; diff_phase90=phase90-old_phase90;
if (diff_phase90>2) diff_phase90-=4; if (diff_phase90>2) diff_phase90-=4;
else if (diff_phase90<-1)diff_phase90+=4; else if (diff_phase90<-1)diff_phase90+=4;
dev_dbg(g_dev_ptr,"%s old_phase= 0x%x old_phase90= 0x%x\r\n",__func__, old_phase, old_phase90 ); dev_dbg(g_dev_ptr,"old_phase= 0x%x old_phase90= 0x%x\n", old_phase, old_phase90 );
dev_dbg(g_dev_ptr,"%s phase= 0x%x phase90= 0x%x\r\n",__func__, phase, phase90 ); dev_dbg(g_dev_ptr,"phase= 0x%x phase90= 0x%x\n", phase, phase90 );
dev_dbg(g_dev_ptr,"%s diff_phase=0x%x diff_phase90=0x%x\r\n",__func__, diff_phase, diff_phase90 ); dev_dbg(g_dev_ptr,"diff_phase=0x%x diff_phase90=0x%x\n", diff_phase, diff_phase90 );
if (diff_phase > 0) for (i=diff_phase; i > 0; i--) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_INC ) if (diff_phase > 0) for (i=diff_phase; i > 0; i--) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_INC )
else if (diff_phase < 0) for (i=diff_phase; i < 0; i++) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_DEC ) else if (diff_phase < 0) for (i=diff_phase; i < 0; i++) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_DEC )
if (diff_phase90 > 0) for (i=diff_phase90; i > 0; i--) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_INC90 ) if (diff_phase90 > 0) for (i=diff_phase90; i > 0; i--) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_INC90 )
else if (diff_phase90 < 0) for (i=diff_phase90; i < 0; i++) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_DEC90 ) else if (diff_phase90 < 0) for (i=diff_phase90; i < 0; i++) MULTISENSOR_WRITE_I2C16(sensor_port, reg_addr, I2C359_DCM_DEC90 )
if (rslt) return -1; if (rslt) return -1;
return (phase & 0xffff) | (phase90 << 16); return (phase & 0xffff) | (phase90 << 16);
} }
return 0; return 0;
} }
...@@ -1803,18 +1945,18 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0.. ...@@ -1803,18 +1945,18 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0..
} }
} }
if (low90 < 0){ if (low90 < 0){
printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);
printk ("**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__);
printk ("oks90=%d, ok90=0x%x, centroids90=0x%x 0x%x 0x%x 0x%x\n",oks90,ok90,centroids90[0],centroids90[1],centroids90[2],centroids90[3]); dev_err(g_dev_ptr,"oks90=%d, ok90=0x%x, centroids90=0x%x 0x%x 0x%x 0x%x\n",oks90,ok90,centroids90[0],centroids90[1],centroids90[2],centroids90[3]);
return -1; return -1;
} }
break; break;
// was: fall through to default branch // was: fall through to default branch
default: default:
printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);
printk ("**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__);
printk ("oks90=%d, ok90=0x%x, centroids90=0x%x 0x%x 0x%x 0x%x\n",oks90,ok90,centroids90[0],centroids90[1],centroids90[2],centroids90[3]); dev_err(g_dev_ptr,"oks90=%d, ok90=0x%x, centroids90=0x%x 0x%x 0x%x 0x%x\n",oks90,ok90,centroids90[0],centroids90[1],centroids90[2],centroids90[3]);
return -1; return -1;
} }
// now find low margin // now find low margin
if (results90 [low90]) { // was bad if (results90 [low90]) { // was bad
...@@ -1832,18 +1974,18 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0.. ...@@ -1832,18 +1974,18 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0..
if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0 if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0
needReset=0; needReset=0;
while ((low_h-low_l)>1) { while ((low_h-low_l)>1) {
i=(low_l+low_h)/2; i=(low_l+low_h)/2;
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (low90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (low90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset
if (oldPhase<0) { if (oldPhase<0) {
MDF24 (printk(" DCM error=%d\n",-oldPhase)); dev_dbg(g_dev_ptr," DCM error=%d\n",-oldPhase);
needReset=1; needReset=1;
if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal
else low_l=i; // bad else low_l=i; // bad
} else { } else {
needReset=0; needReset=0;
if (multisensor_memphase (sensor_port,NULL)==0) low_h=i; // good if (multisensor_memphase (sensor_port,NULL)==0) low_h=i; // good
else low_l=i; // bad else low_l=i; // bad
} }
} }
// now find high margin // now find high margin
if (results90 [high90]) { // was bad if (results90 [high90]) { // was bad
...@@ -1857,35 +1999,35 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0.. ...@@ -1857,35 +1999,35 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0..
if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0 if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0
needReset=0; needReset=0;
while ((high_h-high_l)>1) { while ((high_h-high_l)>1) {
i=(high_h+high_l)/2; i=(high_h+high_l)/2;
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (high90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (high90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset
if (oldPhase<0) { if (oldPhase<0) {
MDF24 (printk(" DCM error=%d\n",-oldPhase)); dev_dbg(g_dev_ptr," DCM error=%d\n",-oldPhase);
needReset=1; needReset=1;
if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal
else high_h=i; // bad else high_h=i; // bad
} else { } else {
needReset=0; needReset=0;
if (multisensor_memphase (sensor_port,NULL)==0) high_l=i; // good if (multisensor_memphase (sensor_port,NULL)==0) high_l=i; // good
else high_h=i; // bad else high_h=i; // bad
} }
} }
MDF24 (printk(" low90=%d, low=%d, high90=%d, high=%d\n",low90,low_h,high90,high_l)); dev_dbg(g_dev_ptr,"low90=%d, low=%d, high90=%d, high=%d\n",low90,low_h,high90,high_l);
if (high90==low90) { // 0,1 OK phases if (high90==low90) { // 0,1 OK phases
if (high_l>low_h) { // 0,1 OK phases if (high_l>low_h) { // 0,1 OK phases
i= (high90<<16) | (((high_l+low_h)>>1) & 0xffff); i= (high90<<16) | (((high_l+low_h)>>1) & 0xffff);
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, i, oldPhase); // middle phase, same 90-degree oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, i, oldPhase); // middle phase, same 90-degree
if (oldPhase<0) return oldPhase; if (oldPhase<0) return oldPhase;
// Verify that final phase is OK // Verify that final phase is OK
if (multisensor_memphase (sensor_port,NULL)==0) return i; if (multisensor_memphase (sensor_port,NULL)==0) return i;
printk ("**** ERROR adjusting SDRAM clock phase (bad between two good points) in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"**** ERROR adjusting SDRAM clock phase (bad between two good points) in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__);
printk ("low90=%d, low_l=%d, high90=%d, high_l=%d, i=0x%x\n",low90, low_l, high90, high_l,i); dev_err(g_dev_ptr,"low90=%d, low_l=%d, high90=%d, high_l=%d, i=0x%x\n",low90, low_l, high90, high_l,i);
return -10; return -10;
} else { } else {
printk ("**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"**** ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__);
printk ("low90=%d, low_l=%d, high90=%d, high_l=%d\n",low90, low_l, high90, high_l); dev_err(g_dev_ptr,"low90=%d, low_l=%d, high90=%d, high_l=%d\n",low90, low_l, high90, high_l);
return -1; return -1;
} }
} }
// There were two good quarter phases (high90!=low90) // There were two good quarter phases (high90!=low90)
// two solution: 1 - put 45 calculate phase knowing the period and DCM step or // two solution: 1 - put 45 calculate phase knowing the period and DCM step or
...@@ -1902,7 +2044,7 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0.. ...@@ -1902,7 +2044,7 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0..
i=(low_l+low_h)/2; i=(low_l+low_h)/2;
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (low90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (low90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset
if (oldPhase<0) { if (oldPhase<0) {
MDF24 (printk(" DCM error=%d\n",-oldPhase)); dev_dbg(g_dev_ptr,"DCM error=%d\n",-oldPhase);
needReset=1; needReset=1;
if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal
else low_l=i; // bad else low_l=i; // bad
...@@ -1920,31 +2062,31 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0.. ...@@ -1920,31 +2062,31 @@ int multisensor_adjustSDRAM (int sensor_port, ///< sensor_port Sensor port (0..
if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0 if (oldPhase<0) return oldPhase; // any error is fatal here - fine phase is 0
needReset=0; needReset=0;
while ((high_h-high_l)>1) { while ((high_h-high_l)>1) {
i=(high_h+high_l)/2; i=(high_h+high_l)/2;
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (high90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, (high90<<16) | (i & 0xffff), oldPhase); // try middle phase, no DCM reset
if (oldPhase<0) { if (oldPhase<0) {
MDF24 (printk(" DCM error=%d\n",-oldPhase)); dev_dbg(g_dev_ptr,"DCM error=%d\n",-oldPhase);
needReset=1; needReset=1;
if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal if ((oldPhase!=-I2C359_DCM_ERR_OVFL) && (oldPhase!=-I2C359_DCM_ERR_NODONE)) return oldPhase; // other errors fatal
else high_h=i; // bad else high_h=i; // bad
} else { } else {
needReset=0; needReset=0;
if (multisensor_memphase (sensor_port, NULL)==0) high_l=i; // good if (multisensor_memphase (sensor_port, NULL)==0) high_l=i; // good
else high_h=i; // bad else high_h=i; // bad
} }
} }
} }
MDF24 (printk("Re-measured to the same 90-degree phase low90=%d, low=%d, high90=%d, high=%d\n",low90,low_h,high90,high_l)); dev_dbg(g_dev_ptr,"Re-measured to the same 90-degree phase low90=%d, low=%d, high90=%d, high=%d\n",low90,low_h,high90,high_l);
if (high_l>low_h) { // 0,1 OK phases if (high_l>low_h) { // 0,1 OK phases
i= (high90<<16) | (((high_l+low_h)>>1) & 0xffff); i= (high90<<16) | (((high_l+low_h)>>1) & 0xffff);
oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, i, oldPhase); // middle phase, same 90-degree oldPhase= multisensor_set_phase_verify (sensor_port, I2C359_DCM_SDRAM, needReset, i, oldPhase); // middle phase, same 90-degree
return oldPhase; // (both >=0 or error (<0) return oldPhase; // (both >=0 or error (<0)
} else { // something strange - should not get here } else { // something strange - should not get here
printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);
printk ("**** BUG - should not get here (there were two good 90-degree phases, now none)\n"); dev_err(g_dev_ptr,"**** BUG - should not get here (there were two good 90-degree phases, now none)\n");
printk ("ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__); dev_err(g_dev_ptr,"ERROR adjusting SDRAM clock phase in %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__);
printk ("low90=%d, low_l=%d, high90=%d, high_l=%d\n",low90, low_l, high90, high_l); dev_err(g_dev_ptr,"low90=%d, low_l=%d, high90=%d, high_l=%d\n",low90, low_l, high90, high_l);
return -1; return -1;
} }
} }
/** Measure SDRAM on 10359 board phase? */ /** Measure SDRAM on 10359 board phase? */
...@@ -1962,7 +2104,7 @@ int multisensor_memphase (int sensor_port, ///< Sensor port ...@@ -1962,7 +2104,7 @@ int multisensor_memphase (int sensor_port, ///< Sensor port
MULTISENSOR_WRITE_I2C32(sensor_port, I2C359_SDRAM_CHEN, I2C359_SDRAM_STOP(4) | I2C359_SDRAM_STOP(5)); // initialize write and read channels, reset SDRAM and buffer addresses MULTISENSOR_WRITE_I2C32(sensor_port, I2C359_SDRAM_CHEN, I2C359_SDRAM_STOP(4) | I2C359_SDRAM_STOP(5)); // initialize write and read channels, reset SDRAM and buffer addresses
MULTISENSOR_WRITE_I2C32(sensor_port, I2C359_SDRAM_CHEN, I2C359_SDRAM_RUN(4) | I2C359_SDRAM_RUN(5)); // enable write and read channels MULTISENSOR_WRITE_I2C32(sensor_port, I2C359_SDRAM_CHEN, I2C359_SDRAM_RUN(4) | I2C359_SDRAM_RUN(5)); // enable write and read channels
for (i=0; i<64;i++) { for (i=0; i<64;i++) {
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_DATA, (((i&7)==3) || ((i&7)==4) || ((i&7)==5))?0xffff:0); // pattern of 5 zeores, 3 ffff-s MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_DATA, (((i&7)==3) || ((i&7)==4) || ((i&7)==5))?0xffff:0); // pattern of 5 zeros, 3 ffff-s
} }
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_PAGE_WR, 0); // start page write MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_PAGE_WR, 0); // start page write
MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_PAGE_RD, 0); // start page read (expecting i2c to be much slower than page wr/rd MULTISENSOR_WRITE_I2C16(sensor_port, I2C359_SDRAM_PAGE_RD, 0); // start page read (expecting i2c to be much slower than page wr/rd
...@@ -1990,7 +2132,7 @@ int multisensor_memphase (int sensor_port, ///< Sensor port ...@@ -1990,7 +2132,7 @@ int multisensor_memphase (int sensor_port, ///< Sensor port
// for (i=0; i<8;i++) printk (" %03x ",setbits[i]); printk("\n"); // for (i=0; i<8;i++) printk (" %03x ",setbits[i]); printk("\n");
n=(0x10000*sx)/s; n=(0x10000*sx)/s;
if (centroid0x10000) centroid0x10000[0]=n; if (centroid0x10000) centroid0x10000[0]=n;
MDF24 (printk("centroid=0x%x, OK=%d\n",n,OK)); dev_err(g_dev_ptr,"centroid=0x%x, OK=%d\n",n,OK);
return OK?0:(n?n:1); // so if !OK but n=0 - return n=1 (1/0x10000, actually) return OK?0:(n?n:1); // so if !OK but n=0 - return n=1 (1/0x10000, actually)
} }
...@@ -2074,16 +2216,16 @@ int multisensor_pgm_sensorregs (int sensor_port, ///< sensor port ...@@ -2074,16 +2216,16 @@ int multisensor_pgm_sensorregs (int sensor_port, ///< sensor port
unsigned long bmask32= ((thispars->mod32) >> (P_M10359_REGS>>5)) & (( 1 << (P_M10359_NUMREGS >> 5))-1) ; unsigned long bmask32= ((thispars->mod32) >> (P_M10359_REGS>>5)) & (( 1 << (P_M10359_NUMREGS >> 5))-1) ;
unsigned long mask; unsigned long mask;
int index,index32; int index,index32;
dev_dbg(g_dev_ptr,"%s frame16=%d\n",__func__,frame16); dev_dbg(g_dev_ptr,"frame16=%d\n",frame16);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
dev_dbg(g_dev_ptr,"%s bmask32=0x%lx, thispars->mod32=0x%lx, P_M10359_REGS=0x%x, P_M10359_NUMREGS=0x%x\n",__func__,bmask32,thispars->mod32,P_M10359_REGS,P_M10359_NUMREGS); dev_dbg(g_dev_ptr,"bmask32=0x%lx, thispars->mod32=0x%lx, P_M10359_REGS=0x%x, P_M10359_NUMREGS=0x%x\n",bmask32,thispars->mod32,P_M10359_REGS,P_M10359_NUMREGS);
if (bmask32) { if (bmask32) {
for (index32=(P_M10359_REGS>>5); bmask32; index32++, bmask32 >>= 1) { for (index32=(P_M10359_REGS>>5); bmask32; index32++, bmask32 >>= 1) {
dev_dbg(g_dev_ptr,"%s index32=0x%x, bmask32=0x%lx\n",__func__,index32,bmask32); dev_dbg(g_dev_ptr,"index32=0x%x, bmask32=0x%lx\n",index32,bmask32);
if (bmask32 & 1) { if (bmask32 & 1) {
mask=thispars->mod[index32]; mask=thispars->mod[index32];
dev_dbg(g_dev_ptr,"%s mask=0x%lx\n",__func__,mask); dev_dbg(g_dev_ptr,"mask=0x%lx\n",mask);
for (index=(index32<<5); mask; index++, mask >>= 1) { for (index=(index32<<5); mask; index++, mask >>= 1) {
if (mask & 1) { if (mask & 1) {
SET_10359_REG (sensor_port, fpga_addr, (index-P_M10359_REGS), thispars->pars[index]); SET_10359_REG (sensor_port, fpga_addr, (index-P_M10359_REGS), thispars->pars[index]);
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
//#define I2C359_I2CMUX 0x07 //#define I2C359_I2CMUX 0x07
// #define I2C359_I2CMUX_2MEM 0x1 // #define I2C359_I2CMUX_2MEM 0x1
// #define I2C359_I2CMUX_2SENSORS 0x0 // #define I2C359_I2CMUX_2SENSORS 0x0
#define I2C359_CLKSRC 0x08 ///< register address: clock source #define I2C359_CLKSRC 0x08 ///< register address: clock source // does not read back
#define I2C359_CLKSRC_SYSTEM 0x00 ///< clock source: system (from the system board over) #define I2C359_CLKSRC_SYSTEM 0x00 ///< clock source: system (from the system board over)
#define I2C359_CLKSRC_LOCAL 0x01 ///< clock source: local (clock generator on the 10359 board #define I2C359_CLKSRC_LOCAL 0x01 ///< clock source: local (clock generator on the 10359 board
#define I2C359_MODE 0x09 ///< register address: mode register #define I2C359_MODE 0x09 ///< register address: mode register
......
...@@ -1096,6 +1096,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -1096,6 +1096,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
} }
// dh (decimation changed)? // dh (decimation changed)?
dh = thispars->pars[P_DCM_HOR]; dh = thispars->pars[P_DCM_HOR];
dh = dh?dh:1;
if (FRAMEPAR_MODIFIED(P_DCM_HOR)) { if (FRAMEPAR_MODIFIED(P_DCM_HOR)) {
if (dh<1) dh=1; else if (dh>32) dh=32; if (dh<1) dh=1; else if (dh>32) dh=32;
while ((dh>1) && !(sensor->dcmHor & (1 << (dh-1)))) dh--; // adjust decimation to maximal supported (if requested is not supported) while ((dh>1) && !(sensor->dcmHor & (1 << (dh-1)))) dh--; // adjust decimation to maximal supported (if requested is not supported)
...@@ -1103,6 +1104,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -1103,6 +1104,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
} }
// dv (decimation changed)? // dv (decimation changed)?
dv = thispars->pars[P_DCM_VERT]; dv = thispars->pars[P_DCM_VERT];
dv = dv?dv:1;
if (FRAMEPAR_MODIFIED(P_DCM_VERT)) { if (FRAMEPAR_MODIFIED(P_DCM_VERT)) {
if (dv<1) dv=1; else if (dv>32) dv=32; if (dv<1) dv=1; else if (dv>32) dv=32;
while ((dv>1) && !(sensor->dcmVert & (1 << (dv-1)))) dv--; // adjust decimation to maximal supported (if requested is not supported) while ((dv>1) && !(sensor->dcmVert & (1 << (dv-1)))) dv--; // adjust decimation to maximal supported (if requested is not supported)
...@@ -1110,6 +1112,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -1110,6 +1112,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
} }
// bh (binning changed)? // bh (binning changed)?
bh = thispars->pars[P_BIN_HOR]; bh = thispars->pars[P_BIN_HOR];
dv = dv?dv:1;
if (FRAMEPAR_MODIFIED(P_BIN_HOR)) { if (FRAMEPAR_MODIFIED(P_BIN_HOR)) {
if (bh<1) bh=1; else if (bh>dh) bh=dh; if (bh<1) bh=1; else if (bh>dh) bh=dh;
while ((bh>1) && !(sensor->binHor & (1 << (bh-1)))) bh--; // adjust binning to maximal supported (if requested is not supported) while ((bh>1) && !(sensor->binHor & (1 << (bh-1)))) bh--; // adjust binning to maximal supported (if requested is not supported)
...@@ -1117,6 +1120,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number ( ...@@ -1117,6 +1120,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
} }
// bv (binning changed)? // bv (binning changed)?
bv = thispars->pars[P_BIN_VERT]; bv = thispars->pars[P_BIN_VERT];
bv = bv?bv:1;
if (FRAMEPAR_MODIFIED(P_BIN_VERT)) { if (FRAMEPAR_MODIFIED(P_BIN_VERT)) {
if (bv<1) bv=1; else if (bv>dv) bv=dv; if (bv<1) bv=1; else if (bv>dv) bv=dv;
while ((bv>1) && !(sensor->binVert & (1 << (bv-1)))) bv--; // adjust binning to maximal supported (if requested is not supported) while ((bv>1) && !(sensor->binVert & (1 << (bv-1)))) bv--; // adjust binning to maximal supported (if requested is not supported)
...@@ -1437,7 +1441,7 @@ int pgm_sensorin (int sensor_port, ///< sensor port number (0..3 ...@@ -1437,7 +1441,7 @@ int pgm_sensorin (int sensor_port, ///< sensor port number (0..3
x393_gamma_ctl_t gamma_ctl = {.d32=0}; x393_gamma_ctl_t gamma_ctl = {.d32=0};
int bayer; int bayer;
int n_scan_lines, n_ph_lines; int n_scan_lines; //, n_ph_lines;
int flips; int flips;
int bayer_modified; int bayer_modified;
x393_mcntrl_frame_start_dly_t start_dly ={.d32=0}; x393_mcntrl_frame_start_dly_t start_dly ={.d32=0};
...@@ -1525,8 +1529,8 @@ int pgm_sensorin (int sensor_port, ///< sensor port number (0..3 ...@@ -1525,8 +1529,8 @@ int pgm_sensorin (int sensor_port, ///< sensor port number (0..3
if (FRAMEPAR_MODIFIED(P_MEMSENSOR_DLY) && ((start_dly.start_dly = thispars->pars[P_MEMSENSOR_DLY]))){ if (FRAMEPAR_MODIFIED(P_MEMSENSOR_DLY) && ((start_dly.start_dly = thispars->pars[P_MEMSENSOR_DLY]))){
X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mcntrl_scanline_start_delay, start_dly); X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mcntrl_scanline_start_delay, start_dly);
dev_dbg(g_dev_ptr,"{%d} Setting sensor-to-memory frame sync delay to %ld (0x%lx)\n",sensor_port, start_dly.start_dly,start_dly.start_dly); dev_dbg(g_dev_ptr,"{%d} Setting sensor-to-memory frame sync delay to %d (0x%x)\n",sensor_port, start_dly.start_dly,start_dly.start_dly);
MDP(DBGB_PADD, sensor_port,"Setting sensor-to-memory frame sync delay to %ld (0x%lx)\n", start_dly.start_dly,start_dly.start_dly) MDP(DBGB_PADD, sensor_port,"Setting sensor-to-memory frame sync delay to %d (0x%x)\n", start_dly.start_dly,start_dly.start_dly)
} }
...@@ -2400,8 +2404,8 @@ int pgm_focusmode (int sensor_port, ///< sensor port number (0..3 ...@@ -2400,8 +2404,8 @@ int pgm_focusmode (int sensor_port, ///< sensor port number (0..3
///< be applied to, negative - ASAP ///< be applied to, negative - ASAP
///< @return OK - 0, <0 - error ///< @return OK - 0, <0 - error
{ {
unsigned long flags; // unsigned long flags;
int i; // int i;
// x393_cmprs_table_addr_t table_addr; // x393_cmprs_table_addr_t table_addr;
struct { struct {
short left; short left;
...@@ -2884,7 +2888,7 @@ int pgm_compstop (int sensor_port, ///< sensor port number (0..3 ...@@ -2884,7 +2888,7 @@ int pgm_compstop (int sensor_port, ///< sensor port number (0..3
disable_need, disable_need,
(frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer (frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer
frame16); frame16);
dev_dbg(g_dev_ptr,"{%d} X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, sensor_port, frame16, cmprs_mode.d32); dev_dbg(g_dev_ptr,"{%d}@0x%lx: X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, getThisFrameNumber(sensor_port), sensor_port, frame16, cmprs_mode.d32);
MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n", sensor_port, frame16, cmprs_mode.d32) MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n", sensor_port, frame16, cmprs_mode.d32)
return 0; return 0;
...@@ -2913,7 +2917,7 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3 ...@@ -2913,7 +2917,7 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3
int disable_need = 1; // TODO: Use some G_* parameter int disable_need = 1; // TODO: Use some G_* parameter
x393_cmprs_mode_t cmprs_mode = {.d32=0}; x393_cmprs_mode_t cmprs_mode = {.d32=0};
int reset_frame = 0; int reset_frame = 0;
int just_started = 0; // int just_started = 0;
dev_dbg(g_dev_ptr,"{%d} frame16=%d, prevpars->pars[P_COMPRESSOR_RUN]=%d, thispars->pars[P_COMPRESSOR_RUN]=%d \n", dev_dbg(g_dev_ptr,"{%d} frame16=%d, prevpars->pars[P_COMPRESSOR_RUN]=%d, thispars->pars[P_COMPRESSOR_RUN]=%d \n",
sensor_port,frame16, (int) prevpars->pars[P_COMPRESSOR_RUN], (int) thispars->pars[P_COMPRESSOR_RUN]); sensor_port,frame16, (int) prevpars->pars[P_COMPRESSOR_RUN], (int) thispars->pars[P_COMPRESSOR_RUN]);
MDP(DBGB_PSFN, sensor_port,"frame16=%d, prevpars->pars[P_COMPRESSOR_RUN]=%d, thispars->pars[P_COMPRESSOR_RUN]=%d \n", MDP(DBGB_PSFN, sensor_port,"frame16=%d, prevpars->pars[P_COMPRESSOR_RUN]=%d, thispars->pars[P_COMPRESSOR_RUN]=%d \n",
...@@ -2958,7 +2962,8 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3 ...@@ -2958,7 +2962,8 @@ int pgm_compctl (int sensor_port, ///< sensor port number (0..3
X393_SEQ_SEND1 (sensor_port, frame16, x393_cmprs_control_reg, cmprs_mode); X393_SEQ_SEND1 (sensor_port, frame16, x393_cmprs_control_reg, cmprs_mode);
} }
dev_dbg(g_dev_ptr,"{%d} X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, sensor_port, frame16, cmprs_mode.d32); dev_dbg(g_dev_ptr,"{%d}@0x%lx: X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, getThisFrameNumber(sensor_port), sensor_port, frame16, cmprs_mode.d32);
MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n", sensor_port, frame16, cmprs_mode.d32) MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n", sensor_port, frame16, cmprs_mode.d32)
return 0; return 0;
......
...@@ -1141,16 +1141,21 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use ...@@ -1141,16 +1141,21 @@ int legacy_i2c(int ports) ///< bitmask of the sensor ports to use
for (sensor_port=0; sensor_port< SENSOR_PORTS; sensor_port++) if (ports & (1 << sensor_port)) { for (sensor_port=0; sensor_port< SENSOR_PORTS; sensor_port++) if (ports & (1 << sensor_port)) {
i2c_page_alloc_init(sensor_port); // reset all pages allocation i2c_page_alloc_init(sensor_port); // reset all pages allocation
i2c_page_register(sensor_port, class_10359->slave7); i2c_page_register(sensor_port, class_10359->slave7);
dev_dbg(g_dev_ptr, "Reset previously allocated pages for port= %d\n",sensor_port);
dev_dbg(g_dev_ptr, "Setting 10359 page for port %d, slave= 0x%x\n",sensor_port,class_10359->slave7);
set_xi2c_wrc(class_10359, sensor_port, class_10359->slave7, 0); set_xi2c_wrc(class_10359, sensor_port, class_10359->slave7, 0);
for (subchn = 0; subchn <4; subchn++){ // subchn == 0 - broadcast for (subchn = 0; subchn <4; subchn++){ // subchn == 0 - broadcast
dev_sensor.slave7 = class_sensor->slave7 + I2C359_INC * subchn; dev_sensor.slave7 = class_sensor->slave7 + I2C359_INC * subchn;
dev_dbg(g_dev_ptr, "Setting sensor page for port %d, slave= 0x%x\n",sensor_port,dev_sensor.slave7);
i2c_page_register(sensor_port, dev_sensor.slave7); i2c_page_register(sensor_port, dev_sensor.slave7);
set_xi2c_wrc(&dev_sensor, sensor_port, dev_sensor.slave7, 0); set_xi2c_wrc(&dev_sensor, sensor_port, dev_sensor.slave7, 0);
} }
// Now register one page for reading 10359 and the sensor using sensor speed data // Now register one page for reading 10359 and the sensor using sensor speed data
memcpy(&dev_sensor, class_sensor, sizeof(x393_i2c_device_t)); // dev_sensor)); memcpy(&dev_sensor, class_sensor, sizeof(x393_i2c_device_t)); // dev_sensor));
dev_dbg(g_dev_ptr, "Registering page to read senors 16-bit on port %d, page= 0x%x\n",sensor_port,LEGACY_READ_PAGE2);
i2c_page_register(sensor_port, LEGACY_READ_PAGE2); i2c_page_register(sensor_port, LEGACY_READ_PAGE2);
set_xi2c_rdc(&dev_sensor, sensor_port, LEGACY_READ_PAGE2); set_xi2c_rdc(&dev_sensor, sensor_port, LEGACY_READ_PAGE2);
dev_dbg(g_dev_ptr, "Registering page to read 32-bit data for 10359 on port %d, page= 0x%x\n",sensor_port,LEGACY_READ_PAGE4);
i2c_page_register(sensor_port, LEGACY_READ_PAGE4); i2c_page_register(sensor_port, LEGACY_READ_PAGE4);
dev_sensor.data_bytes=4; // for reading 10359 in 32-bit mode dev_sensor.data_bytes=4; // for reading 10359 in 32-bit mode
set_xi2c_rdc(&dev_sensor, sensor_port, LEGACY_READ_PAGE4); set_xi2c_rdc(&dev_sensor, sensor_port, LEGACY_READ_PAGE4);
......
...@@ -75,6 +75,9 @@ static u32 i2c_pages_shadow[4][256]; ///< Mostly for debugging to analyze i2c pa ...@@ -75,6 +75,9 @@ static u32 i2c_pages_shadow[4][256]; ///< Mostly for debugging to analyze i2c pa
static int sysfs_page[4]; ///< when positive - page locked for exclusive access static int sysfs_page[4]; ///< when positive - page locked for exclusive access
static struct device *sdev = NULL; ///< store this device here static struct device *sdev = NULL; ///< store this device here
static u32 i2c_read_data[4]; ///< last data read from i2c device static u32 i2c_read_data[4]; ///< last data read from i2c device
static int scale_i2c_speed = 256; // scale i2c speed for all devices, coefficint is scale_i2c_speed/256
static int max_unbalanced_writes = 32; // debug feature used in multi10359 - maximal writes to i2c w/o read
static int unbalanced_writes [SENSOR_PORTS] = {0,0,0,0};
//static DEFINE_SPINLOCK(lock); //static DEFINE_SPINLOCK(lock);
static DEFINE_SPINLOCK(sensori2c_lock_0); ///< static DEFINE_SPINLOCK(sensori2c_lock_0); ///<
...@@ -84,6 +87,39 @@ static DEFINE_SPINLOCK(sensori2c_lock_3); ///< ...@@ -84,6 +87,39 @@ static DEFINE_SPINLOCK(sensori2c_lock_3); ///<
/** Define array of pointers to locks - hardware allows concurrent writes to different ports tables */ /** Define array of pointers to locks - hardware allows concurrent writes to different ports tables */
spinlock_t * sensori2c_locks[4] = {&sensori2c_lock_0, &sensori2c_lock_1, &sensori2c_lock_2, &sensori2c_lock_3}; spinlock_t * sensori2c_locks[4] = {&sensori2c_lock_0, &sensori2c_lock_1, &sensori2c_lock_2, &sensori2c_lock_3};
/** Set status to autoupdate mode and wait for updated result (if it was not in autoupdate mode yet) */
void i2c_autoupdate_status(int chn) ///< Sensor port
{
#ifndef LOCK_BH_SENSORI2C
unsigned long flags;
#endif
x393_status_sens_i2c_t status;
x393_status_ctrl_t status_ctrl = get_x393_sensi2c_status_ctrl(chn); // last written data to status_cntrl
if (status_ctrl.mode != 3){
#ifdef LOCK_BH_SENSORI2C
spin_lock_bh(sensori2c_locks[chn]);
#else
spin_lock_irqsave(sensori2c_locks[chn],flags);
#endif
status = x393_sensi2c_status (chn);
status_ctrl.mode = 3;
status_ctrl.seq_num = status.seq_num ^ 0x20;
set_x393_sensi2c_status_ctrl(status_ctrl, chn);
{
int i;
for (i = 0; i < 10; i++) {
status = x393_sensi2c_status(chn);
if (likely(status.seq_num = status_ctrl.seq_num)) break;
}
}
#ifdef LOCK_BH_SENSORI2C
spin_unlock_bh(sensori2c_locks[chn]);
#else
spin_unlock_irqrestore(sensori2c_locks[chn],flags);
#endif
dev_dbg(sdev, "read_xi2c_fifo(%d): mode set to 3, status updated to 0x%08x\n",chn, (int) status.d32);
}
}
/** I2C sequencer stop/run/reset (also programs status if run)*/ /** I2C sequencer stop/run/reset (also programs status if run)*/
int i2c_stop_run_reset(int chn, ///< Sensor port int i2c_stop_run_reset(int chn, ///< Sensor port
...@@ -190,7 +226,7 @@ int i2c_page_alloc(int chn) ...@@ -190,7 +226,7 @@ int i2c_page_alloc(int chn)
#else #else
spin_unlock_irqrestore(sensori2c_locks[chn],flags); spin_unlock_irqrestore(sensori2c_locks[chn],flags);
#endif #endif
dev_dbg(sdev, "Allocated page= %d for port %d, is RESET(group= 0x%08x bits = 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x )\n", dev_dbg(sdev, "Allocated page= %d for port %d, (group= 0x%08x bits = 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x )\n",
(g << 5) + b, chn,free_i2c_groups[chn], (g << 5) + b, chn,free_i2c_groups[chn],
free_i2c_pages[chn][0],free_i2c_pages[chn][1],free_i2c_pages[chn][2],free_i2c_pages[chn][3], free_i2c_pages[chn][0],free_i2c_pages[chn][1],free_i2c_pages[chn][2],free_i2c_pages[chn][3],
free_i2c_pages[chn][4],free_i2c_pages[chn][5],free_i2c_pages[chn][6],free_i2c_pages[chn][7]); free_i2c_pages[chn][4],free_i2c_pages[chn][5],free_i2c_pages[chn][6],free_i2c_pages[chn][7]);
...@@ -277,7 +313,9 @@ void i2c_page_free(int chn, int page) ...@@ -277,7 +313,9 @@ void i2c_page_free(int chn, int page)
#else #else
spin_unlock_irqrestore(sensori2c_locks[chn],flags); spin_unlock_irqrestore(sensori2c_locks[chn],flags);
#endif #endif
dev_dbg(sdev, "Freed chn=%d, page=%d\n", chn, page);
} }
EXPORT_SYMBOL_GPL(i2c_page_free); EXPORT_SYMBOL_GPL(i2c_page_free);
/** Calculate value of SCLK 1/4 period delay from maximal SCL frequency /** Calculate value of SCLK 1/4 period delay from maximal SCL frequency
...@@ -288,7 +326,10 @@ int get_bit_delay(int khz) ...@@ -288,7 +326,10 @@ int get_bit_delay(int khz)
int dly; int dly;
if (!khz) if (!khz)
return 0; return 0;
dly = (1000 * mclk_mhz / 4)/khz; // Modified FPGA - added extra division
// dly = (1000 * mclk_mhz / 4)/khz;
// dly = (1000 * mclk_mhz / 8 )/khz; //
dly = (32000 * mclk_mhz / scale_i2c_speed )/khz; //
if (dly > 255) if (dly > 255)
dly = 255; dly = 255;
return dly; return dly;
...@@ -322,6 +363,8 @@ void set_xi2c_raw(int chn, ///< Sensor port number ...@@ -322,6 +363,8 @@ void set_xi2c_raw(int chn, ///< Sensor port number
#endif #endif
// i2c_pages_shadow[(chn << 8) + page] =tb_data.d32; // i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
i2c_pages_shadow[chn][page] =tb_data.d32; i2c_pages_shadow[chn][page] =tb_data.d32;
dev_dbg(sdev, "Channel = %d, page = %d, raw data = 0x%08x\n", chn, page, tb_data.d32);
} }
EXPORT_SYMBOL_GPL(set_xi2c_raw); EXPORT_SYMBOL_GPL(set_xi2c_raw);
...@@ -446,6 +489,8 @@ void set_xi2c_wr(int chn, ///< sensor port ...@@ -446,6 +489,8 @@ void set_xi2c_wr(int chn, ///< sensor port
#endif #endif
// i2c_pages_shadow[(chn << 8) + page] =tb_data.d32; // i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
i2c_pages_shadow[chn][page] =tb_data.d32; i2c_pages_shadow[chn][page] =tb_data.d32;
dev_dbg(sdev, "chn=%d, page = %d, tb_addr.d32=0x%08x, tb_data.d32 = 0x%08x\n",chn,page,tb_addr.d32,tb_data.d32);
} }
EXPORT_SYMBOL_GPL(set_xi2c_wr); EXPORT_SYMBOL_GPL(set_xi2c_wr);
...@@ -485,6 +530,7 @@ void set_xi2c_rd(int chn, ///< sensor port ...@@ -485,6 +530,7 @@ void set_xi2c_rd(int chn, ///< sensor port
#endif #endif
// i2c_pages_shadow[(chn << 8) + page] =tb_data.d32; // i2c_pages_shadow[(chn << 8) + page] =tb_data.d32;
i2c_pages_shadow[chn][page] =tb_data.d32; i2c_pages_shadow[chn][page] =tb_data.d32;
dev_dbg(sdev, "chn=%d, page = %d, tb_addr.d32=0x%08x, tb_data.d32 = 0x%08x\n",chn,page,tb_addr.d32,tb_data.d32);
} }
EXPORT_SYMBOL_GPL(set_xi2c_rd); EXPORT_SYMBOL_GPL(set_xi2c_rd);
...@@ -540,6 +586,7 @@ int write_xi2c_rel (int chn, ///< sensor port ...@@ -540,6 +586,7 @@ int write_xi2c_rel (int chn, ///< sensor port
} else { } else {
x393_sensi2c_rel (data[0], chn, offs); x393_sensi2c_rel (data[0], chn, offs);
} }
dev_dbg(sdev, "chn=%d, offs = %d, data[0] = 0x%08x\n",chn,offs,data[0]);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(write_xi2c_rel); EXPORT_SYMBOL_GPL(write_xi2c_rel);
...@@ -582,18 +629,37 @@ int write_xi2c_abs (int chn, ///< sensor port ...@@ -582,18 +629,37 @@ int write_xi2c_abs (int chn, ///< sensor port
} else { } else {
x393_sensi2c_abs (data[0], chn, offs); x393_sensi2c_abs (data[0], chn, offs);
} }
dev_dbg(sdev, "chn=%d, offs = %d, data[0] = 0x%08x\n",chn,offs,data[0]);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(write_xi2c_abs); EXPORT_SYMBOL_GPL(write_xi2c_abs);
u32 i2c_combine_page_addr_data8_16( int chn, ///< sensor port
int page, ///< index in the table (8 bits)
int addr, ///< register address (single byte for 8-bit data, LSB for 16 bit data)
int data) ///< 8/16 bit data to write
///< @ return combined page/address/data
{
x393_i2c_ctltbl_t i2c_ctltbl = {.d32= i2c_pages_shadow[chn][page]};
// i2c_ctltbl.d32 = i2c_pages_shadow[chn][page];
// if ((((x393_i2c_ctltbl_t) i2c_pages_shadow[chn][page]).nbwr > 2))
if (i2c_ctltbl.nbwr > 2)
return ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
else
return ((page & 0xff) << 24) | ((addr & 0xff) << 8) | (data & 0xff);
}
/** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ /** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */
void write_xi2c_reg16 (int chn, ///< sensor port void write_xi2c_reg16 (int chn, ///< sensor port
int page, ///< index in the table (8 bits) int page, ///< index in the table (8 bits)
int addr, ///< low byte of the register address (high is in the table), 8 bits int addr, ///< low byte of the register address (high is in the table), 8 bits
u32 data) ///< 16 or 8-bit data (LSB aligned) u32 data) ///< 16 or 8-bit data (LSB aligned), 16 address only for 16 bit data
{ {
u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); // u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
x393_sensi2c_rel (dw, chn, 0); x393_sensi2c_rel (dw, chn, 0);
dev_dbg(sdev, "i2c_pages_shadow[%d][0x%x]= 0x%08x addr=0x%x data=0x%x dw=0x%08x\n",
chn,page,i2c_pages_shadow[chn][page], addr,data, (int) dw);
} }
EXPORT_SYMBOL_GPL(write_xi2c_reg16); EXPORT_SYMBOL_GPL(write_xi2c_reg16);
...@@ -602,9 +668,10 @@ void write_xi2c_reg16_rel (int chn, ///< sensor port ...@@ -602,9 +668,10 @@ void write_xi2c_reg16_rel (int chn, ///< sensor port
int page, ///< index in the table (8 bits) int page, ///< index in the table (8 bits)
int frame, ///< relative frame number modulo PARS_FRAMES int frame, ///< relative frame number modulo PARS_FRAMES
int addr, ///< low byte of the register address (high is in the table), 8 bits int addr, ///< low byte of the register address (high is in the table), 8 bits
u32 data) ///< 16 or 8-bit data (LSB aligned) u32 data) ///< 16 or 8-bit data (LSB aligned), 16 address only for 16 bit data
{ {
u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); // u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
x393_sensi2c_rel (dw, chn, frame & PARS_FRAMES_MASK); x393_sensi2c_rel (dw, chn, frame & PARS_FRAMES_MASK);
} }
EXPORT_SYMBOL_GPL(write_xi2c_reg16_rel); EXPORT_SYMBOL_GPL(write_xi2c_reg16_rel);
...@@ -614,9 +681,10 @@ void write_xi2c_reg16_abs (int chn, ///< sensor port ...@@ -614,9 +681,10 @@ void write_xi2c_reg16_abs (int chn, ///< sensor port
int page, ///< index in the table (8 bits) int page, ///< index in the table (8 bits)
int frame, ///< absolute frame number modulo PARS_FRAMES int frame, ///< absolute frame number modulo PARS_FRAMES
int addr, ///< low byte of the register address (high is in the table), 8 bits int addr, ///< low byte of the register address (high is in the table), 8 bits
u32 data) ///< 16 or 8-bit data (LSB aligned) u32 data) ///< 16 or 8-bit data (LSB aligned), 16 address only for 16 bit data
{ {
u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); // u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK);
} }
EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs); EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs);
...@@ -627,9 +695,10 @@ void write_xi2c_reg16_abs_asap (int chn, ///< sensor port ...@@ -627,9 +695,10 @@ void write_xi2c_reg16_abs_asap (int chn, ///< sensor port
int page, ///< index in the table (8 bits) int page, ///< index in the table (8 bits)
int frame, ///< absolute frame number modulo PARS_FRAMES int frame, ///< absolute frame number modulo PARS_FRAMES
int addr, ///< low byte of the register address (high is in the table), 8 bits int addr, ///< low byte of the register address (high is in the table), 8 bits
u32 data) ///< 16 or 8-bit data (LSB aligned) u32 data) ///< 16 or 8-bit data (LSB aligned), 16 address only for 16 bit data
{ {
u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); // u32 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff);
u32 dw = i2c_combine_page_addr_data8_16(chn, page, addr, data);
if (frame<0) x393_sensi2c_rel (dw, chn, 0); if (frame<0) x393_sensi2c_rel (dw, chn, 0);
else x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); else x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK);
} }
...@@ -646,10 +715,13 @@ void read_xi2c (x393_i2c_device_t * dc, ///< device class ...@@ -646,10 +715,13 @@ void read_xi2c (x393_i2c_device_t * dc, ///< device class
{ {
u32 dw = ((page & 0xff) << 24) | (dc -> slave7 << 17) | (addr & 0xffff); u32 dw = ((page & 0xff) << 24) | (dc -> slave7 << 17) | (addr & 0xffff);
x393_sensi2c_rel (dw, chn, 0); x393_sensi2c_rel (dw, chn, 0);
dev_dbg(sdev, "chn=%d, page = %d, addr = %d\n",chn,page, addr);
} }
EXPORT_SYMBOL_GPL(read_xi2c); EXPORT_SYMBOL_GPL(read_xi2c);
/** Initiate sensor i2c read in immediate mode, specify 7-bit slave address /** Initiate sensor i2c read in immediate mode, specify 7-bit slave address
* (data itself has to be read from FIFO with read_xi2c_fifo) */ * (data itself has to be read from FIFO with read_xi2c_fifo) */
void read_xi2c_sa7 (int chn, ///< sensor port void read_xi2c_sa7 (int chn, ///< sensor port
...@@ -667,33 +739,8 @@ EXPORT_SYMBOL_GPL(read_xi2c_sa7); ...@@ -667,33 +739,8 @@ EXPORT_SYMBOL_GPL(read_xi2c_sa7);
int read_xi2c_frame(int chn) ///< sensor port number int read_xi2c_frame(int chn) ///< sensor port number
///< @return i2c sequencer frame number (4 bits) ///< @return i2c sequencer frame number (4 bits)
{ {
#ifndef LOCK_BH_SENSORI2C
unsigned long flags;
#endif
int i;
x393_status_sens_i2c_t status; x393_status_sens_i2c_t status;
x393_status_ctrl_t status_ctrl = get_x393_sensi2c_status_ctrl(chn); /* last written data to status_cntrl */ i2c_autoupdate_status(chn);
if (status_ctrl.mode != 3){
#ifdef LOCK_BH_SENSORI2C
spin_lock_bh(sensori2c_locks[chn]);
#else
spin_lock_irqsave(sensori2c_locks[chn],flags);
#endif
status = x393_sensi2c_status (chn);
status_ctrl.mode = 3;
status_ctrl.seq_num = status.seq_num ^ 0x20;
set_x393_sensi2c_status_ctrl(status_ctrl, chn);
for (i = 0; i < 10; i++) {
status = x393_sensi2c_status(chn);
if (likely(status.seq_num = status_ctrl.seq_num)) break;
}
#ifdef LOCK_BH_SENSORI2C
spin_unlock_bh(sensori2c_locks[chn]);
#else
spin_unlock_irqrestore(sensori2c_locks[chn],flags);
#endif
dev_dbg(sdev, "read_xi2c_frame(%d): mode set to 3, status updated to 0x%08x\n",chn, (int) status.d32);
}
status = x393_sensi2c_status (chn); status = x393_sensi2c_status (chn);
return (int) status.frame_num; return (int) status.frame_num;
} }
...@@ -704,34 +751,10 @@ EXPORT_SYMBOL_GPL(read_xi2c_frame); ...@@ -704,34 +751,10 @@ EXPORT_SYMBOL_GPL(read_xi2c_frame);
int read_xi2c_fifo(int chn) ///< sensor port int read_xi2c_fifo(int chn) ///< sensor port
///< @return byte or -1 if no data available, -EIO - error ///< @return byte or -1 if no data available, -EIO - error
{ {
#ifndef LOCK_BH_SENSORI2C
unsigned long flags;
#endif
int fifo_lsb, rslt,i; int fifo_lsb, rslt,i;
x393_i2c_ctltbl_t i2c_cmd; x393_i2c_ctltbl_t i2c_cmd;
x393_status_sens_i2c_t status; x393_status_sens_i2c_t status;
x393_status_ctrl_t status_ctrl = get_x393_sensi2c_status_ctrl(chn); /* last written data to status_cntrl */ i2c_autoupdate_status(chn);
if (status_ctrl.mode != 3){
#ifdef LOCK_BH_SENSORI2C
spin_lock_bh(sensori2c_locks[chn]);
#else
spin_lock_irqsave(sensori2c_locks[chn],flags);
#endif
status = x393_sensi2c_status (chn);
status_ctrl.mode = 3;
status_ctrl.seq_num = status.seq_num ^ 0x20;
set_x393_sensi2c_status_ctrl(status_ctrl, chn);
for (i = 0; i < 10; i++) {
status = x393_sensi2c_status(chn);
if (likely(status.seq_num = status_ctrl.seq_num)) break;
}
#ifdef LOCK_BH_SENSORI2C
spin_unlock_bh(sensori2c_locks[chn]);
#else
spin_unlock_irqrestore(sensori2c_locks[chn],flags);
#endif
dev_dbg(sdev, "read_xi2c_fifo(%d): mode set to 3, status updated to 0x%08x\n",chn, (int) status.d32);
}
status = x393_sensi2c_status (chn); status = x393_sensi2c_status (chn);
// dev_dbg(sdev, "read_xi2c_fifo(%d): status = 0x%08x\n",chn, (int) status.d32); // dev_dbg(sdev, "read_xi2c_fifo(%d): status = 0x%08x\n",chn, (int) status.d32);
if (!status.i2c_fifo_nempty) return -1; // No data available if (!status.i2c_fifo_nempty) return -1; // No data available
...@@ -779,7 +802,7 @@ int x393_xi2c_write_reg(const char * cname, ///< device class name ...@@ -779,7 +802,7 @@ int x393_xi2c_write_reg(const char * cname, ///< device class name
/* Set table entry for writing */ /* Set table entry for writing */
memcpy(&ds, dc, sizeof(ds)); memcpy(&ds, dc, sizeof(ds));
ds.slave7 = dc->slave7 + sa7_offs; ds.slave7 = dc->slave7 + sa7_offs;
set_xi2c_wrc(&ds, // device class set_xi2c_wrc(&ds, // device class
chn, // sensor port chn, // sensor port
page, // index in lookup table page, // index in lookup table
(reg_addr >> 8) & 0xff); // High byte of the i2c register address (reg_addr >> 8) & 0xff); // High byte of the i2c register address
...@@ -831,7 +854,7 @@ int x393_xi2c_read_reg( const char * cname, ///< device class name ...@@ -831,7 +854,7 @@ int x393_xi2c_read_reg( const char * cname, ///< device class name
/* Flush channel i2c read FIFO to make sure it is empty, status mode will be set, if needed */ /* Flush channel i2c read FIFO to make sure it is empty, status mode will be set, if needed */
while (read_xi2c_fifo(chn) >= 0) ; // includes waiting for status propagate while (read_xi2c_fifo(chn) >= 0) ; // includes waiting for status propagate
dev_dbg(sdev, "Flushed i2c read fifo for channel %d\n",chn); dev_dbg(sdev, "Flushed i2c read fifo for channel, running read_xi2c_sa7(%d,0x%x,0x%x, 0x%x)\n",chn, page & 0xff, (dc->slave7 + sa7_offs) & 0x7f, reg_addr & 0xffff);
/* Initiate i2c read */ /* Initiate i2c read */
read_xi2c_sa7 (chn, read_xi2c_sa7 (chn,
...@@ -859,12 +882,52 @@ int x393_xi2c_read_reg( const char * cname, ///< device class name ...@@ -859,12 +882,52 @@ int x393_xi2c_read_reg( const char * cname, ///< device class name
} }
/* Free table page */ /* Free table page */
dev_dbg(sdev, "Freeing i2c page %d\n",page); dev_dbg(sdev, "Freeing i2c page %d, got data 0x%x\n",page, datap[0]);
i2c_page_free(chn, page); i2c_page_free(chn, page);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(x393_xi2c_read_reg); EXPORT_SYMBOL_GPL(x393_xi2c_read_reg);
/** Test if i2c sequencer can accept more data (valid only for the same frame as last written
* In ASAP mode ready means that at least 64/4=16 locations is empty, this can be used when sequencer
* is stopped (no frame pulses) and data to be written is >64 items (i.e. programming 10359)
* in non-ASAP mode can be tested only after writing if needs to write more to the same page
* It will be ready again only if writing to a different page */
int x393_xi2c_ready_wr(int chn) ///< sensor port number
///< @return - 1 - ready, 0 - busy
{
x393_status_sens_i2c_t status;
i2c_autoupdate_status(chn);
status = x393_sensi2c_status (chn);
return status.wr_full? 0 : 1;
}
EXPORT_SYMBOL_GPL(x393_xi2c_ready_wr);
/** Wait for channel sequencer ready to accept more data
* It is valid for the same page as last written, most useful when writing ~>64 times in ASAP mode */
int x393_xi2c_wait_wr(int chn) ///< sensor port number
///< @return - OK, <0 -ETIMEDOUT
{
int rdy;
unsigned long timeout_end;
dev_dbg(sdev, "Waitoing i2c sequencer ready for channel %d\n",chn);
timeout_end = jiffies + tenth_sec;
while (jiffies < timeout_end){
if ((rdy=x393_xi2c_ready_wr( chn)))
break;
}
if (!rdy) {
dev_dbg(sdev, "Timeout waiting for i2c sequencer channel %d ready to accept more data\n",chn);
return -ETIMEDOUT;
}
return 0;
}
EXPORT_SYMBOL_GPL(x393_xi2c_wait_wr);
/** Single-command i2c read register compatible with legacy code. Device class(es) should already be registered, len parameter should /** Single-command i2c read register compatible with legacy code. Device class(es) should already be registered, len parameter should
* match pre-programmed length */ * match pre-programmed length */
int legacy_read_i2c_reg( int chn, ///< sensor port number int legacy_read_i2c_reg( int chn, ///< sensor port number
...@@ -906,6 +969,7 @@ int legacy_read_i2c_reg( int chn, ///< sensor port number ...@@ -906,6 +969,7 @@ int legacy_read_i2c_reg( int chn, ///< sensor port number
} }
*datap = (*datap <<8) | (db & 0xff); *datap = (*datap <<8) | (db & 0xff);
} }
reset_unbalanced_writes(chn);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(legacy_read_i2c_reg); EXPORT_SYMBOL_GPL(legacy_read_i2c_reg);
...@@ -1344,7 +1408,8 @@ static ssize_t set_i2c_tbl_rd_human(struct device *dev, ///< Linux ...@@ -1344,7 +1408,8 @@ static ssize_t set_i2c_tbl_rd_human(struct device *dev, ///< Linux
* - device register address, * - device register address,
* *
* Additional parameter * Additional parameter
* - data to write identifies write operation, if it is missing i2c read will be issued */ * - data to write identifies write operation, if it is missing i2c read will be issued
* This command wait for sequencer ready after writing */
static ssize_t i2c_store(struct device *dev, ///< Linux kernel basic device structure static ssize_t i2c_store(struct device *dev, ///< Linux kernel basic device structure
struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes
const char *buf, ///< 4K buffer with what was written const char *buf, ///< 4K buffer with what was written
...@@ -1381,6 +1446,8 @@ static ssize_t i2c_store(struct device *dev, ///< Linux kernel basi ...@@ -1381,6 +1446,8 @@ static ssize_t i2c_store(struct device *dev, ///< Linux kernel basi
sa7_offset, // slave address (7-bit) offset from the class defined slave address sa7_offset, // slave address (7-bit) offset from the class defined slave address
reg_addr, // register address (width is defined by class) reg_addr, // register address (width is defined by class)
reg_data); // data to write (width is defined by class) reg_data); // data to write (width is defined by class)
if (rslt < 0) return rslt;
if ((rslt = x393_xi2c_wait_wr(chn)) < 0) return rslt;
} }
return count; return count;
} }
...@@ -1459,12 +1526,69 @@ static ssize_t i2c_frame_store(struct device *dev, ///< Linux kerne ...@@ -1459,12 +1526,69 @@ static ssize_t i2c_frame_store(struct device *dev, ///< Linux kerne
default: default:
return - EINVAL; return - EINVAL;
} }
} }
return count;
}
//scale_i2c_speed
/** Show i2c speed scale (256 - normal speed, 128 - 1/2, 512 - 2x) */
static ssize_t i2c_speed_show(struct device *dev, ///< Linux kernel basic device structure
struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes
char *buf) ///< 4K buffer to receive response
///< @return offset to the end of the output data in the *buf buffer
{
return sprintf(buf,"%d\n",scale_i2c_speed);
}
static ssize_t i2c_speed_store(struct device *dev, ///< Linux kernel basic device structure
struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes
const char *buf, ///< 4K buffer with what was written
size_t count) ///< offset to the end of buffer data
///< @return new offset to the end of buffer data
{
if (sscanf(buf, "%i", &scale_i2c_speed)> 0) {
if (scale_i2c_speed<1) scale_i2c_speed = 1;
}
return count;
}
/** Show i2c speed scale (256 - normal speed, 128 - 1/2, 512 - 2x) */
static ssize_t i2c_max_unbalanced_writes_show(struct device *dev, ///< Linux kernel basic device structure
struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes
char *buf) ///< 4K buffer to receive response
///< @return offset to the end of the output data in the *buf buffer
{
return sprintf(buf,"%d\n",max_unbalanced_writes);
}
static ssize_t i2c_max_unbalanced_writes_store(struct device *dev, ///< Linux kernel basic device structure
struct device_attribute *attr, ///< Linux kernel interface for exporting device attributes
const char *buf, ///< 4K buffer with what was written
size_t count) ///< offset to the end of buffer data
///< @return new offset to the end of buffer data
{
sscanf(buf, "%i", &max_unbalanced_writes);
return count; return count;
} }
int i2c_get_max_unbalanced_writes(void) // ///@return - maximal number of unbalanced writes (w/o reads) - debug feature
{
return max_unbalanced_writes;
}
void reset_unbalanced_writes(int chn)
{
unbalanced_writes[chn]=0;
}
void inc_unbalanced_writes(int chn)
{
unbalanced_writes[chn]++;
}
int check_unbalanced_writes(int chn)
{
return unbalanced_writes[chn] > max_unbalanced_writes;
}
int get_unbalanced_writes(int chn)
{
return unbalanced_writes[chn];
}
//max_unbalanced_writes
// Sysfs top // Sysfs top
/* alloc*: read - allocate and return page, write (any data) - free page */ /* alloc*: read - allocate and return page, write (any data) - free page */
static DEVICE_ATTR(i2c_all , SYSFS_PERMISSIONS , i2c_class_show , i2c_class_store); static DEVICE_ATTR(i2c_all , SYSFS_PERMISSIONS , i2c_class_show , i2c_class_store);
...@@ -1497,6 +1621,8 @@ static DEVICE_ATTR(i2c_frame0 , SYSFS_PERMISSIONS , i2c_fr ...@@ -1497,6 +1621,8 @@ static DEVICE_ATTR(i2c_frame0 , SYSFS_PERMISSIONS , i2c_fr
static DEVICE_ATTR(i2c_frame1 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store); static DEVICE_ATTR(i2c_frame1 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store);
static DEVICE_ATTR(i2c_frame2 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store); static DEVICE_ATTR(i2c_frame2 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store);
static DEVICE_ATTR(i2c_frame3 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store); static DEVICE_ATTR(i2c_frame3 , SYSFS_PERMISSIONS , i2c_frame_show, i2c_frame_store);
static DEVICE_ATTR(i2c_speed, SYSFS_PERMISSIONS , i2c_speed_show, i2c_speed_store);
static DEVICE_ATTR(max_unbalanced_writes, SYSFS_PERMISSIONS , i2c_max_unbalanced_writes_show,i2c_max_unbalanced_writes_store);
static DEVICE_ATTR(help, SYSFS_PERMISSIONS & SYSFS_READONLY, get_i2c_help, NULL); static DEVICE_ATTR(help, SYSFS_PERMISSIONS & SYSFS_READONLY, get_i2c_help, NULL);
/** Contains entries for the root node (directory) of the sysfs representation for sensor-port i2c devices */ /** Contains entries for the root node (directory) of the sysfs representation for sensor-port i2c devices */
...@@ -1530,6 +1656,8 @@ static struct attribute *root_dev_attrs[] = { ...@@ -1530,6 +1656,8 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_i2c_frame1.attr, &dev_attr_i2c_frame1.attr,
&dev_attr_i2c_frame2.attr, &dev_attr_i2c_frame2.attr,
&dev_attr_i2c_frame3.attr, &dev_attr_i2c_frame3.attr,
&dev_attr_i2c_speed.attr,
&dev_attr_max_unbalanced_writes.attr,
&dev_attr_help.attr, &dev_attr_help.attr,
NULL NULL
}; };
...@@ -1665,7 +1793,7 @@ static int elphel393_sensor_i2c_remove(struct platform_device *pdev) ///< Platfo ...@@ -1665,7 +1793,7 @@ static int elphel393_sensor_i2c_remove(struct platform_device *pdev) ///< Platfo
dev_info(&pdev->dev,"Removing elphel393-sensor-i2c"); dev_info(&pdev->dev,"Removing elphel393-sensor-i2c");
return 0; return 0;
} }
/** Compatible records in Device Tree fro this driver */ /** Compatible records in Device Tree for this driver */
static struct of_device_id elphel393_sensor_i2c_of_match[] = { static struct of_device_id elphel393_sensor_i2c_of_match[] = {
{ .compatible = "elphel,elphel393-sensor-i2c-1.00", }, ///< Compatibility data { .compatible = "elphel,elphel393-sensor-i2c-1.00", }, ///< Compatibility data
{ /* end of table */} { /* end of table */}
......
...@@ -42,7 +42,7 @@ int read_xi2c_frame (int chn); ...@@ -42,7 +42,7 @@ int read_xi2c_frame (int chn);
int i2c_page_alloc (int chn); int i2c_page_alloc (int chn);
int i2c_page_register(int chn, int page); int i2c_page_register(int chn, int page);
void i2c_page_free (int chn, int page); void i2c_page_free (int chn, int page);
x393_i2c_device_t * xi2c_dev_get(const char * name); //x393_i2c_device_t * xi2c_dev_get(const char * name);
void set_xi2c_raw (int chn, int page, u32 data); void set_xi2c_raw (int chn, int page, u32 data);
void set_xi2c_wr (int chn,int page, int sa7, int rah, int num_bytes, int bit_delay); void set_xi2c_wr (int chn,int page, int sa7, int rah, int num_bytes, int bit_delay);
void set_xi2c_wrc (x393_i2c_device_t * dc, int chn, int page, int rah); void set_xi2c_wrc (x393_i2c_device_t * dc, int chn, int page, int rah);
...@@ -60,5 +60,13 @@ int read_xi2c_fifo (int chn); ...@@ -60,5 +60,13 @@ int read_xi2c_fifo (int chn);
x393_i2c_device_t * xi2c_dev_get(const char * name); x393_i2c_device_t * xi2c_dev_get(const char * name);
int x393_xi2c_write_reg(const char * cname, int chn, int sa7_offs, int reg_addr, int data); int x393_xi2c_write_reg(const char * cname, int chn, int sa7_offs, int reg_addr, int data);
int x393_xi2c_read_reg (const char * cname, int chn, int sa7_offs, int reg_addr, int * datap); int x393_xi2c_read_reg (const char * cname, int chn, int sa7_offs, int reg_addr, int * datap);
int x393_xi2c_ready_wr(int chn);
int x393_xi2c_wait_wr(int chn);
int legacy_read_i2c_reg(int chn, int page, int sa7, int reg_addr, int len, int * datap); int legacy_read_i2c_reg(int chn, int page, int sa7, int reg_addr, int len, int * datap);
int i2c_get_max_unbalanced_writes(void);
void reset_unbalanced_writes(int chn);
void inc_unbalanced_writes(int chn);
int check_unbalanced_writes(int chn);
int get_unbalanced_writes(int chn);
#endif #endif
...@@ -213,7 +213,7 @@ int setup_compressor_memory (int num_sensor, ///< sensor port number (0..3 ...@@ -213,7 +213,7 @@ int setup_compressor_memory (int num_sensor, ///< sensor port number (0..3
int frame_full_width = buffer_settings.frame_full_width[num_sensor] >> 4; int frame_full_width = buffer_settings.frame_full_width[num_sensor] >> 4;
int frame_sa_inc = frame_full_width * (buffer_settings.frame_height[num_sensor] >>3); int frame_sa_inc = frame_full_width * (buffer_settings.frame_height[num_sensor] >>3);
int last_frame_num = buffer_settings.frames_in_buffer[num_sensor] - 1; int last_frame_num = buffer_settings.frames_in_buffer[num_sensor] - 1;
int byte32 = 1; ///< 1 - 32-byte columns (currently used), 0 - 16 byte columns // int byte32 = 1; ///< 1 - 32-byte columns (currently used), 0 - 16 byte columns
x393_mcntrl_window_frame_sa_t window_frame_sa = {.d32=0}; x393_mcntrl_window_frame_sa_t window_frame_sa = {.d32=0};
x393_mcntrl_window_frame_sa_inc_t window_frame_sa_inc = {.d32=0}; x393_mcntrl_window_frame_sa_inc_t window_frame_sa_inc = {.d32=0};
...@@ -554,7 +554,7 @@ static int videomem_probe(struct platform_device *pdev) ...@@ -554,7 +554,7 @@ static int videomem_probe(struct platform_device *pdev)
int res; int res;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct of_device_id *match; const struct of_device_id *match;
const __be32 *bufsize_be; // const __be32 *bufsize_be;
struct device_node *node; struct device_node *node;
elphel393_videomem_sysfs_register(pdev); elphel393_videomem_sysfs_register(pdev);
......
...@@ -303,7 +303,9 @@ ...@@ -303,7 +303,9 @@
<li> bit 0 - "old" external mode (0 - internal, 1 - external ) <li> bit 0 - "old" external mode (0 - internal, 1 - external )
<li> bit 1 - enable(1) or disable(0) external trigger to stop clip <li> bit 1 - enable(1) or disable(0) external trigger to stop clip
<li> bit 2 - async (snapshot, ext trigger) mode, 0 - continuous NOTE: Only this bit is used now <li> bit 2 - async (snapshot, ext trigger) mode, 0 - continuous NOTE: Only this bit is used now
<li> bit 3 - no overlap, single frames: program - acquire/compress same frame</ul>*/ <li> bit 3 - no overlap, single frames: program - acquire/compress same frame
<li> bit 4 - global reset release (GRR) mode - (only when combined with bit 2)
</ul>*/
#define P_BGFRAME 16 ///< Background measurement mode - will use 16-bit mode and no FPN correction #define P_BGFRAME 16 ///< Background measurement mode - will use 16-bit mode and no FPN correction
//#define P_IMGSZMEM 17 ///< image size in video memory (calculated when channel 0 is programmed) NC393: Not used ??? //#define P_IMGSZMEM 17 ///< image size in video memory (calculated when channel 0 is programmed) NC393: Not used ???
//#define P_COMP_BAYER 17 ///< -> 119 derivative, readonly - calculated from P_BAYER and COMPMOD_BYRSH to separate sensor and compressor channels //#define P_COMP_BAYER 17 ///< -> 119 derivative, readonly - calculated from P_BAYER and COMPMOD_BYRSH to separate sensor and compressor channels
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment