Compare commits

...

3 Commits

Author SHA1 Message Date
dchvs 14da17d421 Merge pull request 'jetpack-4.4.1' (#2) from jetpack-4.4.1 into master
Reviewed-on: #2
2021-02-20 02:59:31 +00:00
dchvs a606c4ece1 documentation: Update README 2021-02-19 20:56:55 -06:00
dchvs 9a657623d0 Remove extra Kernel sources 2021-02-19 20:56:55 -06:00
6 changed files with 56 additions and 2526 deletions

View File

@ -1,23 +1,7 @@
# Leopard Imaging LI-M021C-MIPI Stereo-Optic Cameras
## Kernel Changes
The source code we have modified or added and is pertinent to these cameras is in the following files:
* controls-utility.sh
* hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera-base.dtsi
* hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-tx2-spiri-camera.dtsi
* hardware/nvidia/platform/t18x/quill/kernel-dts/Makefile
* hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-tx2-spiri-USB3.dts
* hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-tx2-spiri-base.dts
* hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-tx2-spiri-mPCIe.dts
* hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-tx2-spiri-revF+.dts
* nvidia/drivers/media/i2c/mt9m021.c
* nvidia/drivers/media/i2c/mt9m021_mode_tbls.h
* nvidia/drivers/media/platform/tegra/camera/camera_common.c
* nvidia/drivers/media/platform/tegra/camera/tegracam_ctrls.c
* nvidia/include/media/camera_common.h
* nvidia/include/media/tegra-v4l2-camera.h
All these modifications and additions are part of the Spiri Mu kernel, and are represented by symbolic links from this repository into https://git.spirirobotics.com/Spiri/mu_kernel_sources, with the exception of the controls-utility.sh script, which is transferred in the spiri_scripts folder of the rootfs.
## Cameras setup
The camera sensors should be conencted to a ConnectTech's Elroy board.
## Features
@ -90,7 +74,57 @@ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=RG12 -
v4l2-ctl -d /dev/video01 --set-fmt-video=width=1280,height=720,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap
```
## Documentation
## Appends
#### Kernel Changes
The Driver for the MT9M021 cameras consists on the following structure, that adds the DTB and Kernel sources, along with its Makefiles that lead its portability to a Kernel source.
```bash
.
├── hardware
│ └── nvidia-spiri
│ └── platform
│ └── t18x
│ ├── common
│ │ └── kernel-dts
│ │ └── t18x-common-platforms
│ │ ├── tegra186-tx2-spiri-camera-base.dtsi
│ │ └── tegra186-tx2-spiri-camera.dtsi
│ └── quill
│ └── kernel-dts
│ ├── Makefile
│ ├── tegra186-tx2-spiri-base.dts
│ ├── tegra186-tx2-spiri-mPCIe.dts
│ ├── tegra186-tx2-spiri-revF+.dts
│ └── tegra186-tx2-spiri-USB3.dts
├── kernel
│ ├── kernel-4.9
│ │ └── arch
│ │ └── arm64
│ │ └── configs
│ │ └── tegra_defconfig
│ └── nvidia-spiri
│ ├── drivers
│ │ └── media
│ │ ├── i2c
│ │ │ ├── Kconfig
│ │ │ ├── Makefile
│ │ │ ├── mt9m021.c
│ │ │ └── mt9m021_mode_tbls.h
│ └── include
│ └── media
│ └── mt9m021.h
└── README.md
```
In order to add the Driver to the Kernel, the following reference Kernel files are patched for adding custom controls that the camera implements.
* kernel/nvidia/drivers/media/platform/tegra/camera/camera_common.c
* kernel/nvidia/drivers/media/platform/tegra/camera/tegracam_ctrls.c
* kernel/nvidia/include/media/camera_common.h
* kernel/nvidia/include/media/tegra-v4l2-camera.h
#### Documentation
* <a href="https://nextcloud.spirirobotics.com/f/3369">CSI2 adapter board guide</a>
* <a href="https://nextcloud.spirirobotics.com/f/3382">Camera module data sheet</a>
* <a href="https://nextcloud.spirirobotics.com/f/3392">Camera sensor data sheet</a>

View File

@ -77,7 +77,7 @@ i2c8 = "/i2c@31e0000";
mclk = "extperiph2";
// gpios
// reset-gpios = <&tegra_main_gpio CAM1_RST GPIO_ACTIVE_HIGH>;
reset-gpios = <&tegra_main_gpio CAM1_RST GPIO_ACTIVE_HIGH>;
mode0 {
mclk_khz = "24000";
@ -125,9 +125,7 @@ i2c8 = "/i2c@31e0000";
port@0 {
reg = <0x0>;
// daniel's
status="okay";
status = "okay";
mt9m021_slave: endpoint {
port-index = <0x1>;
bus-width = <0x1>;
@ -168,8 +166,7 @@ i2c8 = "/i2c@31e0000";
mclk = "extperiph1";
// gpios
// reset-gpios = <&tegra_main_gpio CAM0_RST GPIO_ACTIVE_HIGH>;
reset-gpios = <&tegra_main_gpio CAM0_RST GPIO_ACTIVE_HIGH>;
mode0 {
mclk_khz = "24000";
num_lanes = "1";

View File

@ -1,786 +0,0 @@
/*
* tegracam_ctrls - control framework for tegra camera drivers
*
* Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#include <linux/types.h>
#include <media/tegra-v4l2-camera.h>
#include <media/camera_common.h>
#include <media/tegracam_utils.h>
#define CTRL_U32_MIN 0
#define CTRL_U32_MAX 0x7FFFFFFF
#define CTRL_U64_MIN 0
#define CTRL_U64_MAX 0x7FFFFFFFFFFFFFFFLL
#define CTRL_S32_MIN 0x80000000
#define CTRL_S32_MAX 0x7FFFFFFF
#define CTRL_S64_MIN 0x8000000000000000LL
#define CTRL_S64_MAX 0x7FFFFFFFFFFFFFFFLL
#define CTRL_MAX_STR_SIZE 4096
#define TEGRACAM_DEF_CTRLS 1
/* MT9M021 Controls Information */
#define MT9M021_DEFAULT_ANALOG_GAIN (0x0)
#define MT9M021_MAX_ANALOG_GAIN (0x3)
static const char * const mt9m021_test_pattern_menu[] = {
"0:Disabled",
"1:Solid color test pattern",
"2:color bar test pattern",
"3:Fade to gray color bar test pattern",
"256:Walking 1s test pattern (12 bit)"
};
static int tegracam_s_ctrl(struct v4l2_ctrl *ctrl);
static const struct v4l2_ctrl_ops tegracam_ctrl_ops = {
.s_ctrl = tegracam_s_ctrl,
};
static const u32 tegracam_def_cids[] = {
TEGRA_CAMERA_CID_GROUP_HOLD,
};
/*
* For auto control, the states of the previous controls must
* be applied to get optimal quality faster. List all the controls
* which must be overriden
*/
static const u32 tegracam_override_cids[] = {
TEGRA_CAMERA_CID_GAIN,
TEGRA_CAMERA_CID_EXPOSURE,
TEGRA_CAMERA_CID_FRAME_RATE,
};
#define NUM_OVERRIDE_CTRLS ARRAY_SIZE(tegracam_override_cids)
static struct v4l2_ctrl_config ctrl_cfg_list[] = {
/* Do not change the name field for the controls! */
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_GAIN,
.name = "Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_EXPOSURE,
.name = "Exposure",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_EXPOSURE_SHORT,
.name = "Exposure Short",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_FRAME_RATE,
.name = "Frame Rate",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_GROUP_HOLD,
.name = "Group Hold",
.type = V4L2_CTRL_TYPE_BOOLEAN,
.flags = V4L2_CTRL_FLAG_EXECUTE_ON_WRITE,
.min = 0,
.max = 1,
.def = 0,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_EEPROM_DATA,
.name = "EEPROM Data",
.type = V4L2_CTRL_TYPE_STRING,
.flags = V4L2_CTRL_FLAG_READ_ONLY,
.min = 0,
.max = CTRL_MAX_STR_SIZE,
.step = 2,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_FUSE_ID,
.name = "Fuse ID",
.type = V4L2_CTRL_TYPE_STRING,
.flags = V4L2_CTRL_FLAG_READ_ONLY,
.min = 0,
.max = CTRL_MAX_STR_SIZE,
.step = 2,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_SENSOR_MODE_ID,
.name = "Sensor Mode",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U32_MIN,
.max = CTRL_U32_MAX,
.def = CTRL_U32_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_HDR_EN,
.name = "HDR enable",
.type = V4L2_CTRL_TYPE_INTEGER_MENU,
.min = 0,
.max = ARRAY_SIZE(switch_ctrl_qmenu) - 1,
.menu_skip_mask = 0,
.def = 0,
.qmenu_int = switch_ctrl_qmenu,
},
{
.ops = &tegracam_ctrl_ops,
.id = TEGRA_CAMERA_CID_OTP_DATA,
.name = "OTP Data",
.type = V4L2_CTRL_TYPE_STRING,
.flags = V4L2_CTRL_FLAG_READ_ONLY,
.min = 0,
.max = CTRL_MAX_STR_SIZE,
.step = 2,
},
/* Controls extension for MT9M021 */
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_ANALOGUE_GAIN,
.name = "Analog Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = MT9M021_MAX_ANALOG_GAIN,
.def = MT9M021_DEFAULT_ANALOG_GAIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_GAIN_RED,
.name = "Red Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_GAIN_GREENR,
.name = "GreenR Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_GAIN_GREENB,
.name = "GreenB Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_GAIN_BLUE,
.name = "Blue Gain",
.type = V4L2_CTRL_TYPE_INTEGER64,
.flags = V4L2_CTRL_FLAG_SLIDER,
.min = CTRL_U64_MIN,
.max = CTRL_U64_MAX,
.def = CTRL_U64_MIN,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_TEST_PATTERN,
.type = V4L2_CTRL_TYPE_MENU,
.name = "Test Pattern",
.min = 0,
.max = ARRAY_SIZE(mt9m021_test_pattern_menu) - 1,
.step = 0,
.def = 0,
.flags = 0,
.menu_skip_mask = 0,
.qmenu = mt9m021_test_pattern_menu,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_FLASH_LED_MODE,
.name = "Flash",
.type = V4L2_CTRL_TYPE_INTEGER,
.flags = 0,
.min = V4L2_FLASH_LED_MODE_NONE,
.max = V4L2_FLASH_LED_MODE_FLASH,
.def = V4L2_FLASH_LED_MODE_FLASH,
.step = 1,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_HFLIP,
.name = "Horizontal Flip",
.type = V4L2_CTRL_TYPE_INTEGER_MENU,
.min = 0,
.max = ARRAY_SIZE(switch_ctrl_qmenu) - 1,
.menu_skip_mask = 0,
.def = 0,
.qmenu_int = switch_ctrl_qmenu,
},
{
.ops = &tegracam_ctrl_ops,
.id = V4L2_CID_VFLIP,
.name = "Vertical Flip",
.type = V4L2_CTRL_TYPE_INTEGER_MENU,
.min = 0,
.max = ARRAY_SIZE(switch_ctrl_qmenu) - 1,
.menu_skip_mask = 0,
.def = 0,
.qmenu_int = switch_ctrl_qmenu,
},
};
static int tegracam_get_ctrl_index(u32 cid)
{
int i;
for (i = 0; i < ARRAY_SIZE(ctrl_cfg_list); i++) {
if (ctrl_cfg_list[i].id == cid)
return i;
}
return -EINVAL;
}
static int tegracam_get_string_ctrl_size(u32 cid,
const struct tegracam_ctrl_ops *ops)
{
u32 index = 0;
switch (cid) {
case TEGRA_CAMERA_CID_EEPROM_DATA:
index = TEGRA_CAM_STRING_CTRL_EEPROM_INDEX;
break;
case TEGRA_CAMERA_CID_FUSE_ID:
index = TEGRA_CAM_STRING_CTRL_FUSEID_INDEX;
break;
case TEGRA_CAMERA_CID_OTP_DATA:
index = TEGRA_CAM_STRING_CTRL_OTP_INDEX;
break;
default:
return -EINVAL;
}
return ops->string_ctrl_size[index];
}
static int tegracam_setup_string_ctrls(struct tegracam_device *tc_dev,
struct tegracam_ctrl_handler *handler)
{
const struct tegracam_ctrl_ops *ops = handler->ctrl_ops;
u32 numctrls = ops->numctrls;
int i;
int err = 0;
for (i = 0; i < numctrls; i++) {
struct v4l2_ctrl *ctrl = handler->ctrls[i];
if (ctrl->type == V4L2_CTRL_TYPE_STRING) {
err = ops->fill_string_ctrl(tc_dev, ctrl);
if (err)
return err;
}
}
return 0;
}
static int tegracam_set_ctrls(struct tegracam_ctrl_handler *handler,
struct v4l2_ctrl *ctrl)
{
const struct tegracam_ctrl_ops *ops = handler->ctrl_ops;
struct tegracam_device *tc_dev = handler->tc_dev;
struct camera_common_data *s_data = tc_dev->s_data;
int err = 0;
u32 status = 0;
/* For controls that are independent of power state */
switch (ctrl->id) {
case TEGRA_CAMERA_CID_SENSOR_MODE_ID:
s_data->sensor_mode_id = (int) (*ctrl->p_new.p_s64);
return 0;
case TEGRA_CAMERA_CID_HDR_EN:
return 0;
}
if (v4l2_subdev_call(&s_data->subdev, video,
g_input_status, &status)) {
dev_err(s_data->dev, "power status query unsupported\n");
return -ENOTTY;
}
/* power state is turned off, do not program sensor now */
if (!status)
return 0;
/* For controls that require sensor to be on */
switch (ctrl->id) {
case TEGRA_CAMERA_CID_GAIN:
err = ops->set_gain(tc_dev, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_FRAME_RATE:
err = ops->set_frame_rate(tc_dev, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_EXPOSURE:
err = ops->set_exposure(tc_dev, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_EXPOSURE_SHORT:
err = ops->set_exposure_short(tc_dev, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_GROUP_HOLD:
err = ops->set_group_hold(tc_dev, ctrl->val);
break;
case V4L2_CID_ANALOGUE_GAIN:
err = ops->set_analog_gain(tc_dev, *ctrl->p_new.p_s64);
break;
case V4L2_CID_GAIN_RED:
case V4L2_CID_GAIN_GREENR:
case V4L2_CID_GAIN_GREENB:
case V4L2_CID_GAIN_BLUE:
err = ops->set_digital_gain(tc_dev, *ctrl->p_new.p_s64,
ctrl->id);
break;
case V4L2_CID_TEST_PATTERN:
err = ops->set_test_pattern(tc_dev, ctrl->val);
break;
case V4L2_CID_FLASH_LED_MODE:
err = ops->set_flash(tc_dev, ctrl->val);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
err = ops->set_flip(tc_dev, ctrl->val, ctrl->id);
break;
default:
pr_err("%s: unknown ctrl id.\n", __func__);
return -EINVAL;
}
return err;
}
static int tegracam_set_grouphold_ex(struct tegracam_device *tc_dev,
struct sensor_blob *blob,
bool status)
{
const struct tegracam_ctrl_ops *ops = tc_dev->tcctrl_ops;
struct camera_common_data *s_data = tc_dev->s_data;
int err = 0;
/*
* when grouphold is set, reset control blob
* set grouphold register using set API
* start packetize commands for delivering the blob
* when grouphold is unset, unset grouphold register
* and write the blob only if sensor is streaming.
*/
if (status) {
memset(blob, 0, sizeof(struct sensor_blob));
err = ops->set_group_hold_ex(tc_dev, blob, status);
if (err)
return err;
} else {
err = ops->set_group_hold_ex(tc_dev, blob, status);
if (err)
return err;
/* TODO: block this write selectively from VI5 */
if (tc_dev->is_streaming) {
err = write_sensor_blob(s_data->regmap, blob);
if (err)
return err;
}
}
return 0;
}
static int tegracam_set_ctrls_ex(struct tegracam_ctrl_handler *handler,
struct v4l2_ctrl *ctrl)
{
const struct tegracam_ctrl_ops *ops = handler->ctrl_ops;
struct tegracam_device *tc_dev = handler->tc_dev;
struct camera_common_data *s_data = tc_dev->s_data;
struct tegracam_sensor_data *sensor_data = &handler->sensor_data;
struct sensor_blob *blob = &sensor_data->ctrls_blob;
int err = 0;
switch (ctrl->id) {
case TEGRA_CAMERA_CID_GAIN:
err = ops->set_gain_ex(tc_dev, blob, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_FRAME_RATE:
err = ops->set_frame_rate_ex(tc_dev, blob, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_EXPOSURE:
err = ops->set_exposure_ex(tc_dev, blob, *ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_GROUP_HOLD:
err = tegracam_set_grouphold_ex(tc_dev, blob, ctrl->val);
break;
case TEGRA_CAMERA_CID_SENSOR_MODE_ID:
s_data->sensor_mode_id = (int) (*ctrl->p_new.p_s64);
break;
case TEGRA_CAMERA_CID_HDR_EN:
break;
default:
pr_err("%s: unknown ctrl id.\n", __func__);
return -EINVAL;
}
return err;
}
static int tegracam_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct tegracam_ctrl_handler *handler =
container_of(ctrl->handler,
struct tegracam_ctrl_handler, ctrl_handler);
const struct tegracam_ctrl_ops *ops = handler->ctrl_ops;
if (ops->is_blob_supported)
return tegracam_set_ctrls_ex(handler, ctrl);
else
return tegracam_set_ctrls(handler, ctrl);
return 0;
}
int tegracam_ctrl_set_overrides(struct tegracam_ctrl_handler *hdl)
{
struct v4l2_ext_controls ctrls;
struct v4l2_ext_control control;
struct tegracam_device *tc_dev = hdl->tc_dev;
struct device *dev = tc_dev->dev;
const struct tegracam_ctrl_ops *ops = hdl->ctrl_ops;
struct tegracam_sensor_data *sensor_data = &hdl->sensor_data;
struct sensor_blob *blob = &sensor_data->ctrls_blob;
bool is_blob_supported = ops->is_blob_supported;
int err, result = 0;
int i;
/*
* write list of override regs for the asking frame length,
* coarse integration time, and gain. Failures to write
* overrides are non-fatal
*/
memset(&ctrls, 0, sizeof(ctrls));
#if LINUX_VERSION_CODE > KERNEL_VERSION(4, 9, 0)
ctrls.which = V4L2_CTRL_ID2WHICH(TEGRA_CAMERA_CID_BASE);
#else
ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(TEGRA_CAMERA_CID_BASE);
#endif
ctrls.count = 1;
ctrls.controls = &control;
for (i = 0; i < NUM_OVERRIDE_CTRLS; i++) {
s64 val = 0;
control.id = tegracam_override_cids[i];
result = v4l2_g_ext_ctrls(&hdl->ctrl_handler, &ctrls);
if (result == 0) {
val = control.value64;
switch (control.id) {
case TEGRA_CAMERA_CID_GAIN:
if (is_blob_supported)
err = ops->set_gain_ex(tc_dev,
blob, val);
else
err = ops->set_gain(tc_dev, val);
break;
case TEGRA_CAMERA_CID_EXPOSURE:
if (is_blob_supported)
err = ops->set_exposure_ex(tc_dev,
blob, val);
else
err = ops->set_exposure(tc_dev, val);
break;
case TEGRA_CAMERA_CID_FRAME_RATE:
if (is_blob_supported)
err = ops->set_frame_rate_ex(tc_dev,
blob, val);
else
err = ops->set_frame_rate(tc_dev, val);
break;
default:
dev_err(dev, "%s: unsupported override %x\n",
__func__, control.id);
return -EINVAL;
}
if (err) {
dev_err(dev, "%s: error to set %d override\n",
__func__, control.id);
return err;
}
}
}
return 0;
}
int tegracam_init_ctrl_ranges_by_mode(
struct tegracam_ctrl_handler *handler,
u32 modeidx)
{
struct tegracam_device *tc_dev = handler->tc_dev;
struct camera_common_data *s_data = tc_dev->s_data;
struct sensor_control_properties *ctrlprops = NULL;
s64 min_short_exp_time = 0;
s64 max_short_exp_time = 0;
s64 default_short_exp_time = 0;
int i;
if (modeidx >= s_data->sensor_props.num_modes)
return -EINVAL;
ctrlprops =
&s_data->sensor_props.sensor_modes[modeidx].control_properties;
for (i = 0; i < handler->numctrls; i++) {
struct v4l2_ctrl *ctrl = handler->ctrls[i];
int err = 0;
switch (ctrl->id) {
case TEGRA_CAMERA_CID_GAIN:
case V4L2_CID_GAIN_RED:
case V4L2_CID_GAIN_GREENR:
case V4L2_CID_GAIN_GREENB:
case V4L2_CID_GAIN_BLUE:
err = v4l2_ctrl_modify_range(ctrl,
ctrlprops->min_gain_val,
ctrlprops->max_gain_val,
ctrlprops->step_gain_val,
ctrlprops->default_gain);
break;
case TEGRA_CAMERA_CID_FRAME_RATE:
err = v4l2_ctrl_modify_range(ctrl,
ctrlprops->min_framerate,
ctrlprops->max_framerate,
ctrlprops->step_framerate,
ctrlprops->default_framerate);
break;
case TEGRA_CAMERA_CID_EXPOSURE:
err = v4l2_ctrl_modify_range(ctrl,
ctrlprops->min_exp_time.val,
ctrlprops->max_exp_time.val,
ctrlprops->step_exp_time.val,
ctrlprops->default_exp_time.val);
break;
case TEGRA_CAMERA_CID_EXPOSURE_SHORT:
/*
* min_hdr_ratio should be equal to max_hdr_ratio.
* This will ensure consistent short exposure
* limit calculations.
*/
min_short_exp_time =
ctrlprops->min_exp_time.val /
ctrlprops->min_hdr_ratio;
max_short_exp_time =
ctrlprops->max_exp_time.val /
ctrlprops->min_hdr_ratio;
default_short_exp_time =
ctrlprops->default_exp_time.val /
ctrlprops->min_hdr_ratio;
err = v4l2_ctrl_modify_range(ctrl,
min_short_exp_time,
max_short_exp_time,
ctrlprops->step_exp_time.val,
default_short_exp_time);
dev_dbg(s_data->dev,
"%s:short_exp_limits[%lld,%lld], default_short_exp_time=%lld\n",
__func__,
min_short_exp_time,
max_short_exp_time,
default_short_exp_time);
break;
default:
/* Not required to modify these control ranges */
break;
}
if (err) {
dev_err(s_data->dev,
"ctrl %s range update failed\n", ctrl->name);
return err;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(tegracam_init_ctrl_ranges_by_mode);
int tegracam_init_ctrl_ranges(struct tegracam_ctrl_handler *handler)
{
struct tegracam_device *tc_dev = handler->tc_dev;
struct camera_common_data *s_data = tc_dev->s_data;
struct device *dev = tc_dev->dev;
int i, err = 0;
/* Updating static control ranges */
for (i = 0; i < handler->numctrls; i++) {
struct v4l2_ctrl *ctrl = handler->ctrls[i];
switch (ctrl->id) {
case TEGRA_CAMERA_CID_SENSOR_MODE_ID:
err = v4l2_ctrl_modify_range(ctrl,
CTRL_U32_MIN,
(s64) s_data->sensor_props.num_modes,
1,
CTRL_U32_MIN);
break;
default:
/* Not required to modify these control ranges */
break;
}
if (err) {
dev_err(s_data->dev,
"ctrl %s range update failed\n", ctrl->name);
return err;
}
}
/* Use mode 0 control ranges as default */
if (s_data->sensor_props.num_modes > 0) {
err = tegracam_init_ctrl_ranges_by_mode(handler, 0);
if (err) {
dev_err(dev,
"Error %d updating mode specific control ranges\n",
err);
return err;
}
}
return 0;
}
EXPORT_SYMBOL_GPL(tegracam_init_ctrl_ranges);
int tegracam_ctrl_handler_init(struct tegracam_ctrl_handler *handler)
{
struct tegracam_device *tc_dev = handler->tc_dev;
struct v4l2_ctrl *ctrl;
struct v4l2_ctrl_config *ctrl_cfg;
struct device *dev = tc_dev->dev;
const struct tegracam_ctrl_ops *ops = handler->ctrl_ops;
const u32 *cids = ops->ctrl_cid_list;
u32 numctrls = ops->numctrls + TEGRACAM_DEF_CTRLS;
int i, j;
int err = 0;
err = v4l2_ctrl_handler_init(&handler->ctrl_handler, numctrls);
for (i = 0, j = 0; i < numctrls; i++) {
u32 cid = i < ops->numctrls ? cids[i] : tegracam_def_cids[j++];
int index = tegracam_get_ctrl_index(cid);
int size = 0;
if (index >= ARRAY_SIZE(ctrl_cfg_list)) {
dev_err(dev, "unsupported control in the list\n");
return -ENOTTY;
}
ctrl_cfg = &ctrl_cfg_list[index];
if (ctrl_cfg->type == V4L2_CTRL_TYPE_STRING) {
size = tegracam_get_string_ctrl_size(ctrl_cfg->id, ops);
if (size < 0) {
dev_err(dev, "Invalid string ctrl size\n");
return -EINVAL;
}
ctrl_cfg->max = size;
}
ctrl = v4l2_ctrl_new_custom(&handler->ctrl_handler,
ctrl_cfg, NULL);
if (ctrl == NULL) {
dev_err(dev, "Failed to init %s ctrl\n",
ctrl_cfg->name);
return -EINVAL;
}
if (ctrl_cfg->type == V4L2_CTRL_TYPE_STRING &&
ctrl_cfg->flags & V4L2_CTRL_FLAG_READ_ONLY) {
ctrl->p_new.p_char = devm_kzalloc(tc_dev->dev,
size + 1, GFP_KERNEL);
}
handler->ctrls[i] = ctrl;
};
handler->numctrls = numctrls;
err = v4l2_ctrl_handler_setup(&handler->ctrl_handler);
if (err) {
dev_err(dev, "Error %d in control hdl setup\n", err);
goto error;
}
err = handler->ctrl_handler.error;
if (err) {
dev_err(dev, "Error %d adding controls\n", err);
goto error;
}
err = tegracam_setup_string_ctrls(tc_dev, handler);
if (err) {
dev_err(dev, "setup string controls failed\n");
goto error;
}
err = tegracam_init_ctrl_ranges(handler);
if (err) {
dev_err(dev, "Error %d updating control ranges\n", err);
goto error;
}
return 0;
error:
v4l2_ctrl_handler_free(&handler->ctrl_handler);
return err;
}
EXPORT_SYMBOL_GPL(tegracam_ctrl_handler_init);

View File

@ -1,413 +0,0 @@
/**
* camera_common.h - utilities for tegra camera driver
*
* Copyright (c) 2015-2019, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __camera_common__
#define __camera_common__
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/platform_device.h>
#include <linux/v4l2-mediabus.h>
#include <linux/version.h>
#include <linux/videodev2.h>
#include <media/camera_version_utils.h>
#include <media/nvc_focus.h>
#include <media/sensor_common.h>
#include <media/soc_camera.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-ctrls.h>
#include <media/tegracam_core.h>
/*
* Scaling factor for converting a Q10.22 fixed point value
* back to its original floating point value
*/
#define FIXED_POINT_SCALING_FACTOR (1ULL << 22)
struct reg_8 {
u16 addr;
u8 val;
};
struct reg_16 {
u16 addr;
u16 val;
};
struct camera_common_power_rail {
struct regulator *dvdd;
struct regulator *avdd;
struct regulator *iovdd;
struct regulator *vcmvdd;
struct clk *mclk;
unsigned int pwdn_gpio;
unsigned int reset_gpio;
unsigned int af_gpio;
bool state;
};
struct camera_common_regulators {
const char *avdd;
const char *dvdd;
const char *iovdd;
const char *vcmvdd;
};
struct camera_common_pdata {
const char *mclk_name; /* NULL for default default_mclk */
const char *parentclk_name; /* NULL for no parent clock*/
unsigned int pwdn_gpio;
unsigned int reset_gpio;
unsigned int af_gpio;
bool ext_reg;
int (*power_on)(struct camera_common_power_rail *pw);
int (*power_off)(struct camera_common_power_rail *pw);
struct camera_common_regulators regulators;
bool use_cam_gpio;
bool has_eeprom;
bool v_flip;
bool h_mirror;
unsigned int fuse_id_addr;
};
struct camera_common_eeprom_data {
struct i2c_client *i2c_client;
struct i2c_adapter *adap;
struct i2c_board_info brd;
struct regmap *regmap;
};
int
regmap_util_write_table_8(struct regmap *regmap,
const struct reg_8 table[],
const struct reg_8 override_list[],
int num_override_regs,
u16 wait_ms_addr, u16 end_addr);
int
regmap_util_write_table_16_as_8(struct regmap *regmap,
const struct reg_16 table[],
const struct reg_16 override_list[],
int num_override_regs,
u16 wait_ms_addr, u16 end_addr);
enum switch_state {
SWITCH_OFF,
SWITCH_ON,
};
static const s64 switch_ctrl_qmenu[] = {
SWITCH_OFF, SWITCH_ON
};
/*
* The memory buffers allocated from nvrm are aligned to
* fullfill the hardware requirements:
* - size in alignment with a multiple of 128K/64K bytes,
* see CL http://git-master/r/256468 and bug 1321091.
*/
static const s64 size_align_ctrl_qmenu[] = {
1, (64 * 1024), (128 * 1024),
};
struct camera_common_frmfmt {
struct v4l2_frmsize_discrete size;
const int *framerates;
int num_framerates;
bool hdr_en;
int mode;
};
struct camera_common_colorfmt {
unsigned int code;
enum v4l2_colorspace colorspace;
int pix_fmt;
enum v4l2_xfer_func xfer_func;
enum v4l2_ycbcr_encoding ycbcr_enc;
enum v4l2_quantization quantization;
};
struct camera_common_framesync {
u32 inck; /* kHz */
u32 xhs; /* in inck */
u32 xvs; /* in xhs */
u32 fps; /* frames in 1000 second */
};
struct tegracam_device ;
struct camera_common_data;
struct camera_common_sensor_ops {
u32 numfrmfmts;
const struct camera_common_frmfmt *frmfmt_table;
int (*power_on)(struct camera_common_data *s_data);
int (*power_off)(struct camera_common_data *s_data);
int (*write_reg)(struct camera_common_data *s_data,
u16 addr, u8 val);
int (*read_reg)(struct camera_common_data *s_data,
u16 addr, u8 *val);
struct camera_common_pdata *(*parse_dt)(struct tegracam_device *tc_dev);
int (*power_get)(struct tegracam_device *tc_dev);
int (*power_put)(struct tegracam_device *tc_dev);
int (*get_framesync)(struct camera_common_data *s_data,
struct camera_common_framesync *vshs);
int (*set_mode)(struct tegracam_device *tc_dev);
int (*start_streaming)(struct tegracam_device *tc_dev);
int (*stop_streaming)(struct tegracam_device *tc_dev);
};
struct tegracam_sensor_data {
struct sensor_blob mode_blob;
struct sensor_blob ctrls_blob;
};
struct tegracam_ctrl_ops {
u32 numctrls;
u32 string_ctrl_size[TEGRA_CAM_MAX_STRING_CONTROLS];
const u32 *ctrl_cid_list;
bool is_blob_supported;
int (*set_gain)(struct tegracam_device *tc_dev, s64 val);
int (*set_exposure)(struct tegracam_device *tc_dev, s64 val);
int (*set_exposure_short)(struct tegracam_device *tc_dev, s64 val);
int (*set_frame_rate)(struct tegracam_device *tc_dev, s64 val);
int (*set_group_hold)(struct tegracam_device *tc_dev, bool val);
int (*fill_string_ctrl)(struct tegracam_device *tc_dev,
struct v4l2_ctrl *ctrl);
int (*set_gain_ex)(struct tegracam_device *tc_dev,
struct sensor_blob *blob, s64 val);
int (*set_exposure_ex)(struct tegracam_device *tc_dev,
struct sensor_blob *blob, s64 val);
int (*set_frame_rate_ex)(struct tegracam_device *tc_dev,
struct sensor_blob *blob, s64 val);
int (*set_group_hold_ex)(struct tegracam_device *tc_dev,
struct sensor_blob *blob, bool val);
int (*set_analog_gain)(struct tegracam_device *tc_dev, s64 val);
int (*set_digital_gain)(struct tegracam_device *tc_dev, s64 val,
int id);
int (*set_test_pattern)(struct tegracam_device *tc_dev, s32 val);
int (*set_flash)(struct tegracam_device *tc_dev, s32 val);
int (*set_flip)(struct tegracam_device *tc_dev, s32 val, int id);
};
struct tegracam_ctrl_handler {
struct v4l2_ctrl_handler ctrl_handler;
const struct tegracam_ctrl_ops *ctrl_ops;
struct tegracam_device *tc_dev;
struct tegracam_sensor_data sensor_data;
int numctrls;
struct v4l2_ctrl *ctrls[MAX_CID_CONTROLS];
};
struct camera_common_data {
struct camera_common_sensor_ops *ops;
struct v4l2_ctrl_handler *ctrl_handler;
struct device *dev;
const struct camera_common_frmfmt *frmfmt;
const struct camera_common_colorfmt *colorfmt;
struct dentry *debugdir;
struct camera_common_power_rail *power;
struct v4l2_subdev subdev;
struct v4l2_ctrl **ctrls;
struct sensor_properties sensor_props;
/* TODO: cleanup neeeded once all the sensors adapt new framework */
struct tegracam_ctrl_handler *tegracam_ctrl_hdl;
struct regmap *regmap;
struct camera_common_pdata *pdata;
/* TODO: cleanup needed for priv once all the sensors adapt new framework */
void *priv;
int numctrls;
int csi_port;
int numlanes;
int mode;
int mode_prop_idx;
int numfmts;
int def_mode, def_width, def_height;
int def_clk_freq;
int fmt_width, fmt_height;
int sensor_mode_id;
bool use_sensor_mode_id;
bool override_enable;
u32 version;
};
struct camera_common_focuser_data;
struct camera_common_focuser_ops {
int (*power_on)(struct camera_common_focuser_data *s_data);
int (*power_off)(struct camera_common_focuser_data *s_data);
int (*load_config)(struct camera_common_focuser_data *s_data);
int (*ctrls_init)(struct camera_common_focuser_data *s_data);
};
struct camera_common_focuser_data {
struct camera_common_focuser_ops *ops;
struct v4l2_ctrl_handler *ctrl_handler;
struct v4l2_subdev subdev;
struct v4l2_ctrl **ctrls;
struct device *dev;
struct nv_focuser_config config;
void *priv;
int pwr_dev;
int def_position;
};
static inline void msleep_range(unsigned int delay_base)
{
usleep_range(delay_base * 1000, delay_base * 1000 + 500);
}
static inline struct camera_common_data *to_camera_common_data(
const struct device *dev)
{
if (sensor_common_parse_num_modes(dev))
return container_of(dev_get_drvdata(dev),
struct camera_common_data, subdev);
return NULL;
}
static inline struct camera_common_focuser_data *to_camera_common_focuser_data(
const struct device *dev)
{
return container_of(dev_get_drvdata(dev),
struct camera_common_focuser_data, subdev);
}
int camera_common_g_ctrl(struct camera_common_data *s_data,
struct v4l2_control *control);
int camera_common_regulator_get(struct device *dev,
struct regulator **vreg, const char *vreg_name);
int camera_common_parse_clocks(struct device *dev,
struct camera_common_pdata *pdata);
int camera_common_parse_ports(struct device *dev,
struct camera_common_data *s_data);
int camera_common_mclk_enable(struct camera_common_data *s_data);
void camera_common_mclk_disable(struct camera_common_data *s_data);
int camera_common_debugfs_show(struct seq_file *s, void *unused);
ssize_t camera_common_debugfs_write(
struct file *file,
char const __user *buf,
size_t count,
loff_t *offset);
int camera_common_debugfs_open(struct inode *inode, struct file *file);
void camera_common_remove_debugfs(struct camera_common_data *s_data);
void camera_common_create_debugfs(struct camera_common_data *s_data,
const char *name);
const struct camera_common_colorfmt *camera_common_find_datafmt(
unsigned int code);
int camera_common_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code);
int camera_common_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
unsigned int *code);
int camera_common_try_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf);
int camera_common_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);
int camera_common_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);
int camera_common_enum_framesizes(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_size_enum *fse);
int camera_common_enum_frameintervals(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_frame_interval_enum *fie);
int camera_common_set_power(struct camera_common_data *data, int on);
int camera_common_s_power(struct v4l2_subdev *sd, int on);
void camera_common_dpd_disable(struct camera_common_data *s_data);
void camera_common_dpd_enable(struct camera_common_data *s_data);
int camera_common_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg);
int camera_common_get_framesync(struct v4l2_subdev *sd,
struct camera_common_framesync *vshs);
/* Common initialize and cleanup for camera */
int camera_common_initialize(struct camera_common_data *s_data,
const char *dev_name);
void camera_common_cleanup(struct camera_common_data *s_data);
/* Focuser */
int camera_common_focuser_init(struct camera_common_focuser_data *s_data);
int camera_common_focuser_s_power(struct v4l2_subdev *sd, int on);
const struct camera_common_colorfmt *camera_common_find_pixelfmt(
unsigned int pix_fmt);
/* common control layer init */
int tegracam_ctrl_set_overrides(struct tegracam_ctrl_handler *handler);
int tegracam_ctrl_handler_init(struct tegracam_ctrl_handler *handler);
int tegracam_init_ctrl_ranges(struct tegracam_ctrl_handler *handler);
int tegracam_init_ctrl_ranges_by_mode(
struct tegracam_ctrl_handler *handler,
u32 modeidx);
/* Regmap / RTCPU I2C driver interface */
struct tegra_i2c_rtcpu_sensor;
struct tegra_i2c_rtcpu_config;
struct camera_common_i2c {
struct regmap *regmap;
struct tegra_i2c_rtcpu_sensor *rt_sensor;
};
int camera_common_i2c_init(
struct camera_common_i2c *sensor,
struct i2c_client *client,
struct regmap_config *regmap_config,
const struct tegra_i2c_rtcpu_config *rtcpu_config);
int camera_common_i2c_aggregate(
struct camera_common_i2c *sensor,
bool start);
int camera_common_i2c_set_frame_id(
struct camera_common_i2c *sensor,
int frame_id);
int camera_common_i2c_read_reg8(
struct camera_common_i2c *sensor,
unsigned int addr,
u8 *data,
unsigned int count);
int camera_common_i2c_write_reg8(
struct camera_common_i2c *sensor,
unsigned int addr,
const u8 *data,
unsigned int count);
int camera_common_i2c_write_table_8(
struct camera_common_i2c *sensor,
const struct reg_8 table[],
const struct reg_8 override_list[],
int num_override_regs, u16 wait_ms_addr, u16 end_addr);
#endif /* __camera_common__ */

View File

@ -1,181 +0,0 @@
/**
* TEGRA_V4L2_CAMERA.h - utilities for tegra camera driver
*
* Copyright (c) 2017-2019, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/
#ifndef __TEGRA_V4L2_CAMERA__
#define __TEGRA_V4L2_CAMERA__
#include <linux/v4l2-controls.h>
#define TEGRA_CAMERA_CID_BASE (V4L2_CTRL_CLASS_CAMERA | 0x2000)
#define TEGRA_CAMERA_CID_FRAME_LENGTH (TEGRA_CAMERA_CID_BASE+0)
#define TEGRA_CAMERA_CID_COARSE_TIME (TEGRA_CAMERA_CID_BASE+1)
#define TEGRA_CAMERA_CID_COARSE_TIME_SHORT (TEGRA_CAMERA_CID_BASE+2)
#define TEGRA_CAMERA_CID_GROUP_HOLD (TEGRA_CAMERA_CID_BASE+3)
#define TEGRA_CAMERA_CID_HDR_EN (TEGRA_CAMERA_CID_BASE+4)
#define TEGRA_CAMERA_CID_EEPROM_DATA (TEGRA_CAMERA_CID_BASE+5)
#define TEGRA_CAMERA_CID_OTP_DATA (TEGRA_CAMERA_CID_BASE+6)
#define TEGRA_CAMERA_CID_FUSE_ID (TEGRA_CAMERA_CID_BASE+7)
#define TEGRA_CAMERA_CID_SENSOR_MODE_ID (TEGRA_CAMERA_CID_BASE+8)
#define TEGRA_CAMERA_CID_GAIN (TEGRA_CAMERA_CID_BASE+9)
#define TEGRA_CAMERA_CID_EXPOSURE (TEGRA_CAMERA_CID_BASE+10)
#define TEGRA_CAMERA_CID_FRAME_RATE (TEGRA_CAMERA_CID_BASE+11)
#define TEGRA_CAMERA_CID_EXPOSURE_SHORT (TEGRA_CAMERA_CID_BASE+12)
#define TEGRA_CAMERA_CID_SENSOR_CONFIG (TEGRA_CAMERA_CID_BASE+50)
#define TEGRA_CAMERA_CID_SENSOR_MODE_BLOB (TEGRA_CAMERA_CID_BASE+51)
#define TEGRA_CAMERA_CID_SENSOR_CONTROL_BLOB (TEGRA_CAMERA_CID_BASE+52)
#define TEGRA_CAMERA_CID_VI_BYPASS_MODE (TEGRA_CAMERA_CID_BASE+100)
#define TEGRA_CAMERA_CID_OVERRIDE_ENABLE (TEGRA_CAMERA_CID_BASE+101)
#define TEGRA_CAMERA_CID_VI_HEIGHT_ALIGN (TEGRA_CAMERA_CID_BASE+102)
#define TEGRA_CAMERA_CID_VI_SIZE_ALIGN (TEGRA_CAMERA_CID_BASE+103)
#define TEGRA_CAMERA_CID_WRITE_ISPFORMAT (TEGRA_CAMERA_CID_BASE+104)
#define TEGRA_CAMERA_CID_SENSOR_SIGNAL_PROPERTIES (TEGRA_CAMERA_CID_BASE+105)
#define TEGRA_CAMERA_CID_SENSOR_IMAGE_PROPERTIES (TEGRA_CAMERA_CID_BASE+106)
#define TEGRA_CAMERA_CID_SENSOR_CONTROL_PROPERTIES (TEGRA_CAMERA_CID_BASE+107)
#define TEGRA_CAMERA_CID_SENSOR_DV_TIMINGS (TEGRA_CAMERA_CID_BASE+108)
#define TEGRA_CAMERA_CID_LOW_LATENCY (TEGRA_CAMERA_CID_BASE+109)
/* Custom Controls */
#define V4L2_CID_GAIN_RED V4L2_CID_USER_BASE
#define V4L2_CID_GAIN_GREENR V4L2_CID_USER_BASE + 1
#define V4L2_CID_GAIN_GREENB V4L2_CID_USER_BASE + 2
#define V4L2_CID_GAIN_BLUE V4L2_CID_USER_BASE + 3
/**
* This is temporary with the current v4l2 infrastructure
* currently discussing with upstream maintainers our proposals and
* better approaches to resolve this
*/
#define TEGRA_CAMERA_CID_SENSOR_MODES (TEGRA_CAMERA_CID_BASE + 130)
#define MAX_BUFFER_SIZE 32
#define MAX_CID_CONTROLS 32
#define MAX_NUM_SENSOR_MODES 30
#define OF_MAX_STR_LEN 256
#define OF_SENSORMODE_PREFIX ("mode")
/*
* Scaling factor for converting a Q10.22 fixed point value
* back to its original floating point value
*/
#define FIXED_POINT_SCALING_FACTOR (1ULL << 22)
#define TEGRA_CAM_MAX_STRING_CONTROLS 8
#define TEGRA_CAM_STRING_CTRL_EEPROM_INDEX 0
#define TEGRA_CAM_STRING_CTRL_FUSEID_INDEX 1
#define TEGRA_CAM_STRING_CTRL_OTP_INDEX 2
#define CSI_PHY_MODE_DPHY 0
#define CSI_PHY_MODE_CPHY 1
#define SLVS_EC 2
struct unpackedU64 {
__u32 high;
__u32 low;
};
union __u64val {
struct unpackedU64 unpacked;
__u64 val;
};
struct sensor_signal_properties {
__u32 readout_orientation;
__u32 num_lanes;
__u32 mclk_freq;
union __u64val pixel_clock;
__u32 cil_settletime;
__u32 discontinuous_clk;
__u32 dpcm_enable;
__u32 tegra_sinterface;
__u32 phy_mode;
__u32 deskew_initial_enable;
__u32 deskew_periodic_enable;
union __u64val serdes_pixel_clock;
__u32 reserved[2];
};
struct sensor_image_properties {
__u32 width;
__u32 height;
__u32 line_length;
__u32 pixel_format;
__u32 embedded_metadata_height;
__u32 reserved[11];
};
struct sensor_dv_timings {
__u32 hfrontporch;
__u32 hsync;
__u32 hbackporch;
__u32 vfrontporch;
__u32 vsync;
__u32 vbackporch;
__u32 reserved[10];
};
struct sensor_control_properties {
__u32 gain_factor;
__u32 framerate_factor;
__u32 inherent_gain;
__u32 min_gain_val;
__u32 max_gain_val;
__u32 min_hdr_ratio;
__u32 max_hdr_ratio;
__u32 min_framerate;
__u32 max_framerate;
union __u64val min_exp_time;
union __u64val max_exp_time;
__u32 step_gain_val;
__u32 step_framerate;
__u32 exposure_factor;
union __u64val step_exp_time;
__u32 default_gain;
__u32 default_framerate;
union __u64val default_exp_time;
__u32 reserved[10];
};
struct sensor_mode_properties {
struct sensor_signal_properties signal_properties;
struct sensor_image_properties image_properties;
struct sensor_control_properties control_properties;
struct sensor_dv_timings dv_timings;
};
#define SENSOR_SIGNAL_PROPERTIES_CID_SIZE \
(sizeof(struct sensor_signal_properties) / sizeof(__u32))
#define SENSOR_IMAGE_PROPERTIES_CID_SIZE \
(sizeof(struct sensor_image_properties) / sizeof(__u32))
#define SENSOR_CONTROL_PROPERTIES_CID_SIZE \
(sizeof(struct sensor_control_properties) / sizeof(__u32))
#define SENSOR_DV_TIMINGS_CID_SIZE \
(sizeof(struct sensor_dv_timings) / sizeof(__u32))
#define SENSOR_MODE_PROPERTIES_CID_SIZE \
(sizeof(struct sensor_mode_properties) / sizeof(__u32))
#define SENSOR_CONFIG_SIZE \
(sizeof(struct sensor_cfg) / sizeof(__u32))
#define SENSOR_MODE_BLOB_SIZE \
(sizeof(struct sensor_blob) / sizeof(__u32))
#define SENSOR_CTRL_BLOB_SIZE \
(sizeof(struct sensor_blob) / sizeof(__u32))
#endif /* __TEGRA_V4L2_CAMERA__ */