Loading src/drivers/elphel/clock10359.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,6 @@ typedef struct { int calc_pll_params (unsigned int f, t_pll_params * pars); // f -in Hz int calc_pll_params (unsigned int f, t_pll_params * pars); // f -in Hz int setCYField (int sensor_port, int addr, int mask, int value); /// bus==1 - FPGA (sensor bus through 10359), 0 - CPU bus int setCYField (int sensor_port, int addr, int mask, int value); /// bus==1 - FPGA (sensor bus through 10359), 0 - CPU bus int setClockFreq(int nclock, int freq); // freq now in Hz int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz // t_pll_params pars; // t_pll_params pars; Loading Loading @@ -176,6 +175,7 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) { sensor_port, reg_addr, mask, value,reg_data); sensor_port, reg_addr, mask, value,reg_data); return error; return error; } } return 0; } } int x393_getClockFreq(int sensor_port, int nclock) { int x393_getClockFreq(int sensor_port, int nclock) { Loading src/drivers/elphel/framepars.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -115,7 +115,7 @@ #endif #endif /** /** * \def FRAMEPARS_DRIVER_NAME driver name to display * driver name to display */ */ #define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" #define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" Loading src/drivers/elphel/multi10359.c +2035 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes src/drivers/elphel/multi10359.h +139 −1 Original line number Original line Diff line number Diff line /***************************************************************************//** * @file multi10359.h * @brief Control of the 10359 multiplexer board * @copyright Copyright 2010-2016 (C) Elphel, Inc. * @par <b>License</b> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ /* // 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", "mt9p006 0x48 1 2 500", "el10359 0x08 1 2 500", "pca9500_eeprom 0x50 1 1 100", "cy22393 0x69 1 1 100"; */ //multisensor.h #define I2C359_INC 2 ///< slave address increment between sensors in 10359A board (broadcast, 1,2,3) (7 bits SA) #define I2C359_SLAVEADDR 0x08 ///< slave address of the 10359A board (move?) - 393 - use el10359 device class (7 bits SA) #define I2C359_VERSION 0x00 ///< register address: 32-bit FPGA bitstream version #define I2C359_MINVERSION 0x0359104b ///< Minimal FPGA version compatible with this software #define I2C359_DCM_SYSTEM 0x01 ///< register address: System DCM control #define I2C359_DCM_SDRAM 0x02 ///< register address: SDRAM DCM control #define I2C359_DCM_SENSOR1 0x03 ///< register address: sensor 1 DCM control #define I2C359_DCM_SENSOR2 0x04 ///< register address: sensor 2 DCM control #define I2C359_DCM_SENSOR3 0x05 ///< register address: sensor 3 DCM control #define I2C359_DCM_INC 0x01 ///< DCM control bits: increment phase by fine step #define I2C359_DCM_DEC 0x02 ///< DCM control bits: decrement phase by fine step #define I2C359_DCM_RESET 0x03 ///< DCM control bits: reset fine phase #define I2C359_DCM_INC90 0x04 ///< DCM control bits: increment phase by 90 degrees #define I2C359_DCM_DEC90 0x08 ///< DCM control bits: decrement phase by 90 degrees #define I2C359_DCM_RESET90 0x0c ///< DCM control bits: reset 90 degrees phase #define I2C359_DCM_HACT_INC 0x10 ///< DCM control bits: increment HACT phase #define I2C359_DCM_HACT_DEC 0x20 ///< DCM control bits: decrement HACT phase #define I2C359_DCM_HACT_RESET 0x30 ///< DCM control bits: reset HACT phase #define I2C359_CHNSEQ 0x06 ///< register address: channel select #define I2C359_SEQ(x,y,z) (((x)&3) | (((y)&3)<<2) | (((z)&3)<<4)) ///< Channels control: x - direct channel (no memory), ///< y - second, z - third. 0- disabled, 1..3 channels (J2,J3,J4) //#define I2C359_I2CMUX 0x07 // #define I2C359_I2CMUX_2MEM 0x1 // #define I2C359_I2CMUX_2SENSORS 0x0 #define I2C359_CLKSRC 0x08 ///< register address: clock source #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_MODE 0x09 ///< register address: mode register #define I2C359_MODE_RESET 0x01 ///< mode register bit: 1 - reset, 0 - normal operation (persistent) #define I2C359_MODE_DISABLE 0x02 ///< mode register bit: 1 - output disable reset, 0 - normal operation #define I2C359_MODE_MUTI_EN 0x04 ///< mode register bit: 1 - enable multisensor mode, 0 - single sensor #define I2C359_MODE_TEST_PATTERN 0x20 ///< mode register bit: 1 - enable test pattern from 10359, 0 - normal mode, sensor data #define I2C359_MODE_INDIVIDUAL 0x10 ///< mode register bit: 0 - single frame sync for all channels, 1 - each sensor frame with individual frame sync #define I2C359_MODE_PATTERN 0x20 ///< mode register bit: 1 - test pattern, 0 - sensor image #define I2C359_HACT_WIDTH 0x0a ///< register address: HACT duration when internally generated (I2C359_HACT_MODE==1), default 2596 #define I2C359_INTERFRAME_DELAY 0x0c ///< register address: delay between frames output, in lines. 16 bits . ///< Needed in separate frames mode, large frames, non jp4 #define I2C359_HACT_DLY 0x0d ///< register address: bit 0 - delay HACT in frame 2 by 1 clock cycle, ///< bit 1 - delay HACT in frame 3 by 1 c.c (to compensate for Bayer during hor. flips) #define I2C359_HACT_MODE 0x0e ///< register address: 0 - use sensor HACT, 1 - use leading edge from the sensor, ///< generate duration. Bit 0 sensor 0, 1 - 1, 2 - 2 #define I2C359_WIDTH2 0x13 ///< register address: line length for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 2596 #define I2C359_HEIGHT2 0x14 ///< register address: frame height for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 1940 #define I2C359_HBLANK2 0x15 ///< register address: horizontal blank for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 256 #define I2C359_VBLANK2 0x16 ///< register address: vertical blank (before active frame) for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 0 #define I2C359_WIDTH3 0x23 ///< register address: line length for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 2596 #define I2C359_HEIGHT3 0x24 ///< register address: frame height for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 1940 #define I2C359_HBLANK3 0x25 ///< register address: horizontal blank for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 256 #define I2C359_VBLANK3 0x26 ///< register address: vertical blank (before active frame) for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 0 #define I2C359_SDRAM_CHEN 0x40 ///< register address: SDRAM channels enable, LSW of 32-bit, should be sent after I2C359_MSW, will be applied together #define I2C359_SDRAM_RUN(x) (2 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=1, init=0 #define I2C359_SDRAM_STOP(x) (1 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=0, init=1 #define I2C359_SDRAM_PAUSE(x) (3 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=0, init=0 #define I2C359_SDRAM_MANCMD 0x41 ///< Manual commands (mode set) for SDRAM, LSW of 32-bit, should be sent after I2C359_MSW, will be applied together #define I2C359_SDRAM_MAGIC43 0x43 ///< register address: Undocumented #define I2C359_SDRAM_START0 0x44 ///< register address: SDRAM channel 0 start page number (each page 4096 pixels) #define I2C359_SDRAM_START1 0x45 ///< register address: SDRAM channel 1 start page number (each page 4096 pixels) #define I2C359_SDRAM_START2 0x46 ///< register address: SDRAM channel 2 start page number (each page 4096 pixels) #define I2C359_SDRAM_START3 0x47 ///< register address: SDRAM channel 3 start page number (each page 4096 pixels) #define I2C359_SDRAM_CONF01A 0x4c ///< register address: SDRAM channels 0,1 configuration A (with I2C359_MSW) #define I2C359_SDRAM_CONF23A 0x4d ///< register address: SDRAM channels 2,3 configuration A (with I2C359_MSW) #define I2C359_SDRAM_CONF01B 0x4e ///< register address: SDRAM channels 0,1 configuration B (with I2C359_MSW) #define I2C359_SDRAM_CONF23B 0x4f ///< register address: SDRAM channels 2,3 configuration B (with I2C359_MSW) #define I2C359_MSW 0x50 ///< register address: write 16 high bits of the next 32 bit word. Will be combined with other 16-bit writes #define I2C359_SDRAM_PAGE_WR 0x63 ///< register address: write any data to start 64-word page write to buffer #define I2C359_SDRAM_PAGE_RD 0x64 ///< register address: any data to start 64-word page read to buffer #define I2C359_SDRAM_DATA 0x70 ///< register address: 16-bit data to be written to channel 4 or read from channel5 #define I2C359_DCM_STATUS 0x0F ///< register address: readonly, status of DCMs #define I2C359_DCM_OFL(x,status) ((status) & (1<<((((x) & 3 ) <<2) +0))) ///< detect overflow, x = 0 - SDRAM, 1..3 - sensors (status - data read from I2C359_DCM_STATUS) #define I2C359_DCM_DONE(x,status) ((status) & (1<<((((x) & 3 ) <<2) +1))) ///< detect DONE, x = 0 - SDRAM, 1..3 - sensors #define I2C359_DCM_LOCKED(x,status) ((status) & (1<<((((x) & 3 ) <<2) +2))) ///< detect DCM locked, x = 0 - SDRAM, 1..3 - sensors #define I2C359_DCM_ERR_UNKNOWN 2 ///< Error code UNKNOWN #define I2C359_DCM_ERR_OVFL 3 ///< Error code OVERFLOW #define I2C359_DCM_ERR_NODONE 4 ///< Error code NOT DONE #define I2C359_DCM_ERR_NOLOCKED 5 ///< Error code NOT LOCKED /* CHEN_LOW,CHEN_HIGH - control 8 SDRAM channels + refresh (in CHEN_HIGH) each dibit: 0 - nop 1 - disable 2 - enable, init 3 - disable, init MANCMD_HIGH,MANCMD_LOW - data to be directly applied to SDRAM for 1 clock cycle */ //#define I2C359_CLK_NUMBER 4 // system clock number for the 10359A on-board clock generator int multisensor_pgm_detectsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16); /* struct frameparspair_t pars_to_update[8]; int nupdate=0; ... if (nupdate) setFramePars(thispars, nupdate, pars_to_update); /// save changes to sensor register shadows */ src/drivers/elphel/sensor_i2c.c +67 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <asm/uaccess.h> #include <asm/uaccess.h> #include "x393.h" #include "x393.h" #include "sensor_i2c.h" #include "sensor_i2c.h" #include <elphel/c313a.h> // PARS_FRAMES_MASK //------------------ //------------------ Loading Loading @@ -85,8 +86,10 @@ void i2c_page_alloc_init(void) for (i = 0; i < sizeof(sysfs_page)/sizeof(sysfs_page[0]); i++) sysfs_page[i] = -1; for (i = 0; i < sizeof(sysfs_page)/sizeof(sysfs_page[0]); i++) sysfs_page[i] = -1; } } /** Reserve i2c page (1 of 256) for a sensor port /** Reserve i2c page (1 of 256) for a sensor port * @param chn sensor port number (0..3) * @param chn sensor port number (0..3) * @return allocated page number or -ENOMEM if all pages are already used */ */ int i2c_page_alloc(int chn) int i2c_page_alloc(int chn) { { Loading @@ -109,6 +112,31 @@ int i2c_page_alloc(int chn) } } EXPORT_SYMBOL_GPL(i2c_page_alloc); EXPORT_SYMBOL_GPL(i2c_page_alloc); /** Register specific page, can be used with legacy software to register page equal to slave address, * and use 0xff for reading. Works with 1byhte addresses and 16-bit data */ int i2c_page_register(int chn, ///< Sensor port int page) ///< page to register (for legacy software, use 7-bit slave address ///< @return 0 on success, -ENOMEM if page is already registered { int g = page >> 5; int b = page & 0x1f; u32 * fb = free_i2c_pages + ((chn << 3) + g); spin_lock(&lock); if (unlikely(!(*fb & (1 << (31-b))))) { spin_unlock(&lock); return -ENOMEM; // page is already registered } *fb &= (1 << (31-b)); if (unlikely(*fb == 0)){ free_i2c_groups[chn] &= ~(1 << (31 - g)); } spin_unlock(&lock); return 0; } EXPORT_SYMBOL_GPL(i2c_page_register); /** Free i2c page /** Free i2c page * @param chn sensor port number (0..3) * @param chn sensor port number (0..3) * @param page i2c configuration page to release * @param page i2c configuration page to release Loading Loading @@ -355,6 +383,45 @@ void write_xi2c_reg16 (int chn, ///< sensor port } } EXPORT_SYMBOL_GPL(write_xi2c_reg16); EXPORT_SYMBOL_GPL(write_xi2c_reg16); /** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_rel (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< relative frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); x393_sensi2c_rel (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_rel); /** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_abs (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< absolute frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs); /** Compatibility with the legacy code: frame <0 - ASAP, >=0 - absolute * Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_abs_asap (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< absolute frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); if (frame<0) x393_sensi2c_abs (dw, chn, 0); else x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs); /** Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo) /** Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo) * Use slave address from provided class structure. * Use slave address from provided class structure. */ */ Loading Loading
src/drivers/elphel/clock10359.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -75,7 +75,6 @@ typedef struct { int calc_pll_params (unsigned int f, t_pll_params * pars); // f -in Hz int calc_pll_params (unsigned int f, t_pll_params * pars); // f -in Hz int setCYField (int sensor_port, int addr, int mask, int value); /// bus==1 - FPGA (sensor bus through 10359), 0 - CPU bus int setCYField (int sensor_port, int addr, int mask, int value); /// bus==1 - FPGA (sensor bus through 10359), 0 - CPU bus int setClockFreq(int nclock, int freq); // freq now in Hz int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz int calc_pll_params (unsigned int f, t_pll_params * pars) { // f -in Hz // t_pll_params pars; // t_pll_params pars; Loading Loading @@ -176,6 +175,7 @@ int setCYField (int sensor_port, int reg_addr, int mask, int value) { sensor_port, reg_addr, mask, value,reg_data); sensor_port, reg_addr, mask, value,reg_data); return error; return error; } } return 0; } } int x393_getClockFreq(int sensor_port, int nclock) { int x393_getClockFreq(int sensor_port, int nclock) { Loading
src/drivers/elphel/framepars.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -115,7 +115,7 @@ #endif #endif /** /** * \def FRAMEPARS_DRIVER_NAME driver name to display * driver name to display */ */ #define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" #define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" Loading
src/drivers/elphel/multi10359.c +2035 −1 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/drivers/elphel/multi10359.h +139 −1 Original line number Original line Diff line number Diff line /***************************************************************************//** * @file multi10359.h * @brief Control of the 10359 multiplexer board * @copyright Copyright 2010-2016 (C) Elphel, Inc. * @par <b>License</b> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ /* // 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", "mt9p006 0x48 1 2 500", "el10359 0x08 1 2 500", "pca9500_eeprom 0x50 1 1 100", "cy22393 0x69 1 1 100"; */ //multisensor.h #define I2C359_INC 2 ///< slave address increment between sensors in 10359A board (broadcast, 1,2,3) (7 bits SA) #define I2C359_SLAVEADDR 0x08 ///< slave address of the 10359A board (move?) - 393 - use el10359 device class (7 bits SA) #define I2C359_VERSION 0x00 ///< register address: 32-bit FPGA bitstream version #define I2C359_MINVERSION 0x0359104b ///< Minimal FPGA version compatible with this software #define I2C359_DCM_SYSTEM 0x01 ///< register address: System DCM control #define I2C359_DCM_SDRAM 0x02 ///< register address: SDRAM DCM control #define I2C359_DCM_SENSOR1 0x03 ///< register address: sensor 1 DCM control #define I2C359_DCM_SENSOR2 0x04 ///< register address: sensor 2 DCM control #define I2C359_DCM_SENSOR3 0x05 ///< register address: sensor 3 DCM control #define I2C359_DCM_INC 0x01 ///< DCM control bits: increment phase by fine step #define I2C359_DCM_DEC 0x02 ///< DCM control bits: decrement phase by fine step #define I2C359_DCM_RESET 0x03 ///< DCM control bits: reset fine phase #define I2C359_DCM_INC90 0x04 ///< DCM control bits: increment phase by 90 degrees #define I2C359_DCM_DEC90 0x08 ///< DCM control bits: decrement phase by 90 degrees #define I2C359_DCM_RESET90 0x0c ///< DCM control bits: reset 90 degrees phase #define I2C359_DCM_HACT_INC 0x10 ///< DCM control bits: increment HACT phase #define I2C359_DCM_HACT_DEC 0x20 ///< DCM control bits: decrement HACT phase #define I2C359_DCM_HACT_RESET 0x30 ///< DCM control bits: reset HACT phase #define I2C359_CHNSEQ 0x06 ///< register address: channel select #define I2C359_SEQ(x,y,z) (((x)&3) | (((y)&3)<<2) | (((z)&3)<<4)) ///< Channels control: x - direct channel (no memory), ///< y - second, z - third. 0- disabled, 1..3 channels (J2,J3,J4) //#define I2C359_I2CMUX 0x07 // #define I2C359_I2CMUX_2MEM 0x1 // #define I2C359_I2CMUX_2SENSORS 0x0 #define I2C359_CLKSRC 0x08 ///< register address: clock source #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_MODE 0x09 ///< register address: mode register #define I2C359_MODE_RESET 0x01 ///< mode register bit: 1 - reset, 0 - normal operation (persistent) #define I2C359_MODE_DISABLE 0x02 ///< mode register bit: 1 - output disable reset, 0 - normal operation #define I2C359_MODE_MUTI_EN 0x04 ///< mode register bit: 1 - enable multisensor mode, 0 - single sensor #define I2C359_MODE_TEST_PATTERN 0x20 ///< mode register bit: 1 - enable test pattern from 10359, 0 - normal mode, sensor data #define I2C359_MODE_INDIVIDUAL 0x10 ///< mode register bit: 0 - single frame sync for all channels, 1 - each sensor frame with individual frame sync #define I2C359_MODE_PATTERN 0x20 ///< mode register bit: 1 - test pattern, 0 - sensor image #define I2C359_HACT_WIDTH 0x0a ///< register address: HACT duration when internally generated (I2C359_HACT_MODE==1), default 2596 #define I2C359_INTERFRAME_DELAY 0x0c ///< register address: delay between frames output, in lines. 16 bits . ///< Needed in separate frames mode, large frames, non jp4 #define I2C359_HACT_DLY 0x0d ///< register address: bit 0 - delay HACT in frame 2 by 1 clock cycle, ///< bit 1 - delay HACT in frame 3 by 1 c.c (to compensate for Bayer during hor. flips) #define I2C359_HACT_MODE 0x0e ///< register address: 0 - use sensor HACT, 1 - use leading edge from the sensor, ///< generate duration. Bit 0 sensor 0, 1 - 1, 2 - 2 #define I2C359_WIDTH2 0x13 ///< register address: line length for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 2596 #define I2C359_HEIGHT2 0x14 ///< register address: frame height for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 1940 #define I2C359_HBLANK2 0x15 ///< register address: horizontal blank for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 256 #define I2C359_VBLANK2 0x16 ///< register address: vertical blank (before active frame) for memory channel 1 (2-nd frame in sequence). ///< 16 bit (no I2C359_MSW), default 0 #define I2C359_WIDTH3 0x23 ///< register address: line length for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 2596 #define I2C359_HEIGHT3 0x24 ///< register address: frame height for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 1940 #define I2C359_HBLANK3 0x25 ///< register address: horizontal blank for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 256 #define I2C359_VBLANK3 0x26 ///< register address: vertical blank (before active frame) for memory channel 3 (3-rd frame in sequence). ///< 16 bit (no I2C359_MSW), default 0 #define I2C359_SDRAM_CHEN 0x40 ///< register address: SDRAM channels enable, LSW of 32-bit, should be sent after I2C359_MSW, will be applied together #define I2C359_SDRAM_RUN(x) (2 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=1, init=0 #define I2C359_SDRAM_STOP(x) (1 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=0, init=1 #define I2C359_SDRAM_PAUSE(x) (3 << (x <<1)) ///< SDRAM channels enable for channel x (0..7), enable=0, init=0 #define I2C359_SDRAM_MANCMD 0x41 ///< Manual commands (mode set) for SDRAM, LSW of 32-bit, should be sent after I2C359_MSW, will be applied together #define I2C359_SDRAM_MAGIC43 0x43 ///< register address: Undocumented #define I2C359_SDRAM_START0 0x44 ///< register address: SDRAM channel 0 start page number (each page 4096 pixels) #define I2C359_SDRAM_START1 0x45 ///< register address: SDRAM channel 1 start page number (each page 4096 pixels) #define I2C359_SDRAM_START2 0x46 ///< register address: SDRAM channel 2 start page number (each page 4096 pixels) #define I2C359_SDRAM_START3 0x47 ///< register address: SDRAM channel 3 start page number (each page 4096 pixels) #define I2C359_SDRAM_CONF01A 0x4c ///< register address: SDRAM channels 0,1 configuration A (with I2C359_MSW) #define I2C359_SDRAM_CONF23A 0x4d ///< register address: SDRAM channels 2,3 configuration A (with I2C359_MSW) #define I2C359_SDRAM_CONF01B 0x4e ///< register address: SDRAM channels 0,1 configuration B (with I2C359_MSW) #define I2C359_SDRAM_CONF23B 0x4f ///< register address: SDRAM channels 2,3 configuration B (with I2C359_MSW) #define I2C359_MSW 0x50 ///< register address: write 16 high bits of the next 32 bit word. Will be combined with other 16-bit writes #define I2C359_SDRAM_PAGE_WR 0x63 ///< register address: write any data to start 64-word page write to buffer #define I2C359_SDRAM_PAGE_RD 0x64 ///< register address: any data to start 64-word page read to buffer #define I2C359_SDRAM_DATA 0x70 ///< register address: 16-bit data to be written to channel 4 or read from channel5 #define I2C359_DCM_STATUS 0x0F ///< register address: readonly, status of DCMs #define I2C359_DCM_OFL(x,status) ((status) & (1<<((((x) & 3 ) <<2) +0))) ///< detect overflow, x = 0 - SDRAM, 1..3 - sensors (status - data read from I2C359_DCM_STATUS) #define I2C359_DCM_DONE(x,status) ((status) & (1<<((((x) & 3 ) <<2) +1))) ///< detect DONE, x = 0 - SDRAM, 1..3 - sensors #define I2C359_DCM_LOCKED(x,status) ((status) & (1<<((((x) & 3 ) <<2) +2))) ///< detect DCM locked, x = 0 - SDRAM, 1..3 - sensors #define I2C359_DCM_ERR_UNKNOWN 2 ///< Error code UNKNOWN #define I2C359_DCM_ERR_OVFL 3 ///< Error code OVERFLOW #define I2C359_DCM_ERR_NODONE 4 ///< Error code NOT DONE #define I2C359_DCM_ERR_NOLOCKED 5 ///< Error code NOT LOCKED /* CHEN_LOW,CHEN_HIGH - control 8 SDRAM channels + refresh (in CHEN_HIGH) each dibit: 0 - nop 1 - disable 2 - enable, init 3 - disable, init MANCMD_HIGH,MANCMD_LOW - data to be directly applied to SDRAM for 1 clock cycle */ //#define I2C359_CLK_NUMBER 4 // system clock number for the 10359A on-board clock generator int multisensor_pgm_detectsensor (int sensor_port, struct sensor_t * sensor, struct framepars_t * thispars, struct framepars_t * prevpars, int frame16); /* struct frameparspair_t pars_to_update[8]; int nupdate=0; ... if (nupdate) setFramePars(thispars, nupdate, pars_to_update); /// save changes to sensor register shadows */
src/drivers/elphel/sensor_i2c.c +67 −0 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <asm/uaccess.h> #include <asm/uaccess.h> #include "x393.h" #include "x393.h" #include "sensor_i2c.h" #include "sensor_i2c.h" #include <elphel/c313a.h> // PARS_FRAMES_MASK //------------------ //------------------ Loading Loading @@ -85,8 +86,10 @@ void i2c_page_alloc_init(void) for (i = 0; i < sizeof(sysfs_page)/sizeof(sysfs_page[0]); i++) sysfs_page[i] = -1; for (i = 0; i < sizeof(sysfs_page)/sizeof(sysfs_page[0]); i++) sysfs_page[i] = -1; } } /** Reserve i2c page (1 of 256) for a sensor port /** Reserve i2c page (1 of 256) for a sensor port * @param chn sensor port number (0..3) * @param chn sensor port number (0..3) * @return allocated page number or -ENOMEM if all pages are already used */ */ int i2c_page_alloc(int chn) int i2c_page_alloc(int chn) { { Loading @@ -109,6 +112,31 @@ int i2c_page_alloc(int chn) } } EXPORT_SYMBOL_GPL(i2c_page_alloc); EXPORT_SYMBOL_GPL(i2c_page_alloc); /** Register specific page, can be used with legacy software to register page equal to slave address, * and use 0xff for reading. Works with 1byhte addresses and 16-bit data */ int i2c_page_register(int chn, ///< Sensor port int page) ///< page to register (for legacy software, use 7-bit slave address ///< @return 0 on success, -ENOMEM if page is already registered { int g = page >> 5; int b = page & 0x1f; u32 * fb = free_i2c_pages + ((chn << 3) + g); spin_lock(&lock); if (unlikely(!(*fb & (1 << (31-b))))) { spin_unlock(&lock); return -ENOMEM; // page is already registered } *fb &= (1 << (31-b)); if (unlikely(*fb == 0)){ free_i2c_groups[chn] &= ~(1 << (31 - g)); } spin_unlock(&lock); return 0; } EXPORT_SYMBOL_GPL(i2c_page_register); /** Free i2c page /** Free i2c page * @param chn sensor port number (0..3) * @param chn sensor port number (0..3) * @param page i2c configuration page to release * @param page i2c configuration page to release Loading Loading @@ -355,6 +383,45 @@ void write_xi2c_reg16 (int chn, ///< sensor port } } EXPORT_SYMBOL_GPL(write_xi2c_reg16); EXPORT_SYMBOL_GPL(write_xi2c_reg16); /** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_rel (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< relative frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); x393_sensi2c_rel (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_rel); /** Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_abs (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< absolute frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs); /** Compatibility with the legacy code: frame <0 - ASAP, >=0 - absolute * Write sensor 16 bit (or 8 bit as programmed in the table) data in immediate mode */ void write_xi2c_reg16_abs_asap (int chn, ///< sensor port int page, ///< index in the table (8 bits) int frame, ///< absolute frame number modulo PARS_FRAMES 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 dw = ((page & 0xff) << 24) | ((addr & 0xff) << 16) | (data & 0xffff); if (frame<0) x393_sensi2c_abs (dw, chn, 0); else x393_sensi2c_abs (dw, chn, frame & PARS_FRAMES_MASK); } EXPORT_SYMBOL_GPL(write_xi2c_reg16_abs); /** Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo) /** Initiate sensor i2c read in immediate mode (data itself has to be read from FIFO with read_xi2c_fifo) * Use slave address from provided class structure. * Use slave address from provided class structure. */ */ Loading