jetpack-4.4.1 #1
72
README.md
72
README.md
|
@ -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.
|
||||
|
||||
.
|
||||
├── 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>
|
||||
|
|
|
@ -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";
|
||||
|
||||
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";
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
|
@ -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__ */
|
|
@ -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__ */
|
Loading…
Reference in New Issue