Compare commits

..

29 Commits

Author SHA1 Message Date
a324c5b05e Fix gain documentation on Driver 2021-04-05 08:31:27 -06:00
7d7bad60d3 Update script to control gain and exposure 2021-04-05 00:22:44 -06:00
71bc9b31dd Set gain to range 32-255 -> 100.000-796.875 2021-04-05 00:18:35 -06:00
6d982b1ebe Set gain to range 32-255 -> 96-765 on DTB 2021-04-04 19:10:25 -06:00
bd9969166a Set gain to range 32-255 -> 96-765 2021-04-04 19:09:26 -06:00
712fc2f18b Set gain to range 102-160 in order to not have dotted image and blinking 2021-03-29 12:18:11 -06:00
855ce6a4d5 Fix identation 2021-03-29 09:33:30 -06:00
6f6cbd2465 Set exposure time to not exceed 60, 45 frame rates times 2021-03-26 17:37:27 -06:00
e1e5e02beb Set max exposure to 36600 us
Max row times = 1650
Default row time = frame_length_line / pixel_freq
		 = 1650 / 74.25M = 22.22 us
Max exposure = 1650 * 22.22 us = 36600 us
2021-03-25 10:39:02 -06:00
4fe2a92881 Set min exposure to 100 us 2021-03-25 09:24:51 -06:00
5d37ed177d Merge pull request 'feature/resolution-1280x960' (#10) from feature/resolution-1280x960 into master
Reviewed-on: #10
2021-03-20 00:56:50 +00:00
a8d215aed8 documentation: Update README 2021-03-19 18:53:57 -06:00
aff1e46729 documentation: Add 1920x960 resolution support on README 2021-03-19 18:50:20 -06:00
8faeddf611 Add mode1 table with resolution 1280x960 to Driver 2021-03-19 18:25:00 -06:00
bd01d2d08c Add mode1 with resolution 1280x960 to DTB 2021-03-19 18:25:00 -06:00
0c8e4c04c7 Merge pull request 'jetpack-4.4.1' (#8) from jetpack-4.4.1 into master
Reviewed-on: #8
2021-03-16 04:29:32 +00:00
e00ce6abcc Clean up comments in the code 2021-03-15 22:27:57 -06:00
d4df26e9f9 documentation: Fix gain equation on Driver 2021-03-15 22:22:34 -06:00
809d88dd93 documentation: Update README 2021-03-15 21:57:27 -06:00
e4327010bd Fix dotted image -- with fixed blinking 2021-03-10 18:23:42 -06:00
abc331988f Fix dotted image -- still have some blinking 2021-03-10 17:59:54 -06:00
5cede1ef85 Fix dotted image 2021-03-10 13:56:55 -06:00
3f911eb3f3 Merge pull request 'Fix low framerate' (#7) from jetpack-4.4.1 into master
Reviewed-on: #7
2021-03-08 22:59:41 +00:00
69bc2fd5b4 Fix low framerate 2021-03-08 16:58:31 -06:00
d8cb8d7139 Merge pull request 'jetpack-4.4.1' (#3) from jetpack-4.4.1 into master
Reviewed-on: #3
2021-03-04 12:33:15 +00:00
c26468be02 Add script to control AE on sensor-id=0 2021-03-04 06:25:11 -06:00
4c34506a6a Fix gain equation on Driver 2021-03-04 06:25:11 -06:00
897f1f78c1 documentation: Update README with AE 2021-03-04 06:25:11 -06:00
e05aeb04a3 Fix gain & exposure range on DTB 2021-03-03 19:59:21 -06:00
5 changed files with 216 additions and 144 deletions

View File

@ -5,14 +5,16 @@ The camera sensors should be conencted to a ConnectTech's Elroy board.
## Features ## Features
* V4L2 Kernel Driver Version 2.0 supported on L4T32.2.1 * V4L2 Kernel Driver Version 2.0 supported on L4T32.4.4
* V4l2 controls * V4l2 controls
* test pattern * test pattern
* individual gains * individual gains
* vertical/horizontal flip * vertical/horizontal flip
* flash control * flash control
* LibArgus and nvarguscamerasrc * LibArgus and nvarguscamerasrc
* Resolution supported: 1280x720 @ 60fps * Resolutions supported:
* 1280x720 @ 60fps
* 1280x960 @ 45fps
* Gain, exposure, and framerate controls * Gain, exposure, and framerate controls
* Camera synchronization * Camera synchronization
@ -100,28 +102,13 @@ The AE controls realays in the feedback provided by the Driver's camera sensor t
and the custom DTSIs with the sensor parameters definitions. and the custom DTSIs with the sensor parameters definitions.
As the AE has interdependency with the digital gain. This gain it's and operation on the Driver, and follows this setup: As the AE has interdependency with the digital gain. This gain it's and operation on the Driver, and follows this setup:
```bash MT9M021 sensor datasheet:
/*
* Digital gain equation:
*
* RANGE: 1x, 7.97x
* GAIN: VAL / STEPS;
* STEPS: 1/32
*
* SCALE FACTOR = 100.000
*
* min_gain_val = 100.000
* max_gain_val = 797.000
* step_gain_val = 3125
*/
MT9M021 sensor datasheet:
* <a href="https://files.niemo.de/aptina_pdfs/MT9M021-M031_Developer_Guide.pdf">MT9M021 Developer Guide</a> * <a href="https://files.niemo.de/aptina_pdfs/MT9M021-M031_Developer_Guide.pdf">MT9M021 Developer Guide</a>
```
Where, the min_gain_val, max_gain_val, step_gain_val are part of the cameras' DTSI (tegra186-tx2-spiri-camera.dtsi) fixed parameters
as per the datasheet. The step_gain_val consists of the steps (1/32 for the register) scaled to a value that makes this fraction become an significant Where, the `min_gain_val, max_gain_val, step_gain_val` are part of the cameras' DTSI (tegra186-tx2-spiri-camera.dtsi) fixed parameters
in integer. as per the datasheet. The `gain` consists on the steps (1x + n * 1/32 for the register) scaled to a value that represents this fraction in an integer value for the gain register.
#### Kernel Changes #### Kernel Changes

View File

@ -93,31 +93,71 @@ i2c8 = "/i2c@31e0000";
csi_pixel_bit_depth = "12"; csi_pixel_bit_depth = "12";
mode_type = "bayer"; mode_type = "bayer";
pixel_phase = "rggb"; pixel_phase = "rggb";
readout_orientation = "0"; readout_orientation = "0";
line_length = "1650"; line_length = "1650";
inherent_gain = "1"; inherent_gain = "1";
pix_clk_hz = "74250000"; pix_clk_hz = "74250000";
gain_factor = "3125"; gain_factor = "3125";
framerate_factor = "1000000"; framerate_factor = "1000000";
exposure_factor = "1000000"; exposure_factor = "1000000";
min_gain_val = "100000"; min_gain_val = "100000"; /* 1x */
max_gain_val = "796000"; max_gain_val = "796875"; /* 7.97x */
step_gain_val = "1"; step_gain_val = "1";
default_gain = "100000"; default_gain = "100000"; /* 1x */
min_hdr_ratio = "1"; min_hdr_ratio = "1";
max_hdr_ratio = "1"; max_hdr_ratio = "1";
min_framerate = "2000000"; min_framerate = "2000000";
max_framerate = "60000000"; max_framerate = "60000000";
step_framerate = "1"; step_framerate = "1";
default_framerate = "60000000"; // 60.0 fps default_framerate = "60000000"; // 60.0 fps
min_exp_time = "500"; // us min_exp_time = "100"; // us
max_exp_time = "16000"; // us max_exp_time = "16620"; // us
step_exp_time = "1"; step_exp_time = "1";
default_exp_time = "12000"; // us default_exp_time = "16620"; // us
}; };
mode1 {
mclk_khz = "24000";
num_lanes = "1";
tegra_sinterface = "serial_b";
discontinuous_clk = "no";
dpcm_enable = "false";
cil_settletime = "26";
active_w = "1280";
active_h = "960";
dynamic_pixel_bit_depth = "12";
csi_pixel_bit_depth = "12";
mode_type = "bayer";
pixel_phase = "rggb";
readout_orientation = "0";
line_length = "1650";
inherent_gain = "1";
pix_clk_hz = "74250000";
gain_factor = "3125";
framerate_factor = "1000000";
exposure_factor = "1000000";
min_gain_val = "100000"; /* 1x */
max_gain_val = "796875"; /* 7.97x */
step_gain_val = "1";
default_gain = "100000"; /* 1x */
min_hdr_ratio = "1";
max_hdr_ratio = "1";
min_framerate = "2000000";
max_framerate = "45000000";
step_framerate = "1";
default_framerate = "45000000"; // 45.0 fps
min_exp_time = "100"; // us
max_exp_time = "22220"; // us
step_exp_time = "1";
default_exp_time = "22220"; // us
};
ports { ports {
#address-cells = <0x1>; #address-cells = <0x1>;
#size-cells = <0x0>; #size-cells = <0x0>;
@ -180,18 +220,18 @@ i2c8 = "/i2c@31e0000";
csi_pixel_bit_depth = "12"; csi_pixel_bit_depth = "12";
mode_type = "bayer"; mode_type = "bayer";
pixel_phase = "rggb"; pixel_phase = "rggb";
readout_orientation = "0"; readout_orientation = "0";
line_length = "1650"; line_length = "1650";
inherent_gain = "1"; inherent_gain = "1";
pix_clk_hz = "74250000"; pix_clk_hz = "74250000";
gain_factor = "3125"; gain_factor = "3125";
framerate_factor = "1000000"; framerate_factor = "1000000";
exposure_factor = "1000000"; exposure_factor = "1000000";
min_gain_val = "100000"; min_gain_val = "100000"; /* 1x */
max_gain_val = "796000"; max_gain_val = "796875"; /* 7.97x */
step_gain_val = "1"; step_gain_val = "1";
default_gain = "100000"; default_gain = "100000"; /* 1x */
min_hdr_ratio = "1"; min_hdr_ratio = "1";
max_hdr_ratio = "1"; max_hdr_ratio = "1";
@ -200,11 +240,50 @@ i2c8 = "/i2c@31e0000";
step_framerate = "1"; step_framerate = "1";
default_framerate = "60000000"; // 60.0 fps default_framerate = "60000000"; // 60.0 fps
min_exp_time = "500"; // us min_exp_time = "100"; // us
max_exp_time = "16000"; // us max_exp_time = "16620"; // us
step_exp_time = "1"; step_exp_time = "1";
default_exp_time = "12000"; // us default_exp_time = "16620"; // us
}; };
mode1 {
mclk_khz = "24000";
num_lanes = "1";
tegra_sinterface = "serial_a";
discontinuous_clk = "no";
dpcm_enable = "false";
cil_settletime = "26";
active_w = "1280";
active_h = "960";
dynamic_pixel_bit_depth = "12";
csi_pixel_bit_depth = "12";
mode_type = "bayer";
pixel_phase = "rggb";
readout_orientation = "0";
line_length = "1650";
inherent_gain = "1";
pix_clk_hz = "74250000";
gain_factor = "3125";
framerate_factor = "1000000";
exposure_factor = "1000000";
min_gain_val = "100000"; /* 1x */
max_gain_val = "796875"; /* 7.97x */
step_gain_val = "1";
default_gain = "100000"; /* 1x */
min_hdr_ratio = "1";
max_hdr_ratio = "1";
min_framerate = "2000000";
max_framerate = "45000000";
step_framerate = "1";
default_framerate = "45000000"; // 45.0 fps
min_exp_time = "100"; // us
max_exp_time = "22220"; // us
step_exp_time = "1";
default_exp_time = "22220"; // us
};
ports { ports {
#address-cells = <0x1>; #address-cells = <0x1>;
#size-cells = <0x0>; #size-cells = <0x0>;

View File

@ -135,8 +135,8 @@
#define MT9M021_ANALOG_GAIN_SHIFT 4 #define MT9M021_ANALOG_GAIN_SHIFT 4
#define MT9M021_ANALOG_GAIN_MASK 0x0030 #define MT9M021_ANALOG_GAIN_MASK 0x0030
#define MT9M021_GLOBAL_GAIN_MIN 100000 #define MT9M021_GLOBAL_GAIN_MIN 100
#define MT9M021_GLOBAL_GAIN_MAX 796000 #define MT9M021_GLOBAL_GAIN_MAX 762
#define MT9M021_GLOBAL_GAIN_DEF 100 #define MT9M021_GLOBAL_GAIN_DEF 100
#define MT9M021_COARSE_INT_TIME_MIN 0x0001 #define MT9M021_COARSE_INT_TIME_MIN 0x0001
@ -396,67 +396,39 @@ static int mt9m021_set_gain(struct tegracam_device *tc_dev, s64 val)
{ {
struct camera_common_data *s_data = tc_dev->s_data; struct camera_common_data *s_data = tc_dev->s_data;
struct device *dev = tc_dev->dev; struct device *dev = tc_dev->dev;
int err = 0; int err = 0;
u16 gain_mul; u64 gain = 0;
u16 reg16 = 0;
u64 gain = 0;
dev_dbg(dev, "Setting Gain to: %lld", val); dev_dbg(dev, "Setting Gain to: %lld", val);
if (val >= MT9M021_GAIN_8X_FIXED) { /*
gain_mul = MT9M021_GAIN_8X; * Digital gain equation:
} else if (val >= MT9M021_GAIN_4X_FIXED) { *
gain_mul = MT9M021_GAIN_4X; * RANGE: 1x, 7.97x
} else if (val >= MT9M021_GAIN_2X_FIXED) { * STEPS: 1/32
gain_mul = MT9M021_GAIN_2X; *
} else { * gain accepts mapping from range 32 - 255
gain_mul = MT9M021_GAIN_1X; *
} * SCALE FACTOR = 3125
*
/* * min_gain_val = 100000
* Digital gain equation: * max_gain_val = 796875
* * gain_factor = 3125
* RANGE: 1x, 7.97x *
* GAIN: VAL / STEPS; */
* STEPS: 1/32 gain = val / 3125;
*
* SCALE FACTOR = 100.000
*
* min_gain_val = 100.000
* max_gain_val = 797.000
* gain_factor = 3125
*
* gain maps to range 32 - 255
*/
gain = val / 3125;
/* Update analog gain multiplier */
err = mt9m021_read_reg16(s_data, MT9M021_DIGITAL_TEST, &reg16);
if (err)
goto exit;
reg16 =
(reg16 & ~MT9M021_ANALOG_GAIN_MASK) |
((gain_mul << MT9M021_ANALOG_GAIN_SHIFT) &
MT9M021_ANALOG_GAIN_MASK);
err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16);
// msleep(10);
if (err)
goto exit;
/* Update global gain */ /* Update global gain */
err = err = mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, gain);
mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN, gain);
// msleep(10);
if (err) if (err)
goto exit; goto exit;
err = err = mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, gain);
mt9m021_write_reg16(s_data, MT9M021_GLOBAL_GAIN_CB, gain);
if (err) if (err)
goto exit; goto exit;
return 0; return 0;
exit: exit:
dev_err(dev, "Gain control error: %d", err); dev_err(dev, "Gain control error: %d", err);
return err; return err;
@ -492,8 +464,8 @@ static int mt9m021_set_frame_rate(struct tegracam_device *tc_dev, s64 val)
/* Calculate frame-length */ /* Calculate frame-length */
frame_length = mode->signal_properties.pixel_clock.val * frame_length = mode->signal_properties.pixel_clock.val *
mode->control_properties.framerate_factor / mode->control_properties.framerate_factor /
mode->image_properties.line_length / val; mode->image_properties.line_length / val;
err = mt9m021_set_frame_length(priv, frame_length); err = mt9m021_set_frame_length(priv, frame_length);
if (err) if (err)
@ -501,7 +473,7 @@ static int mt9m021_set_frame_rate(struct tegracam_device *tc_dev, s64 val)
return 0; return 0;
exit: exit:
dev_err(dev, "Frame rate control error: %d", err); dev_err(dev, "Frame rate control error: %d", err);
return err; return err;
} }
@ -514,13 +486,12 @@ static int mt9m021_set_coarse_time(struct mt9m021 *priv, s64 val)
dev_dbg(dev, "Setting Coarse Time to: %lld", val); dev_dbg(dev, "Setting Coarse Time to: %lld", val);
err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME, val); err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME, val);
if (err) if (err)
return err; return err;
err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME_CB, val); err = mt9m021_write_reg16(s_data, MT9M021_COARSE_INT_TIME_CB, val);
if (err) if (err)
return err; return err;
// msleep(30);
return 0; return 0;
} }
@ -531,24 +502,24 @@ static int mt9m021_set_exposure(struct tegracam_device *tc_dev, s64 val)
struct mt9m021 *priv = (struct mt9m021 *)tc_dev->priv; struct mt9m021 *priv = (struct mt9m021 *)tc_dev->priv;
struct device *dev = tc_dev->dev; struct device *dev = tc_dev->dev;
const struct sensor_mode_properties *mode = const struct sensor_mode_properties *mode =
&s_data->sensor_props.sensor_modes[s_data->mode]; &s_data->sensor_props.sensor_modes[s_data->mode];
u64 coarse_time; u64 coarse_time;
int err = 0; int err = 0;
dev_dbg(dev, "Setting Exposure Time to : %lld", val); dev_dbg(dev, "Setting Exposure Time to : %lld", val);
coarse_time = coarse_time =
val * mode->signal_properties.pixel_clock.val / val * mode->signal_properties.pixel_clock.val /
mode->image_properties.line_length / mode->image_properties.line_length /
mode->control_properties.exposure_factor; mode->control_properties.exposure_factor;
err = mt9m021_set_coarse_time(priv, coarse_time); err = mt9m021_set_coarse_time(priv, coarse_time);
if (err) if (err)
goto exit; goto exit;
return err; return err;
exit: exit:
dev_err(dev, "Exposure control error: %d", err); dev_err(dev, "Exposure control error: %d", err);
return err; return err;
} }
@ -568,16 +539,14 @@ static int mt9m021_set_analog_gain(struct tegracam_device *tc_dev, s64 val)
goto exit; goto exit;
reg16 = reg16 =
(reg16 & ~MT9M021_ANALOG_GAIN_MASK) | (reg16 & ~MT9M021_ANALOG_GAIN_MASK) |
((val << MT9M021_ANALOG_GAIN_SHIFT) & ((val << MT9M021_ANALOG_GAIN_SHIFT) & MT9M021_ANALOG_GAIN_MASK);
MT9M021_ANALOG_GAIN_MASK);
err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16); err = mt9m021_write_reg16(s_data, MT9M021_DIGITAL_TEST, reg16);
// msleep(30);
if (err) if (err)
goto exit; goto exit;
return 0; return 0;
exit: exit:
dev_err(dev, "Analog Gain control error: %d", err); dev_err(dev, "Analog Gain control error: %d", err);
return err; return err;
@ -627,11 +596,10 @@ static int mt9m021_set_digital_gain(struct tegracam_device *tc_dev, s64 val,
err = mt9m021_write_reg16(s_data, gain_cb_reg, val); err = mt9m021_write_reg16(s_data, gain_cb_reg, val);
if (err) if (err)
goto exit; goto exit;
// msleep(30);
return 0; return 0;
exit: exit:
dev_err(dev, "Digital Gain control error: %d", err); dev_err(dev, "Digital Gain control error: %d", err);
return err; return err;
} }
@ -648,15 +616,13 @@ static int mt9m021_set_test_pattern(struct tegracam_device *tc_dev, s32 val)
err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN, err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN,
MT9M021_TEST_PATTERN_VAL); MT9M021_TEST_PATTERN_VAL);
else else
err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN, err = mt9m021_write_reg16(s_data, MT9M021_TEST_PATTERN, val);
val);
// msleep(30);
if (err) if (err)
goto exit; goto exit;
return 0; return 0;
exit: exit:
dev_err(dev, "Test Pattern control error: %d", err); dev_err(dev, "Test Pattern control error: %d", err);
return err; return err;
@ -671,7 +637,7 @@ static int mt9m021_set_flash(struct tegracam_device *tc_dev, s32 val)
dev_dbg(dev, "Setting Flash to: %d", val); dev_dbg(dev, "Setting Flash to: %d", val);
switch(val) { switch (val) {
case V4L2_FLASH_LED_MODE_NONE: case V4L2_FLASH_LED_MODE_NONE:
err = mt9m021_write_reg16(s_data, MT9M021_FLASH, 0x0000); err = mt9m021_write_reg16(s_data, MT9M021_FLASH, 0x0000);
priv->flash_en = false; priv->flash_en = false;
@ -690,7 +656,7 @@ static int mt9m021_set_flash(struct tegracam_device *tc_dev, s32 val)
goto exit; goto exit;
return 0; return 0;
exit: exit:
dev_err(dev, "Flash control error: %d", err); dev_err(dev, "Flash control error: %d", err);
return err; return err;
@ -704,7 +670,7 @@ static int mt9m021_set_flip(struct tegracam_device *tc_dev, s32 val, int id)
dev_dbg(dev, "Setting Flip to: %d", val); dev_dbg(dev, "Setting Flip to: %d", val);
switch(id) { switch (id) {
case V4L2_CID_HFLIP: case V4L2_CID_HFLIP:
err = mt9m021_update_bits(s_data, MT9M021_READ_MODE, err = mt9m021_update_bits(s_data, MT9M021_READ_MODE,
val << 14, MT9M021_HFLIP_MASK); val << 14, MT9M021_HFLIP_MASK);
@ -723,7 +689,7 @@ static int mt9m021_set_flip(struct tegracam_device *tc_dev, s32 val, int id)
goto exit; goto exit;
return 0; return 0;
exit: exit:
dev_err(dev, "Flip control error: %d", err); dev_err(dev, "Flip control error: %d", err);
return err; return err;
@ -794,7 +760,7 @@ static int mt9m021_power_off(struct camera_common_data *s_data)
usleep_range(2000, 2010); usleep_range(2000, 2010);
} }
power_off_done: power_off_done:
pw->state = SWITCH_OFF; pw->state = SWITCH_OFF;
return 0; return 0;
@ -916,7 +882,7 @@ static struct camera_common_pdata *mt9m021_parse_dt(struct tegracam_device
return board_priv_pdata; return board_priv_pdata;
error: error:
devm_kfree(dev, board_priv_pdata); devm_kfree(dev, board_priv_pdata);
return ret; return ret;
@ -963,15 +929,10 @@ static int mt9m021_col_correction(struct mt9m021 *priv)
if (ret < 0) if (ret < 0)
return ret; return ret;
// msleep(200);
// usleep(200);
/* Enable Streaming */ /* Enable Streaming */
ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_START_STREAM]); ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_START_STREAM]);
if (ret < 0) if (ret < 0)
return ret; return ret;
// msleep(200);
// usleep(200);
/* Disable Streaming */ /* Disable Streaming */
ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_STOP_STREAM]); ret = mt9m021_write_table(priv, mode_table[MT9M021_MODE_STOP_STREAM]);
@ -982,8 +943,6 @@ static int mt9m021_col_correction(struct mt9m021 *priv)
ret = mt9m021_write_reg16(s_data, MT9M021_COLUMN_CORRECTION, 0xE007); ret = mt9m021_write_reg16(s_data, MT9M021_COLUMN_CORRECTION, 0xE007);
if (ret < 0) if (ret < 0)
return ret; return ret;
// msleep(200);
// usleep(200);
return ret; return ret;
} }
@ -1013,7 +972,7 @@ static int mt9m021_set_mode(struct tegracam_device *tc_dev)
dev_err(dev, "%s: Failed to set pll setup\n", __func__); dev_err(dev, "%s: Failed to set pll setup\n", __func__);
return ret; return ret;
} }
msleep(100); msleep(100);
ret = mt9m021_col_correction(priv); ret = mt9m021_col_correction(priv);
if (ret < 0) { if (ret < 0) {
@ -1098,7 +1057,7 @@ static int mt9m021_get_trigger_mode(struct mt9m021 *priv)
} }
err = err =
of_property_read_string(node, "trigger_mode", &priv->trigger_mode); of_property_read_string(node, "trigger_mode", &priv->trigger_mode);
if (err == -EINVAL) { if (err == -EINVAL) {
dev_warn(&client->dev, "trigger_mode not in device tree\n"); dev_warn(&client->dev, "trigger_mode not in device tree\n");
*(&priv->trigger_mode) = "master"; *(&priv->trigger_mode) = "master";
@ -1130,7 +1089,8 @@ static int mt9m021_verify_chip_id(struct mt9m021 *priv)
err = mt9m021_read_reg16(s_data, MT9M021_CHIP_ID_REG, &chip_id); err = mt9m021_read_reg16(s_data, MT9M021_CHIP_ID_REG, &chip_id);
if (!err) if (!err)
break; break;
dev_info(&client->dev, "Failed to read Chip ID, trying again\n"); dev_info(&client->dev,
"Failed to read Chip ID, trying again\n");
max_retries--; max_retries--;
msleep(30); msleep(30);
} }
@ -1146,7 +1106,7 @@ static int mt9m021_verify_chip_id(struct mt9m021 *priv)
goto exit; goto exit;
} }
exit: exit:
ret = mt9m021_power_off(s_data); ret = mt9m021_power_off(s_data);
if (ret) if (ret)
return ret; return ret;

View File

@ -31,12 +31,12 @@
#define mt9m021_reg struct reg_16 #define mt9m021_reg struct reg_16
static const mt9m021_reg mt9m021_start[] = { static const mt9m021_reg mt9m021_start[] = {
{0x301A, 0x00DC}, /* Enable Streaming */ {0x301A, 0x00DC}, /* Enable Streaming */
{MT9M021_TABLE_END, 0x00} {MT9M021_TABLE_END, 0x00}
}; };
static const mt9m021_reg mt9m021_stop[] = { static const mt9m021_reg mt9m021_stop[] = {
{0x301A, 0x00D8}, /* Disable Streaming */ {0x301A, 0x00D8}, /* Disable Streaming */
{MT9M021_TABLE_END, 0x00} {MT9M021_TABLE_END, 0x00}
}; };
@ -102,8 +102,42 @@ static const mt9m021_reg mt9m021_mode_1280x720_60fps[] = {
{MT9M021_TABLE_END, 0x00} {MT9M021_TABLE_END, 0x00}
}; };
static const mt9m021_reg mt9m021_mode_1280x960_45fps[] = {
/* Rev2 Settings */
{0x307A, 0x0000},
{0x30EA, 0x0C00},
{0x3044, 0x0404},
{0x301E, 0x012C},
{0x3180, 0x8000},
{0x3014, 0x0000},
/* Analog Settings */
{0x3ED6, 0x00FD},
{0x3ED8, 0x0FFF},
{0x3EDA, 0x0003},
{0x3EDC, 0xF87A},
{0x3EDE, 0xE075},
{0x3EE0, 0x077C},
{0x3EE2, 0xA4EB},
{0x3EE4, 0xD208},
/* Size Settings */
{0x3064, 0x1802}, /* EMBEDDED_DATA_CTRL */
{0x3032, 0x0020}, /* DIGITAL_BINNING */
{0x3002, 0x0004}, /* Y ADDR START */
{0x3004, 0x0001}, /* X ADDR START */
{0x3006, 0x03C3}, /* Y ADDR END */
{0x3008, 0x0500}, /* X ADDR END */
{0x300A, 0x03DE}, /* FRAME_LENGTH_LINES */
{0x300C, 0x0672}, /* LINE_LENGTH_PCK */
{0x30A2, 0x0001}, /* X_ODD_INC */
{0x30A6, 0x0001}, /* Y_ODD_INC */
{MT9M021_TABLE_END, 0x00}
};
enum { enum {
MT9M021_MODE_1280x720_60FPS, MT9M021_MODE_1280x720_60FPS,
MT9M021_MODE_1280x960_45FPS,
MT9M021_MODE_PLL_SETUP, MT9M021_MODE_PLL_SETUP,
@ -112,15 +146,16 @@ enum {
}; };
static const mt9m021_reg *mode_table[] = { static const mt9m021_reg *mode_table[] = {
[MT9M021_MODE_1280x720_60FPS] = mt9m021_mode_1280x720_60fps, [MT9M021_MODE_1280x720_60FPS] = mt9m021_mode_1280x720_60fps,
[MT9M021_MODE_1280x960_45FPS] = mt9m021_mode_1280x960_45fps,
[MT9M021_MODE_PLL_SETUP] = mt9m021_pll_setup, [MT9M021_MODE_PLL_SETUP] = mt9m021_pll_setup,
[MT9M021_MODE_START_STREAM] = mt9m021_start, [MT9M021_MODE_START_STREAM] = mt9m021_start,
[MT9M021_MODE_STOP_STREAM] = mt9m021_stop, [MT9M021_MODE_STOP_STREAM] = mt9m021_stop,
}; };
static const int mt9m021_framerates[] = { static const int mt9m021_framerates_1280x720[] = {
10, 10,
20, 20,
30, 30,
@ -129,8 +164,19 @@ static const int mt9m021_framerates[] = {
60, 60,
}; };
static const struct camera_common_frmfmt mt9m021_frmfmt[] = { static const int mt9m021_framerates_1280x960[] = {
{{1280, 720}, mt9m021_framerates, 1, 0, MT9M021_MODE_1280x720_60FPS}, 10,
20,
30,
40,
45,
}; };
#endif /* __MT9M021_I2C_TABLES__ */ static const struct camera_common_frmfmt mt9m021_frmfmt[] = {
{{1280, 720}, mt9m021_framerates_1280x720, 1, 0,
MT9M021_MODE_1280x720_60FPS},
{{1280, 960}, mt9m021_framerates_1280x960, 1, 0,
MT9M021_MODE_1280x960_45FPS},
};
#endif /* __MT9M021_I2C_TABLES__ */

View File

@ -5,7 +5,7 @@ initial_exposure_time=0
while true; do sleep 0.5; while true; do sleep 0.5;
# Read center camera controls # Read center camera controls
echo `v4l2-ctl -d /dev/video1 --get-ctrl=gain --get-ctrl=exposure` > controls echo `v4l2-ctl -d /dev/video0 --get-ctrl=gain --get-ctrl=exposure` > controls
awk '{print $2}' controls > get_control awk '{print $2}' controls > get_control
actual_gain=`cat get_control` actual_gain=`cat get_control`
awk '{print $4}' controls > get_control awk '{print $4}' controls > get_control
@ -18,10 +18,10 @@ while true; do sleep 0.5;
rm controls get_control rm controls get_control
# Set R/L camera controls manually # Set R/L camera controls manually
if [ $actual_gain -ne $initial_gain ]; then if [ $actual_gain -ne $initial_gain ]; then
v4l2-ctl -d /dev/video0 --set-ctrl=gain=$actual_gain v4l2-ctl -d /dev/video1 --set-ctrl=gain=$actual_gain
fi fi
if [ $actual_exposure_time -ne $initial_exposure_time ]; then if [ $actual_exposure_time -ne $initial_exposure_time ]; then
v4l2-ctl -d /dev/video0 --set-ctrl=exposure=$actual_exposure_time v4l2-ctl -d /dev/video1 --set-ctrl=exposure=$actual_exposure_time
fi fi
# Define new initial value # Define new initial value
initial_gain=$actual_gain initial_gain=$actual_gain