Compare commits
29 Commits
hotfix/fix
...
master
Author | SHA1 | Date | |
---|---|---|---|
a324c5b05e | |||
7d7bad60d3 | |||
71bc9b31dd | |||
6d982b1ebe | |||
bd9969166a | |||
712fc2f18b | |||
855ce6a4d5 | |||
6f6cbd2465 | |||
e1e5e02beb | |||
4fe2a92881 | |||
5d37ed177d | |||
a8d215aed8 | |||
aff1e46729 | |||
8faeddf611 | |||
bd01d2d08c | |||
0c8e4c04c7 | |||
e00ce6abcc | |||
d4df26e9f9 | |||
809d88dd93 | |||
e4327010bd | |||
abc331988f | |||
5cede1ef85 | |||
3f911eb3f3 | |||
69bc2fd5b4 | |||
d8cb8d7139 | |||
c26468be02 | |||
4c34506a6a | |||
897f1f78c1 | |||
e05aeb04a3 |
31
README.md
31
README.md
@ -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
|
||||||
|
|
||||||
|
@ -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>;
|
||||||
|
@ -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, ®16);
|
|
||||||
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;
|
||||||
|
@ -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__ */
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user