diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 30bcfa71..a833d9c5 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -5,3 +5,4 @@ subdir-ccflags-y += -Werror obj-m += nv_imx185.o obj-m += nv_imx274.o +obj-m += nv_ov5693.o diff --git a/drivers/media/i2c/nv_ov5693.c b/drivers/media/i2c/nv_ov5693.c new file mode 100644 index 00000000..1b682c8d --- /dev/null +++ b/drivers/media/i2c/nv_ov5693.c @@ -0,0 +1,1276 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2013-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * nv_ov5693.c - ov5693 sensor driver + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../platform/tegra/camera/camera_gpio.h" +#include "ov5693_mode_tbls.h" +#define CREATE_TRACE_POINTS +#include + +#define OV5693_MAX_COARSE_DIFF 6 +#define OV5693_MAX_FRAME_LENGTH (0x7fff) +#define OV5693_MIN_EXPOSURE_COARSE (0x0002) +#define OV5693_MAX_EXPOSURE_COARSE \ + (OV5693_MAX_FRAME_LENGTH-OV5693_MAX_COARSE_DIFF) +#define OV5693_DEFAULT_LINE_LENGTH (0xA80) +#define OV5693_DEFAULT_PIXEL_CLOCK (160) +#define OV5693_DEFAULT_FRAME_LENGTH (0x07C0) +#define OV5693_DEFAULT_EXPOSURE_COARSE \ + (OV5693_DEFAULT_FRAME_LENGTH-OV5693_MAX_COARSE_DIFF) + +static const u32 ctrl_cid_list[] = { + TEGRA_CAMERA_CID_GAIN, + TEGRA_CAMERA_CID_EXPOSURE, + TEGRA_CAMERA_CID_EXPOSURE_SHORT, + TEGRA_CAMERA_CID_FRAME_RATE, + TEGRA_CAMERA_CID_HDR_EN, + TEGRA_CAMERA_CID_EEPROM_DATA, + TEGRA_CAMERA_CID_OTP_DATA, + TEGRA_CAMERA_CID_FUSE_ID, +}; + +struct ov5693 { + struct camera_common_eeprom_data eeprom[OV5693_EEPROM_NUM_BLOCKS]; + u8 eeprom_buf[OV5693_EEPROM_SIZE]; + u8 otp_buf[OV5693_OTP_SIZE]; + struct i2c_client *i2c_client; + struct v4l2_subdev *subdev; + u8 fuse_id[OV5693_FUSE_ID_SIZE]; + const char *devname; + struct dentry *debugfs_dir; + struct mutex streaming_lock; + bool streaming; + + s32 group_hold_prev; + u32 frame_length; + bool group_hold_en; + struct camera_common_i2c i2c_dev; + struct camera_common_data *s_data; + struct tegracam_device *tc_dev; +}; + +static struct regmap_config ov5693_regmap_config = { + .reg_bits = 16, + .val_bits = 8, +}; + +static inline void ov5693_get_frame_length_regs(ov5693_reg *regs, + u32 frame_length) +{ + regs->addr = OV5693_FRAME_LENGTH_ADDR_MSB; + regs->val = (frame_length >> 8) & 0xff; + (regs + 1)->addr = OV5693_FRAME_LENGTH_ADDR_LSB; + (regs + 1)->val = (frame_length) & 0xff; +} + +static inline void ov5693_get_coarse_time_regs(ov5693_reg *regs, + u32 coarse_time) +{ + regs->addr = OV5693_COARSE_TIME_ADDR_1; + regs->val = (coarse_time >> 12) & 0xff; + (regs + 1)->addr = OV5693_COARSE_TIME_ADDR_2; + (regs + 1)->val = (coarse_time >> 4) & 0xff; + (regs + 2)->addr = OV5693_COARSE_TIME_ADDR_3; + (regs + 2)->val = (coarse_time & 0xf) << 4; +} + +static inline void ov5693_get_coarse_time_short_regs(ov5693_reg *regs, + u32 coarse_time) +{ + regs->addr = OV5693_COARSE_TIME_SHORT_ADDR_1; + regs->val = (coarse_time >> 12) & 0xff; + (regs + 1)->addr = OV5693_COARSE_TIME_SHORT_ADDR_2; + (regs + 1)->val = (coarse_time >> 4) & 0xff; + (regs + 2)->addr = OV5693_COARSE_TIME_SHORT_ADDR_3; + (regs + 2)->val = (coarse_time & 0xf) << 4; +} + +static inline void ov5693_get_gain_regs(ov5693_reg *regs, + u16 gain) +{ + regs->addr = OV5693_GAIN_ADDR_MSB; + regs->val = (gain >> 8) & 0xff; + + (regs + 1)->addr = OV5693_GAIN_ADDR_LSB; + (regs + 1)->val = (gain) & 0xff; +} + +static int test_mode; +module_param(test_mode, int, 0644); + +static inline int ov5693_read_reg(struct camera_common_data *s_data, + u16 addr, u8 *val) +{ + int err = 0; + u32 reg_val = 0; + + err = regmap_read(s_data->regmap, addr, ®_val); + *val = reg_val & 0xFF; + + return err; +} + +static int ov5693_write_reg(struct camera_common_data *s_data, u16 addr, u8 val) +{ + int err; + struct device *dev = s_data->dev; + + err = regmap_write(s_data->regmap, addr, val); + + if (err) + dev_err(dev, "%s: i2c write failed, 0x%x = %x\n", + __func__, addr, val); + + return err; +} + +static int ov5693_write_table(struct ov5693 *priv, + const ov5693_reg table[]) +{ + struct camera_common_data *s_data = priv->s_data; + + return regmap_util_write_table_8(s_data->regmap, + table, + NULL, 0, + OV5693_TABLE_WAIT_MS, + OV5693_TABLE_END); +} + +static void ov5693_gpio_set(struct camera_common_data *s_data, + unsigned int gpio, int val) +{ + struct camera_common_pdata *pdata = s_data->pdata; + + if (pdata && pdata->use_cam_gpio) + cam_gpio_ctrl(s_data->dev, gpio, val, 1); + else { + if (gpio_cansleep(gpio)) + gpio_set_value_cansleep(gpio, val); + else + gpio_set_value(gpio, val); + } +} + +static int ov5693_power_on(struct camera_common_data *s_data) +{ + int err = 0; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = s_data->dev; + + + dev_dbg(dev, "%s: power on\n", __func__); + + if (pdata && pdata->power_on) { + err = pdata->power_on(pw); + if (err) + dev_err(dev, "%s failed.\n", __func__); + else + pw->state = SWITCH_ON; + return err; + } + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor + */ + + if (pw->avdd) + err = regulator_enable(pw->avdd); + if (err) + goto ov5693_avdd_fail; + + if (pw->iovdd) + err = regulator_enable(pw->iovdd); + if (err) + goto ov5693_iovdd_fail; + + usleep_range(1, 2); + if (gpio_is_valid(pw->pwdn_gpio)) + ov5693_gpio_set(s_data, pw->pwdn_gpio, 1); + + /* + * datasheet 2.9: reset requires ~2ms settling time + * a power on reset is generated after core power becomes stable + */ + usleep_range(2000, 2010); + + if (gpio_is_valid(pw->reset_gpio)) + ov5693_gpio_set(s_data, pw->reset_gpio, 1); + + /* datasheet fig 2-9: t3 */ + usleep_range(2000, 2010); + + pw->state = SWITCH_ON; + + + return 0; + +ov5693_iovdd_fail: + regulator_disable(pw->avdd); + +ov5693_avdd_fail: + dev_err(dev, "%s failed.\n", __func__); + return -ENODEV; +} + +static int ov5693_power_off(struct camera_common_data *s_data) +{ + int err = 0; + struct camera_common_power_rail *pw = s_data->power; + struct device *dev = s_data->dev; + struct camera_common_pdata *pdata = s_data->pdata; + + dev_dbg(dev, "%s: power off\n", __func__); + + if (pdata && pdata->power_off) { + err = pdata->power_off(pw); + if (!err) { + goto power_off_done; + } else { + dev_err(dev, "%s failed.\n", __func__); + return err; + } + } + + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor + */ + usleep_range(21, 25); + if (gpio_is_valid(pw->pwdn_gpio)) + ov5693_gpio_set(s_data, pw->pwdn_gpio, 0); + usleep_range(1, 2); + if (gpio_is_valid(pw->reset_gpio)) + ov5693_gpio_set(s_data, pw->reset_gpio, 0); + + /* datasheet 2.9: reset requires ~2ms settling time*/ + usleep_range(2000, 2010); + + if (pw->iovdd) + regulator_disable(pw->iovdd); + if (pw->avdd) + regulator_disable(pw->avdd); + +power_off_done: + pw->state = SWITCH_OFF; + return 0; +} + +static int ov5693_power_put(struct tegracam_device *tc_dev) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = tc_dev->dev; + + if (unlikely(!pw)) + return -EFAULT; + + if (pdata && pdata->use_cam_gpio) + cam_gpio_deregister(dev, pw->pwdn_gpio); + else { + if (gpio_is_valid(pw->pwdn_gpio)) + gpio_free(pw->pwdn_gpio); + if (gpio_is_valid(pw->reset_gpio)) + gpio_free(pw->reset_gpio); + } + + return 0; +} + +static int ov5693_power_get(struct tegracam_device *tc_dev) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_power_rail *pw = s_data->power; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = tc_dev->dev; + const char *mclk_name; + const char *parentclk_name; + struct clk *parent; + int err = 0, ret = 0; + + if (!pdata) { + dev_err(dev, "pdata missing\n"); + return -EFAULT; + } + + mclk_name = pdata->mclk_name ? + pdata->mclk_name : "cam_mclk1"; + pw->mclk = devm_clk_get(dev, mclk_name); + if (IS_ERR(pw->mclk)) { + dev_err(dev, "unable to get clock %s\n", mclk_name); + return PTR_ERR(pw->mclk); + } + parentclk_name = pdata->parentclk_name; + if (parentclk_name) { + parent = devm_clk_get(dev, parentclk_name); + if (IS_ERR(parent)) { + dev_err(dev, "unable to get parent clcok %s", + parentclk_name); + } else + clk_set_parent(pw->mclk, parent); + } + + /* analog 2.8v */ + err |= camera_common_regulator_get(dev, + &pw->avdd, pdata->regulators.avdd); + /* IO 1.8v */ + err |= camera_common_regulator_get(dev, + &pw->iovdd, pdata->regulators.iovdd); + + if (!err) { + pw->reset_gpio = pdata->reset_gpio; + pw->pwdn_gpio = pdata->pwdn_gpio; + } + if (pdata->use_cam_gpio) { + if (cam_gpio_register(dev, pw->pwdn_gpio)) + dev_err(dev, "%s ERR can't register cam gpio %u!\n", + __func__, pw->pwdn_gpio); + } else { + if (gpio_is_valid(pw->pwdn_gpio)) { + ret = gpio_request(pw->pwdn_gpio, "cam_pwdn_gpio"); + if (ret < 0) { + dev_dbg(dev, "%s can't request pwdn_gpio %d\n", + __func__, ret); + } + gpio_direction_output(pw->pwdn_gpio, 1); + } + if (gpio_is_valid(pw->reset_gpio)) { + ret = gpio_request(pw->reset_gpio, "cam_reset_gpio"); + if (ret < 0) { + dev_dbg(dev, "%s can't request reset_gpio %d\n", + __func__, ret); + } + gpio_direction_output(pw->reset_gpio, 1); + } + } + + pw->state = SWITCH_OFF; + return err; +} + +static const struct of_device_id ov5693_of_match[] = { + { + .compatible = "ovti,ov5693", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, ov5693_of_match); + +static int ov5693_set_group_hold(struct tegracam_device *tc_dev, bool val) +{ + int err; + struct ov5693 *priv = tc_dev->priv; + int gh_prev = switch_ctrl_qmenu[priv->group_hold_prev]; + struct device *dev = tc_dev->dev; + + if (priv->group_hold_en == true && gh_prev == SWITCH_OFF) { + camera_common_i2c_aggregate(&priv->i2c_dev, true); + /* enter group hold */ + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, val); + if (err) + goto fail; + + priv->group_hold_prev = 1; + + dev_dbg(dev, "%s: enter group hold\n", __func__); + } else if (priv->group_hold_en == false && gh_prev == SWITCH_ON) { + /* leave group hold */ + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, 0x11); + if (err) + goto fail; + + err = ov5693_write_reg(priv->s_data, + OV5693_GROUP_HOLD_ADDR, 0x61); + if (err) + goto fail; + + camera_common_i2c_aggregate(&priv->i2c_dev, false); + + priv->group_hold_prev = 0; + + dev_dbg(dev, "%s: leave group hold\n", __func__); + } + + return 0; + +fail: + dev_dbg(dev, "%s: Group hold control error\n", __func__); + return err; +} + +static int ov5693_set_gain(struct tegracam_device *tc_dev, s64 val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct ov5693 *priv = (struct ov5693 *)tc_dev->priv; + struct device *dev = tc_dev->dev; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; + ov5693_reg reg_list[2]; + int err; + u16 gain; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(tc_dev, 1); + + /* translate value */ + gain = (u16) (((val * 16) + + (mode->control_properties.gain_factor / 2)) / + mode->control_properties.gain_factor); + ov5693_get_gain_regs(reg_list, gain); + dev_dbg(dev, "%s: gain %d val: %lld\n", __func__, gain, val); + + for (i = 0; i < 2; i++) { + err = ov5693_write_reg(s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(dev, "%s: GAIN control error\n", __func__); + return err; +} + +static int ov5693_set_frame_rate(struct tegracam_device *tc_dev, s64 val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + struct ov5693 *priv = tc_dev->priv; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; + ov5693_reg reg_list[2]; + int err; + u32 frame_length; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(tc_dev, 1); + + frame_length = mode->signal_properties.pixel_clock.val * + mode->control_properties.framerate_factor / + mode->image_properties.line_length / val; + + ov5693_get_frame_length_regs(reg_list, frame_length); + dev_dbg(dev, "%s: val: %d\n", __func__, frame_length); + + for (i = 0; i < 2; i++) { + err = ov5693_write_reg(s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + priv->frame_length = frame_length; + + return 0; + +fail: + dev_dbg(dev, "%s: FRAME_LENGTH control error\n", __func__); + return err; +} + +static int ov5693_set_exposure(struct tegracam_device *tc_dev, s64 val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + struct ov5693 *priv = tc_dev->priv; + const s32 max_coarse_time = priv->frame_length - OV5693_MAX_COARSE_DIFF; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; + ov5693_reg reg_list[3]; + int err; + u32 coarse_time; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(tc_dev, 1); + + coarse_time = (u32)(((mode->signal_properties.pixel_clock.val*val) + /mode->image_properties.line_length)/ + mode->control_properties.exposure_factor); + if (coarse_time < OV5693_MIN_EXPOSURE_COARSE) + coarse_time = OV5693_MIN_EXPOSURE_COARSE; + else if (coarse_time > max_coarse_time) + coarse_time = max_coarse_time; + ov5693_get_coarse_time_regs(reg_list, coarse_time); + dev_dbg(dev, "%s: val: %d\n", __func__, coarse_time); + + for (i = 0; i < 3; i++) { + err = ov5693_write_reg(s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(dev, "%s: COARSE_TIME control error\n", __func__); + return err; +} + +static int ov5693_set_exposure_short(struct tegracam_device *tc_dev, s64 val) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct device *dev = tc_dev->dev; + struct ov5693 *priv = tc_dev->priv; + const struct sensor_mode_properties *mode = + &s_data->sensor_props.sensor_modes[s_data->mode_prop_idx]; + ov5693_reg reg_list[3]; + int err; + struct v4l2_control hdr_control; + int hdr_en; + u32 coarse_time_short; + int i; + + if (!priv->group_hold_prev) + ov5693_set_group_hold(tc_dev, 1); + + /* check hdr enable ctrl */ + hdr_control.id = TEGRA_CAMERA_CID_HDR_EN; + + err = camera_common_g_ctrl(s_data, &hdr_control); + if (err < 0) { + dev_err(dev, "could not find device ctrl.\n"); + return err; + } + + hdr_en = switch_ctrl_qmenu[hdr_control.value]; + if (hdr_en == SWITCH_OFF) + return 0; + + coarse_time_short = (u32)(((mode->signal_properties.pixel_clock.val*val) + /mode->image_properties.line_length) + /mode->control_properties.exposure_factor); + + ov5693_get_coarse_time_short_regs(reg_list, coarse_time_short); + dev_dbg(dev, "%s: val: %d\n", __func__, coarse_time_short); + + for (i = 0; i < 3; i++) { + err = ov5693_write_reg(s_data, reg_list[i].addr, + reg_list[i].val); + if (err) + goto fail; + } + + return 0; + +fail: + dev_dbg(dev, "%s: COARSE_TIME_SHORT control error\n", __func__); + return err; +} + +static int ov5693_fill_string_ctrl(struct tegracam_device *tc_dev, + struct v4l2_ctrl *ctrl) +{ + struct ov5693 *priv = tc_dev->priv; + int i, ret, size; + u8 *src; + + switch (ctrl->id) { + case TEGRA_CAMERA_CID_EEPROM_DATA: + size = OV5693_EEPROM_SIZE; + src = priv->eeprom_buf; + break; + case TEGRA_CAMERA_CID_OTP_DATA: + size = OV5693_OTP_SIZE; + src = priv->otp_buf; + break; + case TEGRA_CAMERA_CID_FUSE_ID: + size = OV5693_FUSE_ID_SIZE; + src = priv->fuse_id; + break; + default: + return -EINVAL; + } + + for (i = 0; i < size; i++) { + ret = sprintf(&ctrl->p_new.p_char[i*2], "%02x", src[i]); + if (ret < 0) + return -EINVAL; + } + + ctrl->p_cur.p_char = ctrl->p_new.p_char; + + return 0; +} + +static int ov5693_eeprom_device_release(struct ov5693 *priv) +{ + int i; + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + if (priv->eeprom[i].i2c_client != NULL) { + i2c_unregister_device(priv->eeprom[i].i2c_client); + priv->eeprom[i].i2c_client = NULL; + } + } + + return 0; +} + +static int ov5693_eeprom_device_init(struct ov5693 *priv) +{ + struct camera_common_pdata *pdata = priv->s_data->pdata; + const char *dev_name = "eeprom_ov5693"; + static struct regmap_config eeprom_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + }; + int i; + int err; + + if (!pdata->has_eeprom) + return -EINVAL; + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + priv->eeprom[i].adap = i2c_get_adapter( + priv->i2c_client->adapter->nr); + memset(&priv->eeprom[i].brd, 0, sizeof(priv->eeprom[i].brd)); + strscpy(priv->eeprom[i].brd.type, dev_name, + sizeof(priv->eeprom[i].brd.type)); + priv->eeprom[i].brd.addr = OV5693_EEPROM_ADDRESS + i; + priv->eeprom[i].i2c_client = i2c_new_client_device( + priv->eeprom[i].adap, &priv->eeprom[i].brd); + + priv->eeprom[i].regmap = devm_regmap_init_i2c( + priv->eeprom[i].i2c_client, &eeprom_regmap_config); + if (IS_ERR(priv->eeprom[i].regmap)) { + err = PTR_ERR(priv->eeprom[i].regmap); + ov5693_eeprom_device_release(priv); + return err; + } + } + + return 0; +} + +static int ov5693_read_eeprom(struct ov5693 *priv) +{ + int err, i; + + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + err = regmap_bulk_read(priv->eeprom[i].regmap, 0, + &priv->eeprom_buf[i * OV5693_EEPROM_BLOCK_SIZE], + OV5693_EEPROM_BLOCK_SIZE); + if (err) + return err; + } + + return 0; +} + +static int ov5693_read_otp_bank(struct ov5693 *priv, + u8 *buf, int bank, u16 addr, int size) +{ + int err; + + /* sleeps calls in the sequence below are for internal device + * signal propagation as specified by sensor vendor + */ + usleep_range(10000, 11000); + mutex_lock(&priv->streaming_lock); + err = ov5693_write_table(priv, mode_table[OV5693_MODE_START_STREAM]); + if (err) { + mutex_unlock(&priv->streaming_lock); + return err; + } + + priv->streaming = true; + mutex_unlock(&priv->streaming_lock); + + + err = ov5693_write_reg(priv->s_data, OV5693_OTP_BANK_SELECT_ADDR, + 0xC0 | bank); + if (err) + return err; + + err = ov5693_write_reg(priv->s_data, OV5693_OTP_LOAD_CTRL_ADDR, 0x01); + if (err) + return err; + + usleep_range(10000, 11000); + err = regmap_bulk_read(priv->s_data->regmap, addr, buf, size); + + if (err) + return err; + + mutex_lock(&priv->streaming_lock); + err = ov5693_write_table(priv, mode_table[OV5693_MODE_STOP_STREAM]); + if (err) { + mutex_unlock(&priv->streaming_lock); + return err; + } + + priv->streaming = false; + mutex_unlock(&priv->streaming_lock); + + return 0; +} + +static int ov5693_otp_setup(struct ov5693 *priv) +{ + struct device *dev = priv->s_data->dev; + int err = 0; + int i; + + for (i = 0; i < OV5693_OTP_NUM_BANKS; i++) { + err = ov5693_read_otp_bank(priv, + &priv->otp_buf[i + * OV5693_OTP_BANK_SIZE], + i, + OV5693_OTP_BANK_START_ADDR, + OV5693_OTP_BANK_SIZE); + if (err) { + dev_err(dev, "could not read otp bank\n"); + goto ret; + } + } + +ret: + return err; +} + +static int ov5693_fuse_id_setup(struct ov5693 *priv) +{ + struct device *dev = priv->s_data->dev; + int err; + + err = ov5693_read_otp_bank(priv, + &priv->fuse_id[0], + OV5693_FUSE_ID_OTP_BANK, + OV5693_FUSE_ID_OTP_START_ADDR, + OV5693_FUSE_ID_SIZE); + if (err) { + dev_err(dev, "could not read otp bank\n"); + goto ret; + } + +ret: + return err; +} + +static struct camera_common_pdata *ov5693_parse_dt(struct tegracam_device + *tc_dev) +{ + struct device *dev = tc_dev->dev; + struct device_node *node = dev->of_node; + struct camera_common_pdata *board_priv_pdata; + const struct of_device_id *match; + int gpio; + int err; + struct camera_common_pdata *ret = NULL; + + if (!node) + return NULL; + + match = of_match_device(ov5693_of_match, dev); + if (!match) { + dev_err(dev, "Failed to find matching dt id\n"); + return NULL; + } + + board_priv_pdata = devm_kzalloc(dev, + sizeof(*board_priv_pdata), GFP_KERNEL); + if (!board_priv_pdata) + return NULL; + + err = camera_common_parse_clocks(dev, + board_priv_pdata); + if (err) { + dev_err(dev, "Failed to find clocks\n"); + goto error; + } + + gpio = of_get_named_gpio(node, "pwdn-gpios", 0); + if (gpio < 0) { + if (gpio == -EPROBE_DEFER) { + ret = ERR_PTR(-EPROBE_DEFER); + goto error; + } + gpio = 0; + } + board_priv_pdata->pwdn_gpio = (unsigned int)gpio; + + gpio = of_get_named_gpio(node, "reset-gpios", 0); + if (gpio < 0) { + /* reset-gpio is not absolutely needed */ + if (gpio == -EPROBE_DEFER) { + ret = ERR_PTR(-EPROBE_DEFER); + goto error; + } + dev_dbg(dev, "reset gpios not in DT\n"); + gpio = 0; + } + board_priv_pdata->reset_gpio = (unsigned int)gpio; + + board_priv_pdata->use_cam_gpio = + of_property_read_bool(node, "cam, use-cam-gpio"); + + err = of_property_read_string(node, "avdd-reg", + &board_priv_pdata->regulators.avdd); + if (err) { + dev_err(dev, "avdd-reg not in DT\n"); + goto error; + } + err = of_property_read_string(node, "iovdd-reg", + &board_priv_pdata->regulators.iovdd); + if (err) { + dev_err(dev, "iovdd-reg not in DT\n"); + goto error; + } + + board_priv_pdata->has_eeprom = + of_property_read_bool(node, "has-eeprom"); + board_priv_pdata->v_flip = of_property_read_bool(node, "vertical-flip"); + board_priv_pdata->h_mirror = of_property_read_bool(node, + "horizontal-mirror"); + + return board_priv_pdata; + +error: + return ret; +} + +static int ov5693_set_mode(struct tegracam_device *tc_dev) +{ + struct ov5693 *priv = (struct ov5693 *)tegracam_get_privdata(tc_dev); + struct camera_common_data *s_data = tc_dev->s_data; + int err; + + if (s_data->mode_prop_idx < 0) + return -EINVAL; + + err = ov5693_write_table(priv, mode_table[s_data->mode_prop_idx]); + if (err) + return err; + + return 0; +} + +static int ov5693_start_streaming(struct tegracam_device *tc_dev) +{ + struct ov5693 *priv = (struct ov5693 *)tegracam_get_privdata(tc_dev); + struct camera_common_data *s_data = tc_dev->s_data; + struct camera_common_pdata *pdata = s_data->pdata; + struct device *dev = s_data->dev; + int err; + u8 val; + + mutex_lock(&priv->streaming_lock); + err = ov5693_write_table(priv, mode_table[OV5693_MODE_START_STREAM]); + if (err) { + mutex_unlock(&priv->streaming_lock); + goto exit; + } else { + priv->streaming = true; + mutex_unlock(&priv->streaming_lock); + } + if (pdata->v_flip) { + ov5693_read_reg(s_data, OV5693_TIMING_REG20, &val); + ov5693_write_reg(s_data, OV5693_TIMING_REG20, + val | VERTICAL_FLIP); + } + if (pdata->h_mirror) { + ov5693_read_reg(s_data, OV5693_TIMING_REG21, &val); + ov5693_write_reg(s_data, OV5693_TIMING_REG21, + val | HORIZONTAL_MIRROR_MASK); + } else { + ov5693_read_reg(s_data, OV5693_TIMING_REG21, &val); + ov5693_write_reg(s_data, OV5693_TIMING_REG21, + val & (~HORIZONTAL_MIRROR_MASK)); + } + if (test_mode) { + err = ov5693_write_table(priv, + mode_table[OV5693_MODE_TEST_PATTERN]); + if (err) { + dev_err(dev, "%s: error :write test pattern\n", + __func__); + goto exit; + } + } + + return 0; + +exit: + dev_err(dev, "%s: error starting stream\n", __func__); + return err; +} + +static int ov5693_stop_streaming(struct tegracam_device *tc_dev) +{ + struct camera_common_data *s_data = tc_dev->s_data; + struct ov5693 *priv = (struct ov5693 *)tegracam_get_privdata(tc_dev); + struct device *dev = s_data->dev; + u32 frame_time; + int err; + + mutex_lock(&priv->streaming_lock); + err = ov5693_write_table(priv, + mode_table[OV5693_MODE_STOP_STREAM]); + if (err) { + mutex_unlock(&priv->streaming_lock); + goto exit; + } else { + priv->streaming = false; + mutex_unlock(&priv->streaming_lock); + } + + /* + * Wait for one frame to make sure sensor is set to + * software standby in V-blank + * + * frame_time = frame length rows * Tline + * Tline = line length / pixel clock (in MHz) + */ + frame_time = priv->frame_length * + OV5693_DEFAULT_LINE_LENGTH / OV5693_DEFAULT_PIXEL_CLOCK; + + usleep_range(frame_time, frame_time + 1000); + + return 0; + +exit: + dev_err(dev, "%s: error stopping stream\n", __func__); + return err; +} + +static struct camera_common_sensor_ops ov5693_common_ops = { + .numfrmfmts = ARRAY_SIZE(ov5693_frmfmt), + .frmfmt_table = ov5693_frmfmt, + .power_on = ov5693_power_on, + .power_off = ov5693_power_off, + .write_reg = ov5693_write_reg, + .read_reg = ov5693_read_reg, + .parse_dt = ov5693_parse_dt, + .power_get = ov5693_power_get, + .power_put = ov5693_power_put, + .set_mode = ov5693_set_mode, + .start_streaming = ov5693_start_streaming, + .stop_streaming = ov5693_stop_streaming, +}; + +static int ov5693_debugfs_streaming_show(void *data, u64 *val) +{ + struct ov5693 *priv = data; + + mutex_lock(&priv->streaming_lock); + *val = priv->streaming; + mutex_unlock(&priv->streaming_lock); + + return 0; +} + +static int ov5693_debugfs_streaming_write(void *data, u64 val) +{ + int err = 0; + struct ov5693 *priv = data; + struct i2c_client *client = priv->i2c_client; + bool enable = (val != 0); + int mode_index = enable ? + (OV5693_MODE_START_STREAM) : (OV5693_MODE_STOP_STREAM); + + dev_info(&client->dev, "%s: %s sensor\n", + __func__, (enable ? "enabling" : "disabling")); + + mutex_lock(&priv->streaming_lock); + + err = ov5693_write_table(priv, mode_table[mode_index]); + if (err) { + dev_err(&client->dev, "%s: error setting sensor streaming\n", + __func__); + goto done; + } + + priv->streaming = enable; + +done: + mutex_unlock(&priv->streaming_lock); + + return err; +} + +DEFINE_SIMPLE_ATTRIBUTE(ov5693_debugfs_streaming_fops, + ov5693_debugfs_streaming_show, + ov5693_debugfs_streaming_write, + "%lld\n"); + +static void ov5693_debugfs_remove(struct ov5693 *priv); + +static int ov5693_debugfs_create(struct ov5693 *priv) +{ + int err = 0; + struct i2c_client *client = priv->i2c_client; + const char *devnode; + char debugfs_dir[16]; + + err = of_property_read_string(client->dev.of_node, "devnode", &devnode); + if (err) { + dev_err(&client->dev, "devnode not in DT\n"); + return err; + } + err = snprintf(debugfs_dir, sizeof(debugfs_dir), "camera-%s", devnode); + if (err < 0) + return -EINVAL; + + priv->debugfs_dir = debugfs_create_dir(debugfs_dir, NULL); + if (priv->debugfs_dir == NULL) + return -ENOMEM; + + if (!debugfs_create_file("streaming", 0644, priv->debugfs_dir, priv, + &ov5693_debugfs_streaming_fops)) + goto error; + + return 0; + +error: + ov5693_debugfs_remove(priv); + + return -ENOMEM; +} + +static struct tegracam_ctrl_ops ov5693_ctrl_ops = { + .numctrls = ARRAY_SIZE(ctrl_cid_list), + .ctrl_cid_list = ctrl_cid_list, + .string_ctrl_size = {OV5693_EEPROM_STR_SIZE, + OV5693_FUSE_ID_STR_SIZE, + OV5693_OTP_STR_SIZE}, + .set_gain = ov5693_set_gain, + .set_exposure = ov5693_set_exposure, + .set_exposure_short = ov5693_set_exposure_short, + .set_frame_rate = ov5693_set_frame_rate, + .set_group_hold = ov5693_set_group_hold, + .fill_string_ctrl = ov5693_fill_string_ctrl, +}; + +static int ov5693_board_setup(struct ov5693 *priv) +{ + struct camera_common_data *s_data = priv->s_data; + struct device *dev = s_data->dev; + bool eeprom_ctrl = 0; + int err = 0; + + dev_dbg(dev, "%s++\n", __func__); + + /* eeprom interface */ + err = ov5693_eeprom_device_init(priv); + if (err && s_data->pdata->has_eeprom) + dev_err(dev, + "Failed to allocate eeprom reg map: %d\n", err); + eeprom_ctrl = !err; + + err = camera_common_mclk_enable(s_data); + if (err) { + dev_err(dev, + "Error %d turning on mclk\n", err); + return err; + } + + err = ov5693_power_on(s_data); + if (err) { + dev_err(dev, + "Error %d during power on sensor\n", err); + return err; + } + + if (eeprom_ctrl) { + err = ov5693_read_eeprom(priv); + if (err) { + dev_err(dev, + "Error %d reading eeprom\n", err); + goto error; + } + } + + err = ov5693_otp_setup(priv); + if (err) { + dev_err(dev, + "Error %d reading otp data\n", err); + goto error; + } + + err = ov5693_fuse_id_setup(priv); + if (err) { + dev_err(dev, + "Error %d reading fuse id data\n", err); + goto error; + } + +error: + ov5693_power_off(s_data); + camera_common_mclk_disable(s_data); + return err; +} + +static void ov5693_debugfs_remove(struct ov5693 *priv) +{ + debugfs_remove_recursive(priv->debugfs_dir); + priv->debugfs_dir = NULL; +} + +static int ov5693_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +{ + struct i2c_client *client = v4l2_get_subdevdata(sd); + + dev_dbg(&client->dev, "%s:\n", __func__); + return 0; +} + +static const struct v4l2_subdev_internal_ops ov5693_subdev_internal_ops = { + .open = ov5693_open, +}; + +static int ov5693_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct device *dev = &client->dev; + struct device_node *node = client->dev.of_node; + struct tegracam_device *tc_dev; + struct ov5693 *priv; + int err; + const struct of_device_id *match; + int i; + + dev_info(dev, "probing v4l2 sensor.\n"); + + match = of_match_device(ov5693_of_match, dev); + if (!match) { + dev_err(dev, "No device match found\n"); + return -ENODEV; + } + + if (!IS_ENABLED(CONFIG_OF) || !node) + return -EINVAL; + + priv = devm_kzalloc(dev, + sizeof(struct ov5693), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + tc_dev = devm_kzalloc(dev, + sizeof(struct tegracam_device), GFP_KERNEL); + if (!tc_dev) + return -ENOMEM; + + priv->i2c_client = tc_dev->client = client; + tc_dev->dev = dev; + strncpy(tc_dev->name, "ov5693", sizeof(tc_dev->name)); + tc_dev->dev_regmap_config = &ov5693_regmap_config; + tc_dev->sensor_ops = &ov5693_common_ops; + tc_dev->v4l2sd_internal_ops = &ov5693_subdev_internal_ops; + tc_dev->tcctrl_ops = &ov5693_ctrl_ops; + + err = tegracam_device_register(tc_dev); + if (err) { + dev_err(dev, "tegra camera driver registration failed\n"); + return err; + } + + priv->tc_dev = tc_dev; + priv->s_data = tc_dev->s_data; + priv->subdev = &tc_dev->s_data->subdev; + tegracam_set_privdata(tc_dev, (void *)priv); + mutex_init(&priv->streaming_lock); + + err = ov5693_board_setup(priv); + if (err) { + tegracam_device_unregister(tc_dev); + dev_err(dev, "board setup failed\n"); + goto fail; + } + + err = tegracam_v4l2subdev_register(tc_dev, true); + if (err) { + dev_err(dev, "tegra camera subdev registration failed\n"); + goto fail; + } + + err = ov5693_debugfs_create(priv); + if (err) { + dev_err(dev, "error creating debugfs interface"); + ov5693_debugfs_remove(priv); + goto fail; + } + + dev_dbg(dev, "Detected OV5693 sensor\n"); + + return 0; + +fail: + for (i = 0; i < OV5693_EEPROM_NUM_BLOCKS; i++) { + if (priv->eeprom[i].i2c_client != NULL) { + i2c_unregister_device(priv->eeprom[i].i2c_client); + priv->eeprom[i].i2c_client = NULL; + } + } + return err; +} + +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) +static int +ov5693_remove(struct i2c_client *client) +#else +static void +ov5693_remove(struct i2c_client *client) +#endif +{ + struct camera_common_data *s_data = to_camera_common_data(&client->dev); + struct ov5693 *priv = (struct ov5693 *)s_data->priv; + + ov5693_debugfs_remove(priv); + + tegracam_v4l2subdev_unregister(priv->tc_dev); + ov5693_power_put(priv->tc_dev); + tegracam_device_unregister(priv->tc_dev); + ov5693_eeprom_device_release(priv); + + mutex_destroy(&priv->streaming_lock); +#if (KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE) + return 0; +#endif +} + +static const struct i2c_device_id ov5693_id[] = { + { "ov5693", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, ov5693_id); + +static struct i2c_driver ov5693_i2c_driver = { + .driver = { + .name = "ov5693", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ov5693_of_match), + }, + .probe = ov5693_probe, + .remove = ov5693_remove, + .id_table = ov5693_id, +}; +module_i2c_driver(ov5693_i2c_driver); + +MODULE_DESCRIPTION("Media Controller driver for OmniVision OV5693"); +MODULE_AUTHOR("NVIDIA Corporation"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/i2c/ov5693_mode_tbls.h b/drivers/media/i2c/ov5693_mode_tbls.h new file mode 100644 index 00000000..1604b6e3 --- /dev/null +++ b/drivers/media/i2c/ov5693_mode_tbls.h @@ -0,0 +1,2390 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * ov5693_mode_tbls.h - ov5693 sensor mode tables + * + */ + +#ifndef __OV5693_TABLES__ +#define __OV5693_TABLES__ + +#include + +#define OV5693_TABLE_WAIT_MS 0 +#define OV5693_TABLE_END 1 +#define OV5693_MAX_RETRIES 3 +#define OV5693_WAIT_MS 10 + +#define ENABLE_EXTRA_MODES 0 + +#define ov5693_reg struct reg_8 + +static const ov5693_reg ov5693_start[] = { + {0x0100, 0x01}, /* mode select streaming on */ + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg ov5693_stop[] = { + {0x0100, 0x00}, /* mode select streaming on */ + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg tp_colorbars[] = { + {0x0600, 0x00}, + {0x0601, 0x02}, + + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {OV5693_TABLE_END, 0x00} +}; + +static const ov5693_reg mode_2592x1944[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3090, 0x02}, + {0x3091, 0x0e}, + {0x3092, 0x00}, + {0x3093, 0x00}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x18}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x02}, + {0x3802, 0x00}, + {0x3803, 0x02}, + {0x3804, 0x0a}, + {0x3805, 0x41}, + {0x3806, 0x07}, + {0x3807, 0xa5}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3d00, 0x00}, + {0x3d01, 0x00}, + {0x3d02, 0x00}, + {0x3d03, 0x00}, + {0x3d04, 0x00}, + {0x3d05, 0x00}, + {0x3d06, 0x00}, + {0x3d07, 0x00}, + {0x3d08, 0x00}, + {0x3d09, 0x00}, + {0x3d0a, 0x00}, + {0x3d0b, 0x00}, + {0x3d0c, 0x00}, + {0x3d0d, 0x00}, + {0x3d0e, 0x00}, + {0x3d0f, 0x00}, + {0x3d80, 0x00}, + {0x3d81, 0x00}, + {0x3d84, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_2592x1458[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3400, 0x04}, + {0x3401, 0x00}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x04}, + {0x3405, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3600, 0xbc}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x44}, + {0x3621, 0xb5}, + {0x3622, 0x0c}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf4}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xb1}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x05}, + {0x380b, 0xb2}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0xfc}, + {0x5781, 0x13}, + {0x5782, 0x03}, + {0x5786, 0x20}, + {0x5787, 0x40}, + {0x5788, 0x08}, + {0x5789, 0x08}, + {0x578a, 0x02}, + {0x578b, 0x01}, + {0x578c, 0x01}, + {0x578d, 0x0c}, + {0x578e, 0x02}, + {0x578f, 0x01}, + {0x5790, 0x01}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1920x1080[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/*, 0xIncluding, 0xsw, 0xreset, 0x*/ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf8}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xab}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x80}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1280x720_120fps[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x2e}, + {0x3502, 0x80}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe6}, + {0x3709, 0xc7}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0xf4}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x06}, + {0x3807, 0xab}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x06}, + {0x380d, 0xd8}, + {0x380e, 0x02}, + {0x380f, 0xf8}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x31}, + {0x3815, 0x31}, + {0x3820, 0x04}, + {0x3821, 0x1f}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x00}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_2592x1944_HDR_24fps[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x02}, + {0x3099, 0x16}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30b2, 0x00}, + {0x30b3, 0x6e}, + {0x30b4, 0x03}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x80}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x05}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xa8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x0c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x02}, + {0x3802, 0x00}, + {0x3803, 0x06}, + {0x3804, 0x0a}, + {0x3805, 0x41}, + {0x3806, 0x07}, + {0x3807, 0xa1}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0e}, + {0x380d, 0x70}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1920x1080_HDR_30fps[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x72}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x01}, + {0x3801, 0x70}, + {0x3802, 0x01}, + {0x3803, 0xbc}, + {0x3804, 0x09}, + {0x3805, 0x0f}, + {0x3806, 0x05}, + {0x3807, 0xff}, + {0x3808, 0x07}, + {0x3809, 0x80}, + {0x380a, 0x04}, + {0x380b, 0x38}, + {0x380c, 0x0b}, + {0x380d, 0x40}, + {0x380e, 0x07}, + {0x380f, 0x3a}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_1280x720_HDR_60fps[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x02}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x68}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x39}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x01}, + {0x3508, 0x80}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x40}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x54}, + {0x3621, 0xc7}, + {0x3622, 0x0f}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x02}, + {0x3801, 0xa8}, + {0x3802, 0x02}, + {0x3803, 0x68}, + {0x3804, 0x07}, + {0x3805, 0xb7}, + {0x3806, 0x05}, + {0x3807, 0x3b}, + {0x3808, 0x05}, + {0x3809, 0x00}, + {0x380a, 0x02}, + {0x380b, 0xd0}, + {0x380c, 0x0b}, + {0x380d, 0x40}, + {0x380e, 0x03}, + {0x380f, 0x9e}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x9e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x09}, + {0x3a05, 0xa9}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4800, 0x20}, /* dis-continuous */ + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x32}, + {0x4831, 0x6a}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0x1c}, + {0x5786, 0x20}, + {0x5787, 0x10}, + {0x5788, 0x18}, + {0x578a, 0x04}, + {0x578b, 0x02}, + {0x578c, 0x02}, + {0x578e, 0x06}, + {0x578f, 0x02}, + {0x5790, 0x02}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_2592x1944_one_lane_15fps[] = { + {0x0100, 0x00},/* Including sw reset */ + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x11}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x28}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x05}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x64}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x01}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3400, 0x04}, + {0x3401, 0x00}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x04}, + {0x3405, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x7b}, + {0x3502, 0x00}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0x20}, + {0x3600, 0xbc}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x44}, + {0x3621, 0xb5}, + {0x3622, 0x0c}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xe2}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x00}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0xa3}, + {0x3808, 0x0a}, + {0x3809, 0x20}, + {0x380a, 0x07}, + {0x380b, 0x98}, + {0x380c, 0x0a}, + {0x380d, 0x80}, + {0x380e, 0x07}, + {0x380f, 0xc0}, + {0x3810, 0x00}, + {0x3811, 0x02}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x11}, + {0x3815, 0x11}, + {0x3820, 0x00}, + {0x3821, 0x1e}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x2c}, + {0x4831, 0x64}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x0a}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0xfc}, + {0x5781, 0x13}, + {0x5782, 0x03}, + {0x5786, 0x20}, + {0x5787, 0x40}, + {0x5788, 0x08}, + {0x5789, 0x08}, + {0x578a, 0x02}, + {0x578b, 0x01}, + {0x578c, 0x01}, + {0x578d, 0x0c}, + {0x578e, 0x02}, + {0x578f, 0x01}, + {0x5790, 0x01}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {0x0100, 0x01}, + {0x3810, 0x00}, + {0x3811, 0x10}, + {0x3812, 0x00}, + {0x3813, 0x06}, + {OV5693_TABLE_END, 0x0000} +}; + +static const ov5693_reg mode_640x480[] = { + {OV5693_TABLE_WAIT_MS, OV5693_WAIT_MS}, + {0x0103, 0x01}, + {0x3001, 0x0a}, + {0x3002, 0x80}, + {0x3006, 0x00}, + {0x3011, 0x21}, + {0x3012, 0x09}, + {0x3013, 0x10}, + {0x3014, 0x00}, + {0x3015, 0x08}, + {0x3016, 0xf0}, + {0x3017, 0xf0}, + {0x3018, 0xf0}, + {0x301b, 0xb4}, + {0x301d, 0x02}, + {0x3021, 0x00}, + {0x3022, 0x01}, + {0x3028, 0x44}, + {0x3098, 0x03}, + {0x3099, 0x1e}, + {0x309a, 0x0b}, + {0x309b, 0x01}, + {0x309c, 0x00}, + {0x30a0, 0xd2}, + {0x30a2, 0x01}, + {0x30b2, 0x00}, + {0x30b3, 0x64}, + {0x30b4, 0x03}, + {0x30b5, 0x04}, + {0x30b6, 0x04}, + {0x3104, 0x21}, + {0x3106, 0x00}, + {0x3400, 0x04}, + {0x3401, 0x00}, + {0x3402, 0x04}, + {0x3403, 0x00}, + {0x3404, 0x04}, + {0x3405, 0x00}, + {0x3406, 0x01}, + {0x3500, 0x00}, + {0x3501, 0x1f}, + {0x3502, 0x10}, + {0x3503, 0x07}, + {0x3504, 0x00}, + {0x3505, 0x00}, + {0x3506, 0x00}, + {0x3507, 0x02}, + {0x3508, 0x00}, + {0x3509, 0x10}, + {0x350a, 0x00}, + {0x350b, 0xF8}, + {0x3600, 0xbc}, + {0x3601, 0x0a}, + {0x3602, 0x38}, + {0x3612, 0x80}, + {0x3620, 0x44}, + {0x3621, 0xb5}, + {0x3622, 0x0c}, + {0x3625, 0x10}, + {0x3630, 0x55}, + {0x3631, 0xf4}, + {0x3632, 0x00}, + {0x3633, 0x34}, + {0x3634, 0x02}, + {0x364d, 0x0d}, + {0x364f, 0xdd}, + {0x3660, 0x04}, + {0x3662, 0x10}, + {0x3663, 0xf1}, + {0x3665, 0x00}, + {0x3666, 0x20}, + {0x3667, 0x00}, + {0x366a, 0x80}, + {0x3680, 0xe0}, + {0x3681, 0x00}, + {0x3700, 0x42}, + {0x3701, 0x14}, + {0x3702, 0xa0}, + {0x3703, 0xd8}, + {0x3704, 0x78}, + {0x3705, 0x02}, + {0x3708, 0xeb}, + {0x3709, 0xc3}, + {0x370a, 0x00}, + {0x370b, 0x20}, + {0x370c, 0x0c}, + {0x370d, 0x11}, + {0x370e, 0x00}, + {0x370f, 0x40}, + {0x3710, 0x00}, + {0x371a, 0x1c}, + {0x371b, 0x05}, + {0x371c, 0x01}, + {0x371e, 0xa1}, + {0x371f, 0x0c}, + {0x3721, 0x00}, + {0x3724, 0x10}, + {0x3726, 0x00}, + {0x372a, 0x01}, + {0x3730, 0x10}, + {0x3738, 0x22}, + {0x3739, 0xe5}, + {0x373a, 0x50}, + {0x373b, 0x02}, + {0x373c, 0x41}, + {0x373f, 0x02}, + {0x3740, 0x42}, + {0x3741, 0x02}, + {0x3742, 0x18}, + {0x3743, 0x01}, + {0x3744, 0x02}, + {0x3747, 0x10}, + {0x374c, 0x04}, + {0x3751, 0xf0}, + {0x3752, 0x00}, + {0x3753, 0x00}, + {0x3754, 0xc0}, + {0x3755, 0x00}, + {0x3756, 0x1a}, + {0x3758, 0x00}, + {0x3759, 0x0f}, + {0x376b, 0x44}, + {0x375c, 0x04}, + {0x3774, 0x10}, + {0x3776, 0x00}, + {0x377f, 0x08}, + {0x3780, 0x22}, + {0x3781, 0x0c}, + {0x3784, 0x2c}, + {0x3785, 0x1e}, + {0x378f, 0xf5}, + {0x3791, 0xb0}, + {0x3795, 0x00}, + {0x3796, 0x64}, + {0x3797, 0x11}, + {0x3798, 0x30}, + {0x3799, 0x41}, + {0x379a, 0x07}, + {0x379b, 0xb0}, + {0x379c, 0x0c}, + {0x37c5, 0x00}, + {0x37c6, 0x00}, + {0x37c7, 0x00}, + {0x37c9, 0x00}, + {0x37ca, 0x00}, + {0x37cb, 0x00}, + {0x37de, 0x00}, + {0x37df, 0x00}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x04}, + {0x3804, 0x0a}, + {0x3805, 0x3f}, + {0x3806, 0x07}, + {0x3807, 0x9b}, + {0x3808, 0x02}, + {0x3809, 0x80}, + {0x380a, 0x01}, + {0x380b, 0xe0}, + {0x380c, 0x0a}, + {0x380d, 0x20}, + {0x380e, 0x02}, + {0x380f, 0x02}, + {0x3810, 0x00}, + {0x3811, 0x0e}, + {0x3812, 0x00}, + {0x3813, 0x02}, + {0x3814, 0x71}, + {0x3815, 0x71}, + {0x3820, 0x01}, + {0x3821, 0x1f}, + {0x3823, 0x00}, + {0x3824, 0x00}, + {0x3825, 0x00}, + {0x3826, 0x00}, + {0x3827, 0x00}, + {0x382a, 0x04}, + {0x3a04, 0x06}, + {0x3a05, 0x14}, + {0x3a06, 0x00}, + {0x3a07, 0xfe}, + {0x3b00, 0x00}, + {0x3b02, 0x00}, + {0x3b03, 0x00}, + {0x3b04, 0x00}, + {0x3b05, 0x00}, + {0x3e07, 0x20}, + {0x4000, 0x08}, + {0x4001, 0x04}, + {0x4002, 0x45}, + {0x4004, 0x08}, + {0x4005, 0x18}, + {0x4006, 0x20}, + {0x4008, 0x24}, + {0x4009, 0x10}, + {0x400c, 0x00}, + {0x400d, 0x00}, + {0x4058, 0x00}, + {0x404e, 0x37}, + {0x404f, 0x8f}, + {0x4058, 0x00}, + {0x4101, 0xb2}, + {0x4303, 0x00}, + {0x4304, 0x08}, + {0x4307, 0x30}, + {0x4311, 0x04}, + {0x4315, 0x01}, + {0x4511, 0x05}, + {0x4512, 0x01}, + {0x4806, 0x00}, + {0x4816, 0x52}, + {0x481f, 0x30}, + {0x4826, 0x2c}, + {0x4831, 0x64}, + {0x4d00, 0x04}, + {0x4d01, 0x71}, + {0x4d02, 0xfd}, + {0x4d03, 0xf5}, + {0x4d04, 0x0c}, + {0x4d05, 0xcc}, + {0x4837, 0x28}, + {0x5000, 0x06}, + {0x5001, 0x01}, + {0x5002, 0x00}, + {0x5003, 0x20}, + {0x5046, 0x0a}, + {0x5013, 0x00}, + {0x5046, 0x0a}, + {0x5780, 0xfc}, + {0x5781, 0x13}, + {0x5782, 0x03}, + {0x5786, 0x20}, + {0x5787, 0x40}, + {0x5788, 0x08}, + {0x5789, 0x08}, + {0x578a, 0x02}, + {0x578b, 0x01}, + {0x578c, 0x01}, + {0x578d, 0x0c}, + {0x578e, 0x02}, + {0x578f, 0x01}, + {0x5790, 0x01}, + {0x5791, 0xff}, + {0x5842, 0x01}, + {0x5843, 0x2b}, + {0x5844, 0x01}, + {0x5845, 0x92}, + {0x5846, 0x01}, + {0x5847, 0x8f}, + {0x5848, 0x01}, + {0x5849, 0x0c}, + {0x5e00, 0x00}, + {0x5e10, 0x0c}, + {OV5693_TABLE_END, 0x0000}, +}; + +enum { + OV5693_MODE_2592X1944, + OV5693_MODE_2592X1458, + OV5693_MODE_1280X720_120FPS, + OV5693_MODE_640X480, + OV5693_MODE_1920X1080, + OV5693_MODE_2592X1944_HDR, + OV5693_MODE_1920X1080_HDR, + OV5693_MODE_2592x1944_15FPS, + + OV5693_MODE_START_STREAM, + OV5693_MODE_STOP_STREAM, + OV5693_MODE_TEST_PATTERN +}; + +static const ov5693_reg *mode_table[] = { + [OV5693_MODE_2592X1944] = mode_2592x1944, + [OV5693_MODE_2592X1458] = mode_2592x1458, + [OV5693_MODE_1280X720_120FPS] = mode_1280x720_120fps, + [OV5693_MODE_640X480] = mode_640x480, + [OV5693_MODE_1920X1080] = mode_1920x1080, + [OV5693_MODE_2592X1944_HDR] = mode_2592x1944_HDR_24fps, + [OV5693_MODE_1920X1080_HDR] = mode_1920x1080_HDR_30fps, + [OV5693_MODE_2592x1944_15FPS] = mode_2592x1944_one_lane_15fps, + + [OV5693_MODE_START_STREAM] = ov5693_start, + [OV5693_MODE_STOP_STREAM] = ov5693_stop, + [OV5693_MODE_TEST_PATTERN] = tp_colorbars, +}; + +static const int ov5693_15fps[] = { + 15, +}; + +static const int ov5693_24fps[] = { + 24, +}; + +static const int ov5693_30fps[] = { + 30, +}; + +static const int ov5693_120fps[] = { + 120, +}; + +static const struct camera_common_frmfmt ov5693_frmfmt[] = { + {{2592, 1944}, ov5693_30fps, 1, 0, OV5693_MODE_2592X1944}, + {{2592, 1458}, ov5693_30fps, 1, 0, OV5693_MODE_2592X1458}, + {{1280, 720}, ov5693_120fps, 1, 0, OV5693_MODE_1280X720_120FPS}, +#if ENABLE_EXTRA_MODES + {{640, 480}, ov5693_30fps, 1, 0, OV5693_MODE_640X480}, + {{1920, 1080}, ov5693_30fps, 1, 0, OV5693_MODE_1920X1080}, + {{2592, 1944}, ov5693_24fps, 1, 1, OV5693_MODE_2592X1944_HDR}, + {{1920, 1080}, ov5693_30fps, 1, 1, OV5693_MODE_1920X1080_HDR}, + {{2592, 1944}, ov5693_15fps, 1, 1, OV5693_MODE_2592x1944_15FPS}, +#endif +}; +#endif /* __OV5693_TABLES__ */ + diff --git a/include/media/nvc.h b/include/media/nvc.h new file mode 100644 index 00000000..d9bac299 --- /dev/null +++ b/include/media/nvc.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + */ + +#ifndef __NVC_H__ +#define __NVC_H__ + +#include +#include + +#define MAKE_CONSTUSER_PTR(p) ((const void __user *)((unsigned long)(p))) +#define MAKE_USER_PTR(p) ((void __user *)((unsigned long)(p))) + +/* The NVC_CFG_ defines are for the .cfg entry in the + * platform data structure. + */ +/* Device not registered if not found */ +#define NVC_CFG_NODEV (1 << 0) +/* Don't return errors */ +#define NVC_CFG_NOERR (1 << 1) +/* Always go to _PWR_STDBY instead of _PWR_OFF */ +#define NVC_CFG_OFF2STDBY (1 << 2) +/* Init device at sys boot */ +#define NVC_CFG_BOOT_INIT (1 << 3) +/* Sync mode uses an I2C MUX to send at same time */ +#define NVC_CFG_SYNC_I2C_MUX (1 << 4) + +struct nvc_regulator_init { + unsigned int vreg_num; + const char *vreg_name; +}; + +struct nvc_regulator { + bool vreg_flag; + struct regulator *vreg; + const char *vreg_name; +}; + +/* The GPIO mechanism uses the _gpio_type in the device's header file as a key + * to define all the possible GPIO's the device will need. The key is used to + * combine the GPIO's defined in the platform board file using the + * nvc_gpio_pdata structure with the nvc_gpio structure in the nvc kernel + * driver. + */ +struct nvc_gpio_pdata { + /* use a _gpio_type enum from the device's header file */ + unsigned int gpio_type; + /* the GPIO system number */ + unsigned int gpio; + /* init_en is typically set to true for all GPIO's used by the driver. + * However, some GPIO's are used by multiple drivers (CSI MUX, reset, + * etc.). In this case, this is set true for only one of the drivers + * that uses the GPIO and false for the others. If the platform board + * file initializes the GPIO, then this is false for all of the drivers + * using the GPIO. + */ + bool init_en; + /* this defines the assert level for the general purpose GPIO's + * (_GPIO_TYPE_GPx, etc.). The _GPIO_TYPE_GPx can be used for a GPIO + * that the driver doesn't know about but is needed in order for the + * device to work (CSI select, regulator, etc.). The driver will + * blindly assert the GPIO when the device is operational and deassert + * when the device is turned off. + */ + bool active_high; +}; + +struct nvc_gpio_init { + /* key to match in nvc_gpio_pdata */ + unsigned int gpio_type; + /* same as in gpio.h */ + unsigned long flags; + /* same as in gpio.h */ + const char *label; + /* used instead of nvc_gpio_pdata.active_high if use_flags true */ + bool active_high; + /* false if nvc_gpio_pdata.active_high used else flags is used */ + bool use_flags; +}; + +struct nvc_gpio { + unsigned int gpio; /* system GPIO number */ + bool own; /* gets set if driver initializes */ + bool active_high; /* used for GP GPIOs */ + bool valid; /* set if struct data is valid */ + bool flag; /* scratch flag for driver implementation */ +}; + +#endif /* __NVC_H__ */ diff --git a/include/media/ov5693.h b/include/media/ov5693.h new file mode 100644 index 00000000..a2e7ad44 --- /dev/null +++ b/include/media/ov5693.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2013-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + */ + +#ifndef __OV5693_H__ +#define __OV5693_H__ + +#include +#include +#include + +#define OV5693_INVALID_COARSE_TIME -1 + +#define OV5693_EEPROM_ADDRESS 0x54 +#define OV5693_EEPROM_SIZE 1024 +#define OV5693_EEPROM_STR_SIZE (OV5693_EEPROM_SIZE * 2) +#define OV5693_EEPROM_BLOCK_SIZE (1 << 8) +#define OV5693_EEPROM_NUM_BLOCKS \ + (OV5693_EEPROM_SIZE / OV5693_EEPROM_BLOCK_SIZE) + +#define OV5693_OTP_LOAD_CTRL_ADDR 0x3D81 +#define OV5693_OTP_BANK_SELECT_ADDR 0x3D84 +#define OV5693_OTP_BANK_START_ADDR 0x3D00 +#define OV5693_OTP_BANK_END_ADDR 0x3D0F +#define OV5693_OTP_NUM_BANKS (32) +#define OV5693_OTP_BANK_SIZE \ + (OV5693_OTP_BANK_END_ADDR - OV5693_OTP_BANK_START_ADDR + 1) +#define OV5693_OTP_SIZE \ + (OV5693_OTP_BANK_SIZE * OV5693_OTP_NUM_BANKS) +#define OV5693_OTP_STR_SIZE (OV5693_OTP_SIZE * 2) + +/* See notes in the nvc.h file on the GPIO usage */ +enum ov5693_gpio_type { + OV5693_GPIO_TYPE_PWRDN = 0, + OV5693_GPIO_TYPE_RESET, +}; + +struct ov5693_eeprom_data { + struct i2c_client *i2c_client; + struct i2c_adapter *adap; + struct i2c_board_info brd; + struct regmap *regmap; +}; + +struct ov5693_power_rail { + struct regulator *dvdd; + struct regulator *avdd; + struct regulator *dovdd; +}; + +struct ov5693_regulators { + const char *avdd; + const char *dvdd; + const char *dovdd; +}; + +#endif /* __OV5693_H__ */ diff --git a/include/trace/events/ov5693.h b/include/trace/events/ov5693.h new file mode 100644 index 00000000..4adf414d --- /dev/null +++ b/include/trace/events/ov5693.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * ov5693.h + * + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ov5693 + +#if !defined(_TRACE_OV5693_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_OV5693_H + +#include + +TRACE_EVENT(ov5693_s_stream, + TP_PROTO(const char *name, int enable, int mode), + TP_ARGS(name, enable, mode), + TP_STRUCT__entry( + __string(name, name) + __field(int, enable) + __field(int, mode) + ), + TP_fast_assign( + __assign_str(name, name); + __entry->enable = enable; + __entry->mode = mode; + ), + TP_printk("%s: on %d mode %d", __get_str(name), + __entry->enable, __entry->mode) +); + + +#endif + +/* This part must be outside protection */ +#include diff --git a/include/uapi/media/nvc.h b/include/uapi/media/nvc.h new file mode 100644 index 00000000..4157dcba --- /dev/null +++ b/include/uapi/media/nvc.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2012-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ + +#ifndef __UAPI_NVC_H__ +#define __UAPI_NVC_H__ + +#include +#include + +#define NVC_INT2FLOAT_DIVISOR_1K 1000 +#define NVC_INT2FLOAT_DIVISOR_1M 1000000 +#define NVC_INT2FLOAT_DIVISOR 1000 + +struct nvc_param_32 { + __u32 param; + __u32 sizeofvalue; + __u32 variant; + __u32 p_value; +} __packed; + +struct nvc_param { + __u32 param; + __u32 sizeofvalue; + __u32 variant; + unsigned long p_value; +} __packed; + +enum nvc_params { + NVC_PARAM_EXPOSURE = 0, + NVC_PARAM_GAIN, + NVC_PARAM_FRAMERATE, + NVC_PARAM_MAX_FRAMERATE, + NVC_PARAM_INPUT_CLOCK, + NVC_PARAM_LOCUS, + NVC_PARAM_FLASH_CAPS, + NVC_PARAM_FLASH_LEVEL, + NVC_PARAM_FLASH_PIN_STATE, + NVC_PARAM_TORCH_CAPS, + NVC_PARAM_TORCH_LEVEL, + NVC_PARAM_FOCAL_LEN, + NVC_PARAM_MAX_APERTURE, + NVC_PARAM_FNUMBER, + NVC_PARAM_EXPOSURE_LIMITS, + NVC_PARAM_GAIN_LIMITS, + NVC_PARAM_FRAMERATE_LIMITS, + NVC_PARAM_FRAME_RATES, + NVC_PARAM_CLOCK_LIMITS, + NVC_PARAM_EXP_LATCH_TIME, + NVC_PARAM_REGION_USED, + NVC_PARAM_CALIBRATION_DATA, + NVC_PARAM_CALIBRATION_OVERRIDES, + NVC_PARAM_SELF_TEST, + NVC_PARAM_STS, + NVC_PARAM_TESTMODE, + NVC_PARAM_EXPECTED_VALUES, + NVC_PARAM_RESET, + NVC_PARAM_OPTIMIZE_RES, + NVC_PARAM_DETECT_COLOR_TEMP, + NVC_PARAM_LINES_PER_SEC, + NVC_PARAM_CAPS, + NVC_PARAM_CUSTOM_BLOCK_INFO, + NVC_PARAM_STEREO_CAP, + NVC_PARAM_FOCUS_STEREO, + NVC_PARAM_STEREO, + NVC_PARAM_INHERENT_GAIN, + NVC_PARAM_VIEW_ANGLE_H, + NVC_PARAM_VIEW_ANGLE_V, + NVC_PARAM_ISP_SETTING, + NVC_PARAM_OPERATION_MODE, + NVC_PARAM_SUPPORT_ISP, + NVC_PARAM_AWB_LOCK, + NVC_PARAM_AE_LOCK, + NVC_PARAM_RES_CHANGE_WAIT_TIME, + NVC_PARAM_FACTORY_CALIBRATION_DATA, + NVC_PARAM_DEV_ID, + NVC_PARAM_GROUP_HOLD, + NVC_PARAM_SET_SENSOR_FLASH_MODE, + NVC_PARAM_TORCH_QUERY, + NVC_PARAM_FLASH_EXT_CAPS, + NVC_PARAM_TORCH_EXT_CAPS, + NVC_PARAM_BEGIN_VENDOR_EXTENSIONS = 0x10000000, + NVC_PARAM_CALIBRATION_STATUS, + NVC_PARAM_TEST_PATTERN, + NVC_PARAM_MODULE_INFO, + NVC_PARAM_FLASH_MAX_POWER, + NVC_PARAM_DIRECTION, + NVC_PARAM_SENSOR_TYPE, + NVC_PARAM_DLI_CHECK, + NVC_PARAM_PARALLEL_DLI_CHECK, + NVC_PARAM_BRACKET_CAPS, + NVC_PARAM_NUM, + NVC_PARAM_I2C, + NVC_PARAM_FEATURES, + NVC_PARAM_FORCE32 = 0x7FFFFFFF +}; + +/* sync off */ +#define NVC_SYNC_OFF 0 +/* use only this device (the one receiving the call) */ +#define NVC_SYNC_MASTER 1 +/* use only the synced device (the "other" device) */ +#define NVC_SYNC_SLAVE 2 +/* use both synced devices at the same time */ +#define NVC_SYNC_STEREO 3 + +#define NVC_RESET_HARD 0 +#define NVC_RESET_SOFT 1 + +struct nvc_param_isp { + int attr; + void *p_data; + __u32 data_size; +} __packed; + +struct nvc_isp_focus_param { + __s32 min_pos; + __s32 max_pos; + __s32 hyperfocal; + __s32 macro; + __s32 powersave; +} __packed; + +struct nvc_isp_focus_pos { + __u32 is_auto; + __s32 value; +} __packed; + +struct nvc_isp_focus_region { + __u32 num_region; + __s32 value; +} __packed; + +enum nvc_params_isp { + NVC_PARAM_ISP_FOCUS_CAF = 16389, + NVC_PARAM_ISP_FOCUS_CAF_PAUSE, + NVC_PARAM_ISP_FOCUS_CAF_STS, + NVC_PARAM_ISP_FOCUS_POS = 16407, + NVC_PARAM_ISP_FOCUS_RANGE, + NVC_PARAM_ISP_FOCUS_AF_RGN = 16413, + NVC_PARAM_ISP_FOCUS_AF_RGN_MASK, + NVC_PARAM_ISP_FOCUS_AF_RGN_STS, + NVC_PARAM_ISP_FOCUS_CTRL = 16424, + NVC_PARAM_ISP_FOCUS_TRGR, + NVC_PARAM_ISP_FOCUS_STS, +}; + +#define NVC_PARAM_ISP_FOCUS_STS_BUSY 0 +#define NVC_PARAM_ISP_FOCUS_STS_LOCKD 1 +#define NVC_PARAM_ISP_FOCUS_STS_FAILD 2 +#define NVC_PARAM_ISP_FOCUS_STS_ERR 3 + +#define NVC_PARAM_ISP_FOCUS_CTRL_ON 0 +#define NVC_PARAM_ISP_FOCUS_CTRL_OFF 1 +#define NVC_PARAM_ISP_FOCUS_CTRL_AUTO 2 +#define NVC_PARAM_ISP_FOCUS_CTRL_ALOCK 3 + +#define NVC_PARAM_ISP_FOCUS_CAF_CONVRG 1 +#define NVC_PARAM_ISP_FOCUS_CAF_SEARCH 2 + +#define NVC_PARAM_ISP_FOCUS_POS_INF 0 + + +#define NVC_IOCTL_PWR_WR _IOW('o', 102, int) +#define NVC_IOCTL_PWR_RD _IOW('o', 103, int) +#define NVC_IOCTL_PARAM_WR _IOW('o', 104, struct nvc_param) +#define NVC_IOCTL32_PARAM_WR _IOW('o', 104, struct nvc_param_32) +#define NVC_IOCTL_PARAM_RD _IOWR('o', 105, struct nvc_param) +#define NVC_IOCTL32_PARAM_RD _IOWR('o', 105, struct nvc_param_32) +#define NVC_IOCTL_PARAM_ISP_RD _IOWR('o', 200, struct nvc_param_isp) +#define NVC_IOCTL_PARAM_ISP_WR _IOWR('o', 201, struct nvc_param_isp) +#define NVC_IOCTL_FUSE_ID _IOWR('o', 202, struct nvc_fuseid) +#define NVC_IOCTL_SET_EEPROM_DATA _IOWR('o', 254, __u8 *) +#define NVC_IOCTL_GET_EEPROM_DATA _IOWR('o', 255, __u8 *) + +/* Expected higher level power calls are: + * 1 = OFF + * 2 = STANDBY + * 3 = ON + * These will be multiplied by 2 before given to the driver's PM code that + * uses the _PWR_ defines. This allows us to insert defines to give more power + * granularity and still remain linear with regards to the power usage and + * full power state transition latency for easy implementation of PM + * algorithms. + * The PM actions: + * _PWR_ERR = Non-valid state. + * _PWR_OFF_FORCE = _PWR_OFF is forced regardless of standby mechanisms. + * _PWR_OFF = Device, regulators, clocks, etc is turned off. The longest + * transition time to _PWR_ON is from this state. + * _PWR_STDBY_OFF = Device is useless but powered. No communication possible. + * Device does not retain programming. Main purpose is for + * faster return to _PWR_ON without regulator delays. + * _PWR_STDBY = Device is in standby. Device retains programming. + * _PWR_COMM = Device is powered enough to communicate with the device. + * _PWR_ON = Device is at full power with active output. + * + * The kernel drivers treat these calls as Guaranteed Level Of Service. + */ + +#define NVC_PWR_ERR 0 +#define NVC_PWR_OFF_FORCE 1 +#define NVC_PWR_OFF 2 +#define NVC_PWR_STDBY_OFF 3 +#define NVC_PWR_STDBY 4 +#define NVC_PWR_COMM 5 +#define NVC_PWR_ON 6 + +struct nvc_fuseid { + __u32 size; + __u8 data[16]; +}; + +#endif /* __UAPI_NVC_H__ */ + diff --git a/include/uapi/media/nvc_image.h b/include/uapi/media/nvc_image.h new file mode 100644 index 00000000..50a6ea81 --- /dev/null +++ b/include/uapi/media/nvc_image.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2013-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ + +#ifndef __UAPI_NVC_IMAGE_H__ +#define __UAPI_NVC_IMAGE_H__ + +#include +#include + +#define NVC_IMAGER_API_CAPS_VER 2 +#define NVC_IMAGER_API_STATIC_VER 1 +#define NVC_IMAGER_API_DYNAMIC_VER 1 +#define NVC_IMAGER_API_BAYER_VER 1 + +#define NVC_IMAGER_TEST_NONE 0 +#define NVC_IMAGER_TEST_COLORBARS 1 +#define NVC_IMAGER_TEST_CHECKERBOARD 2 +#define NVC_IMAGER_TEST_WALKING1S 3 + +#define NVC_IMAGER_CROPMODE_NONE 1 +#define NVC_IMAGER_CROPMODE_PARTIAL 2 + +#define NVC_IMAGER_TYPE_HUH 0 +#define NVC_IMAGER_TYPE_RAW 1 +#define NVC_IMAGER_TYPE_SOC 2 + +/** + * Defines camera imager types. + * Mirrors "NvOdmImagerRegion" in "imager/include/nvodm_imager.h". + * These must remain in sync. + */ +#define NVC_IMAGER_SENSOR_INTERFACE_PARALLEL_8 1 +#define NVC_IMAGER_SENSOR_INTERFACE_PARALLEL_10 2 +#define NVC_IMAGER_SENSOR_INTERFACE_SERIAL_A 3 +#define NVC_IMAGER_SENSOR_INTERFACE_SERIAL_B 4 +#define NVC_IMAGER_SENSOR_INTERFACE_SERIAL_C 5 +#define NVC_IMAGER_SENSOR_INTERFACE_SERIAL_AB 6 +#define NVC_IMAGER_SENSOR_INTERFACE_CCIR 7 +#define NVC_IMAGER_SENSOR_INTERFACE_HOST 8 +#define NVC_IMAGER_SENSOR_INTERFACE_HOST_CSI_A 9 +#define NVC_IMAGER_SENSOR_INTERFACE_HOST_CSI_B 10 +#define NVC_IMAGER_SENSOR_INTERFACE_NUM 11 + +#define NVC_IMAGER_IDENTIFIER_MAX 32 +#define NVC_IMAGER_FORMAT_MAX 4 +#define NVC_IMAGER_CLOCK_PROFILE_MAX 2 +#define NVC_IMAGER_CAPABILITIES_VERSION2 ((0x3434 << 16) | 2) + +#define NVC_IMAGER_INT2FLOAT_DIVISOR 1000 + +#define NVC_FOCUS_INTERNAL (0x665F4E5643414D69ULL) +#define NVC_FOCUS_GUID(n) (0x665F4E5643414D30ULL | ((n) & 0xF)) +#define NVC_TORCH_GUID(n) (0x6C5F4E5643414D30ULL | ((n) & 0xF)) + + +struct nvc_imager_static_nvc { + __u32 api_version; + __u32 sensor_type; + __u32 bits_per_pixel; + __u32 sensor_id; + __u32 sensor_id_minor; + __u32 focal_len; + __u32 max_aperture; + __u32 fnumber; + __u32 view_angle_h; + __u32 view_angle_v; + __u32 stereo_cap; + __u32 res_chg_wait_time; + __u8 support_isp; + __u8 align1; + __u8 align2; + __u8 align3; + __u8 fuse_id[16]; + __u32 place_holder1; + __u32 place_holder2; + __u32 place_holder3; + __u32 place_holder4; +} __packed; + +struct nvc_imager_dynamic_nvc { + __u32 api_version; + __s32 region_start_x; + __s32 region_start_y; + __u32 x_scale; + __u32 y_scale; + __u32 bracket_caps; + __u32 flush_count; + __u32 init_intra_frame_skip; + __u32 ss_intra_frame_skip; + __u32 ss_frame_number; + __u32 coarse_time; + __u32 max_coarse_diff; + __u32 min_exposure_course; + __u32 max_exposure_course; + __u32 diff_integration_time; + __u32 line_length; + __u32 frame_length; + __u32 min_frame_length; + __u32 max_frame_length; + __u32 min_gain; + __u32 max_gain; + __u32 inherent_gain; + __u32 inherent_gain_bin_en; + __u8 support_bin_control; + __u8 support_fast_mode; + __u8 align2; + __u8 align3; + __u32 pll_mult; + __u32 pll_div; + __u32 mode_sw_wait_frames; + __u32 place_holder1; + __u32 place_holder2; + __u32 place_holder3; +} __packed; + +struct nvc_imager_bayer { + __u32 api_version; + __s32 res_x; + __s32 res_y; + __u32 frame_length; + __u32 coarse_time; + __u32 gain; + __u8 bin_en; + __u8 align1; + __u8 align2; + __u8 align3; + __u32 place_holder1; + __u32 place_holder2; + __u32 place_holder3; + __u32 place_holder4; +} __packed; + +struct nvc_imager_mode { + __s32 res_x; + __s32 res_y; + __s32 active_start_x; + __s32 active_stary_y; + __u32 peak_frame_rate; + __u32 pixel_aspect_ratio; + __u32 pll_multiplier; + __u32 crop_mode; + __u32 rect_left; + __u32 rect_top; + __u32 rect_right; + __u32 rect_bottom; + __u32 point_x; + __u32 point_y; + __u32 type; +} __packed; + +struct nvc_imager_dnvc { + __s32 res_x; + __s32 res_y; + struct nvc_imager_mode *p_mode; + struct nvc_imager_dynamic_nvc *p_dnvc; +} __packed; + +struct nvc_imager_mode_list { + struct nvc_imager_mode *p_modes; + __u32 *p_num_mode; +} __packed; + +struct nvc_clock_profile { + __u32 external_clock_khz; + __u32 clock_multiplier; +} __packed; + +struct nvc_imager_cap { + char identifier[NVC_IMAGER_IDENTIFIER_MAX]; + __u32 sensor_nvc_interface; + __u32 pixel_types[NVC_IMAGER_FORMAT_MAX]; + __u32 orientation; + __u32 direction; + __u32 initial_clock_rate_khz; + struct nvc_clock_profile clock_profiles[NVC_IMAGER_CLOCK_PROFILE_MAX]; + __u32 h_sync_edge; + __u32 v_sync_edge; + __u32 mclk_on_vgp0; + __u8 csi_port; + __u8 data_lanes; + __u8 virtual_channel_id; + __u8 discontinuous_clk_mode; + __u8 cil_threshold_settle; + __u8 align1; + __u8 align2; + __u8 align3; + __s32 min_blank_time_width; + __s32 min_blank_time_height; + __u32 preferred_mode_index; + __u64 focuser_guid; + __u64 torch_guid; + __u32 cap_version; + __u8 flash_control_enabled; + __u8 adjustable_flash_timing; + __u8 is_hdr; + __u8 align5; +} __packed; + +struct nvc_imager_ae { + __u32 frame_length; + __u8 frame_length_enable; + __u32 coarse_time; + __u8 coarse_time_enable; + __u32 gain; + __u8 gain_enable; +} __packed; + +union nvc_imager_flash_control { + __u16 mode; + struct { + __u16 enable:1; /* enable the on-sensor flash control */ + __u16 edge_trig_en:1; /* two types of flash controls: + * 0 - LED_FLASH_EN - supports continued + * flash level only, doesn't + * support start edge/repeat/dly. + * 1 - FLASH_EN - supports control pulse + * control pulse attributes are + * defined below. + */ + __u16 start_edge:1; /* flash control pulse rise position: + * 0 - at the start of the next frame. + * 1 - at the effective pixel end + * position of the next frame. + */ + __u16 repeat:1; /* flash control pulse repeat: + * 0 - only triggers one frame. + * 1 - trigger repeats every frame until + * Flash_EN = 0. + */ + __u16 delay_frm:2; /* flash control pulse can be delayed + * in frame units: (0 - 3) - frame + * numbers the pulse is delayed. + */ + } settings; +}; + +#define NVC_IOCTL_CAPS_RD _IOWR('o', 106, struct nvc_imager_cap) +#define NVC_IOCTL_MODE_WR _IOW('o', 107, struct nvc_imager_bayer) +#define NVC_IOCTL_MODE_RD _IOWR('o', 108, struct nvc_imager_mode_list) +#define NVC_IOCTL_STATIC_RD _IOWR('o', 109, struct nvc_imager_static_nvc) +#define NVC_IOCTL_DYNAMIC_RD _IOWR('o', 110, struct nvc_imager_dnvc) + +#endif /* __UAPI_NVC_IMAGE_H__ */ diff --git a/include/uapi/media/ov5693.h b/include/uapi/media/ov5693.h new file mode 100644 index 00000000..e2269302 --- /dev/null +++ b/include/uapi/media/ov5693.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2013-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + */ + +#ifndef __UAPI_OV5693_H__ +#define __UAPI_OV5693_H__ + +#include +#include "nvc_image.h" + +#define OV5693_IOCTL_SET_MODE _IOW('o', 1, struct ov5693_mode) +#define OV5693_IOCTL_SET_FRAME_LENGTH _IOW('o', 2, __u32) +#define OV5693_IOCTL_SET_COARSE_TIME _IOW('o', 3, __u32) +#define OV5693_IOCTL_SET_GAIN _IOW('o', 4, __u16) +#define OV5693_IOCTL_GET_STATUS _IOR('o', 5, __u8) +#define OV5693_IOCTL_SET_BINNING _IOW('o', 6, __u8) +#define OV5693_IOCTL_TEST_PATTERN _IOW('o', 7, \ + enum ov5693_test_pattern) +#define OV5693_IOCTL_SET_GROUP_HOLD _IOW('o', 8, struct ov5693_ae) +/* + * IOCTL to set the operating mode of camera. + * This can be either stereo , leftOnly or rightOnly + */ +#define OV5693_IOCTL_SET_CAMERA_MODE _IOW('o', 10, __u32) +#define OV5693_IOCTL_SYNC_SENSORS _IOW('o', 11, __u32) +#define OV5693_IOCTL_GET_FUSEID _IOR('o', 12, struct nvc_fuseid) +#define OV5693_IOCTL_SET_HDR_COARSE_TIME _IOW('o', 13, struct ov5693_hdr) +#define OV5693_IOCTL_READ_OTP_BANK _IOWR('o', 14, \ + struct ov5693_otp_bank) +#define OV5693_IOCTL_SET_CAL_DATA _IOW('o', 15, \ + struct ov5693_cal_data) +#define OV5693_IOCTL_GET_EEPROM_DATA _IOR('o', 20, __u8 *) +#define OV5693_IOCTL_SET_EEPROM_DATA _IOW('o', 21, __u8 *) +#define OV5693_IOCTL_GET_CAPS _IOR('o', 22, struct nvc_imager_cap) +#define OV5693_IOCTL_SET_POWER _IOW('o', 23, __u32) + +#define OV5693_FUSE_ID_OTP_START_ADDR 0x3D00 +#define OV5693_FUSE_ID_OTP_BANK 0 +#define OV5693_FUSE_ID_SIZE 8 +#define OV5693_FUSE_ID_STR_SIZE (OV5693_FUSE_ID_SIZE * 2) + +#define OV5693_FRAME_LENGTH_ADDR_MSB 0x380E +#define OV5693_FRAME_LENGTH_ADDR_LSB 0x380F +#define OV5693_COARSE_TIME_ADDR_1 0x3500 +#define OV5693_COARSE_TIME_ADDR_2 0x3501 +#define OV5693_COARSE_TIME_ADDR_3 0x3502 +#define OV5693_COARSE_TIME_SHORT_ADDR_1 0x3506 +#define OV5693_COARSE_TIME_SHORT_ADDR_2 0x3507 +#define OV5693_COARSE_TIME_SHORT_ADDR_3 0x3508 +#define OV5693_GAIN_ADDR_MSB 0x350A +#define OV5693_GAIN_ADDR_LSB 0x350B +#define OV5693_GROUP_HOLD_ADDR 0x3208 +#define OV5693_TIMING_REG20 0x3820 +#define VERTICAL_FLIP ((0x1 << 1) | (0x1 << 6)) +#define OV5693_TIMING_REG21 0x3821 +#define HORIZONTAL_MIRROR_MASK (0x3 << 1) + +struct ov5693_mode { + int res_x; + int res_y; + int fps; + __u32 frame_length; + __u32 coarse_time; + __u32 coarse_time_short; + __u16 gain; + __u8 hdr_en; +}; + +struct ov5693_ae { + __u32 frame_length; + __u8 frame_length_enable; + __u32 coarse_time; + __u32 coarse_time_short; + __u8 coarse_time_enable; + __s32 gain; + __u8 gain_enable; +}; + +struct ov5693_fuseid { + __u32 size; + __u8 id[16]; +}; + +struct ov5693_hdr { + __u32 coarse_time_long; + __u32 coarse_time_short; +}; + +struct ov5693_otp_bank { + __u32 id; + __u8 buf[16]; +}; + +struct ov5693_cal_data { + int loaded; + int rg_ratio; + int bg_ratio; + int rg_ratio_typical; + int bg_ratio_typical; + __u8 lenc[62]; +}; + +#endif /* __UAPI_OV5693_H__ */