Add Driver files

This commit is contained in:
dchvs 2021-01-20 09:46:28 -06:00
parent 32d9f5e2a5
commit f51aa9f2ac
7 changed files with 3946 additions and 0 deletions

View File

@ -0,0 +1,47 @@
#ifndef MT9M021_H
#define MT9M021_H
struct v4l2_subdev;
/*
* struct mt9m021_platform_data - MT9M021 platform data
* @reset: Chip reset GPIO (set to -1 if not used)
* @ext_freq: Input clock frequency
* @target_freq: Pixel clock frequency
*/
static uint16_t mt9m021_seq_data[] = {
0x3227, 0x0101, 0x0F25, 0x0808, 0x0227, 0x0101, 0x0837, 0x2700,
0x0138, 0x2701, 0x013A, 0x2700, 0x0125, 0x0020, 0x3C25, 0x0040,
0x3427, 0x003F, 0x2500, 0x2037, 0x2540, 0x4036, 0x2500, 0x4031,
0x2540, 0x403D, 0x6425, 0x2020, 0x3D64, 0x2510, 0x1037, 0x2520,
0x2010, 0x2510, 0x100F, 0x2708, 0x0802, 0x2540, 0x402D, 0x2608,
0x280D, 0x1709, 0x2600, 0x2805, 0x26A7, 0x2807, 0x2580, 0x8029,
0x1705, 0x2500, 0x4027, 0x2222, 0x1616, 0x2726, 0x2617, 0x3626,
0xA617, 0x0326, 0xA417, 0x1F28, 0x0526, 0x2028, 0x0425, 0x2020,
0x2700, 0x2625, 0x0000, 0x171E, 0x2500, 0x0425, 0x0020, 0x2117,
0x121B, 0x1703, 0x2726, 0x2617, 0x2828, 0x0517, 0x1A26, 0x6017,
0xAE25, 0x0080, 0x2700, 0x2626, 0x1828, 0x002E, 0x2A28, 0x081E,
0x4127, 0x1010, 0x0214, 0x6060, 0x0A14, 0x6060, 0x0B14, 0x6060,
0x0C14, 0x6060, 0x0D14, 0x6060, 0x0217, 0x3C14, 0x0060, 0x0A14,
0x0060, 0x0B14, 0x0060, 0x0C14, 0x0060, 0x0D14, 0x0060, 0x0811,
0x2500, 0x1027, 0x0010, 0x2F6F, 0x0F3E, 0x2500, 0x0827, 0x0008,
0x3066, 0x3225, 0x0008, 0x2700, 0x0830, 0x6631, 0x3D64, 0x2508,
0x083D, 0xFF3D, 0x2A27, 0x083F, 0x2C00
};
static uint16_t mt9m021_analog_setting[] = {
0x00FD, 0x0FFF, 0x0003, 0xF87A, 0xE075, 0x077C, 0xA4EB, 0xD208
};
/***************************************************
NVIDIA Camera Common Defines
****************************************************/
enum mt9m021_modes{
MT9M021_DEFAULT_MODE
};
static const int mt9m021_framerates[] = {10, 20, 30, 40, 50, 60,};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
/*
* mt9m021_mode_tbls.h - MT9M021 sensor mode tables
*
* Copyright (c) 2019, RidgeRun. All rights reserved.
*
* Author: Enrique Ramírez (enrique.ramirez@ridgerun.com)
*
* 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 __MT9M021_I2C_TABLES__
#define __MT9M021_I2C_TABLES__
#include <media/camera_common.h>
#define MT9M021_TABLE_WAIT_MS 0
#define MT9M021_TABLE_END 1
#define MT9M021_MAX_RETRIES 6
#define MT9M021_WAIT_MS 10
#define mt9m021_reg struct reg_16
static const mt9m021_reg mt9m021_start[] = {
{0x301A, 0x00DC}, /* Enable Streaming */
{MT9M021_TABLE_END, 0x00}
};
static const mt9m021_reg mt9m021_stop[] = {
{0x301A, 0x00D8}, /* Disable Streaming */
{MT9M021_TABLE_END, 0x00}
};
static uint16_t mt9m021_seq_data[] = {
0x3227, 0x0101, 0x0F25, 0x0808, 0x0227, 0x0101, 0x0837, 0x2700,
0x0138, 0x2701, 0x013A, 0x2700, 0x0125, 0x0020, 0x3C25, 0x0040,
0x3427, 0x003F, 0x2500, 0x2037, 0x2540, 0x4036, 0x2500, 0x4031,
0x2540, 0x403D, 0x6425, 0x2020, 0x3D64, 0x2510, 0x1037, 0x2520,
0x2010, 0x2510, 0x100F, 0x2708, 0x0802, 0x2540, 0x402D, 0x2608,
0x280D, 0x1709, 0x2600, 0x2805, 0x26A7, 0x2807, 0x2580, 0x8029,
0x1705, 0x2500, 0x4027, 0x2222, 0x1616, 0x2726, 0x2617, 0x3626,
0xA617, 0x0326, 0xA417, 0x1F28, 0x0526, 0x2028, 0x0425, 0x2020,
0x2700, 0x2625, 0x0000, 0x171E, 0x2500, 0x0425, 0x0020, 0x2117,
0x121B, 0x1703, 0x2726, 0x2617, 0x2828, 0x0517, 0x1A26, 0x6017,
0xAE25, 0x0080, 0x2700, 0x2626, 0x1828, 0x002E, 0x2A28, 0x081E,
0x4127, 0x1010, 0x0214, 0x6060, 0x0A14, 0x6060, 0x0B14, 0x6060,
0x0C14, 0x6060, 0x0D14, 0x6060, 0x0217, 0x3C14, 0x0060, 0x0A14,
0x0060, 0x0B14, 0x0060, 0x0C14, 0x0060, 0x0D14, 0x0060, 0x0811,
0x2500, 0x1027, 0x0010, 0x2F6F, 0x0F3E, 0x2500, 0x0827, 0x0008,
0x3066, 0x3225, 0x0008, 0x2700, 0x0830, 0x6631, 0x3D64, 0x2508,
0x083D, 0xFF3D, 0x2A27, 0x083F, 0x2C00
};
static const mt9m021_reg mt9m021_pll_setup[] = {
{0x302C, 0x0001}, /* VT_PIX_CLK_DIV */
{0x302A, 0x0008}, /* VT_SYS_CLK_DIV */
{0x302E, 0x0004}, /* PRE_PLL_CLK_DIV */
{0x3030, 0x0063}, /* PLL_MULTIPLIER */
{0x30B0, 0x0000}, /* DIGITAL_TEST */
{MT9M021_TABLE_END, 0x00}
};
static const mt9m021_reg mt9m021_mode_1280x720_60fps[] = {
/* 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, 0x0078}, /* Y ADDR START */
{0x3004, 0x0001}, /* X ADDR START */
{0x3006, 0x0347}, /* Y ADDR END */
{0x3008, 0x0500}, /* X ADDR END */
{0x300A, 0x02EE}, /* FRAME_LENGTH_LINES */
{0x300C, 0x0672}, /* LINE_LENGTH_PCK */
{0x30A2, 0x0001}, /* X_ODD_INC */
{0x30A6, 0x0001}, /* Y_ODD_INC */
{MT9M021_TABLE_END, 0x00}
};
enum {
MT9M021_MODE_1280x720_60FPS,
MT9M021_MODE_PLL_SETUP,
MT9M021_MODE_START_STREAM,
MT9M021_MODE_STOP_STREAM,
};
static const mt9m021_reg *mode_table[] = {
[MT9M021_MODE_1280x720_60FPS] = mt9m021_mode_1280x720_60fps,
[MT9M021_MODE_PLL_SETUP] = mt9m021_pll_setup,
[MT9M021_MODE_START_STREAM] = mt9m021_start,
[MT9M021_MODE_STOP_STREAM] = mt9m021_stop,
};
static const int mt9m021_framerates[] = {
10,
20,
30,
40,
50,
60,
};
static const struct camera_common_frmfmt mt9m021_frmfmt[] = {
{{1280, 720}, mt9m021_framerates, 1, 0, MT9M021_MODE_1280x720_60FPS},
};
#endif /* __MT9M021_I2C_TABLES__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,786 @@
/*
* 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

@ -0,0 +1,413 @@
/**
* 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

@ -0,0 +1,181 @@
/**
* 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__ */