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