linux/drivers/media/i2c/imx290.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Sony IMX290 CMOS Image Sensor Driver
 *
 * Copyright (C) 2019 FRAMOS GmbH.
 *
 * Copyright (C) 2019 Linaro Ltd.
 * Author: Manivannan Sadhasivam <[email protected]>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

#include <linux/unaligned.h>

#include <media/media-entity.h>
#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>

#define IMX290_STANDBY
#define IMX290_REGHOLD
#define IMX290_XMSTA
#define IMX290_ADBIT
#define IMX290_ADBIT_10BIT
#define IMX290_ADBIT_12BIT
#define IMX290_CTRL_07
#define IMX290_VREVERSE
#define IMX290_HREVERSE
#define IMX290_WINMODE_1080P
#define IMX290_WINMODE_720P
#define IMX290_WINMODE_CROP
#define IMX290_FR_FDG_SEL
#define IMX290_BLKLEVEL
#define IMX290_GAIN
#define IMX290_VMAX
#define IMX290_VMAX_MAX
#define IMX290_HMAX
#define IMX290_HMAX_MAX
#define IMX290_SHS1
#define IMX290_WINWV_OB
#define IMX290_WINPV
#define IMX290_WINWV
#define IMX290_WINPH
#define IMX290_WINWH
#define IMX290_OUT_CTRL
#define IMX290_ODBIT_10BIT
#define IMX290_ODBIT_12BIT
#define IMX290_OPORTSEL_PARALLEL
#define IMX290_OPORTSEL_LVDS_2CH
#define IMX290_OPORTSEL_LVDS_4CH
#define IMX290_OPORTSEL_LVDS_8CH
#define IMX290_XSOUTSEL
#define IMX290_XSOUTSEL_XVSOUTSEL_HIGH
#define IMX290_XSOUTSEL_XVSOUTSEL_VSYNC
#define IMX290_XSOUTSEL_XHSOUTSEL_HIGH
#define IMX290_XSOUTSEL_XHSOUTSEL_HSYNC
#define IMX290_INCKSEL1
#define IMX290_INCKSEL2
#define IMX290_INCKSEL3
#define IMX290_INCKSEL4
#define IMX290_PGCTRL
#define IMX290_ADBIT1
#define IMX290_ADBIT1_10BIT
#define IMX290_ADBIT1_12BIT
#define IMX290_INCKSEL5
#define IMX290_INCKSEL6
#define IMX290_ADBIT2
#define IMX290_ADBIT2_10BIT
#define IMX290_ADBIT2_12BIT
#define IMX290_CHIP_ID
#define IMX290_ADBIT3
#define IMX290_ADBIT3_10BIT
#define IMX290_ADBIT3_12BIT
#define IMX290_REPETITION
#define IMX290_PHY_LANE_NUM
#define IMX290_OPB_SIZE_V
#define IMX290_Y_OUT_SIZE
#define IMX290_CSI_DT_FMT
#define IMX290_CSI_DT_FMT_RAW10
#define IMX290_CSI_DT_FMT_RAW12
#define IMX290_CSI_LANE_MODE
#define IMX290_EXTCK_FREQ
#define IMX290_TCLKPOST
#define IMX290_THSZERO
#define IMX290_THSPREPARE
#define IMX290_TCLKTRAIL
#define IMX290_THSTRAIL
#define IMX290_TCLKZERO
#define IMX290_TCLKPREPARE
#define IMX290_TLPX
#define IMX290_X_OUT_SIZE
#define IMX290_INCKSEL7

#define IMX290_PGCTRL_REGEN
#define IMX290_PGCTRL_THRU
#define IMX290_PGCTRL_MODE(n)

/* Number of lines by which exposure must be less than VMAX */
#define IMX290_EXPOSURE_OFFSET

#define IMX290_PIXEL_RATE

/*
 * The IMX290 pixel array is organized as follows:
 *
 *     +------------------------------------+
 *     |           Optical Black            |     }  Vertical effective optical black (10)
 * +---+------------------------------------+---+
 * |   |                                    |   | }  Effective top margin (8)
 * |   |   +----------------------------+   |   | \
 * |   |   |                            |   |   |  |
 * |   |   |                            |   |   |  |
 * |   |   |                            |   |   |  |
 * |   |   |    Recording Pixel Area    |   |   |  | Recommended height (1080)
 * |   |   |                            |   |   |  |
 * |   |   |                            |   |   |  |
 * |   |   |                            |   |   |  |
 * |   |   +----------------------------+   |   | /
 * |   |                                    |   | }  Effective bottom margin (9)
 * +---+------------------------------------+---+
 *  <-> <-> <--------------------------> <-> <->
 *                                            \----  Ignored right margin (4)
 *                                        \--------  Effective right margin (9)
 *                       \-------------------------  Recommended width (1920)
 *       \-----------------------------------------  Effective left margin (8)
 *   \---------------------------------------------  Ignored left margin (4)
 *
 * The optical black lines are output over CSI-2 with a separate data type.
 *
 * The pixel array is meant to have 1920x1080 usable pixels after image
 * processing in an ISP. It has 8 (9) extra active pixels usable for color
 * processing in the ISP on the top and left (bottom and right) sides of the
 * image. In addition, 4 additional pixels are present on the left and right
 * sides of the image, documented as "ignored area".
 *
 * As far as is understood, all pixels of the pixel array (ignored area, color
 * processing margins and recording area) can be output by the sensor.
 */

#define IMX290_PIXEL_ARRAY_WIDTH
#define IMX290_PIXEL_ARRAY_HEIGHT
#define IMX290_PIXEL_ARRAY_MARGIN_LEFT
#define IMX290_PIXEL_ARRAY_MARGIN_RIGHT
#define IMX290_PIXEL_ARRAY_MARGIN_TOP
#define IMX290_PIXEL_ARRAY_MARGIN_BOTTOM
#define IMX290_PIXEL_ARRAY_RECORDING_WIDTH
#define IMX290_PIXEL_ARRAY_RECORDING_HEIGHT

/* Equivalent value for 16bpp */
#define IMX290_BLACK_LEVEL_DEFAULT

#define IMX290_NUM_SUPPLIES

enum imx290_colour_variant {};

enum imx290_model {};

struct imx290_model_info {};

enum imx290_clk_freq {};

/*
 * Clock configuration for registers INCKSEL1 to INCKSEL6.
 */
struct imx290_clk_cfg {};

struct imx290_mode {};

struct imx290_csi_cfg {};

struct imx290 {};

static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
{}

/* -----------------------------------------------------------------------------
 * Modes and formats
 */

static const struct cci_reg_sequence imx290_global_init_settings[] =;

static const struct cci_reg_sequence imx290_global_init_settings_290[] =;

#define IMX290_NUM_CLK_REGS
static const struct cci_reg_sequence xclk_regs[][IMX290_NUM_CLK_REGS] =;

static const struct cci_reg_sequence imx290_global_init_settings_327[] =;

static const struct cci_reg_sequence imx290_1080p_settings[] =;

static const struct cci_reg_sequence imx290_720p_settings[] =;

static const struct cci_reg_sequence imx290_10bit_settings[] =;

static const struct cci_reg_sequence imx290_12bit_settings[] =;

static const struct imx290_csi_cfg imx290_csi_222_75mhz =;

static const struct imx290_csi_cfg imx290_csi_445_5mhz =;

static const struct imx290_csi_cfg imx290_csi_148_5mhz =;

static const struct imx290_csi_cfg imx290_csi_297mhz =;

/* supported link frequencies */
#define FREQ_INDEX_1080P
#define FREQ_INDEX_720P
static const s64 imx290_link_freq_2lanes[] =;

static const s64 imx290_link_freq_4lanes[] =;

/*
 * In this function and in the similar ones below We rely on imx290_probe()
 * to ensure that nlanes is either 2 or 4.
 */
static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290)
{}

static inline int imx290_link_freqs_num(const struct imx290 *imx290)
{}

static const struct imx290_clk_cfg imx290_1080p_clock_config[] =;

static const struct imx290_clk_cfg imx290_720p_clock_config[] =;

/* Mode configs */
static const struct imx290_mode imx290_modes_2lanes[] =;

static const struct imx290_mode imx290_modes_4lanes[] =;

static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
{}

static inline int imx290_modes_num(const struct imx290 *imx290)
{}

struct imx290_format_info {};

static const struct imx290_format_info imx290_formats[] =;

static const struct imx290_format_info *
imx290_format_info(const struct imx290 *imx290, u32 code)
{}

static int imx290_set_register_array(struct imx290 *imx290,
				     const struct cci_reg_sequence *settings,
				     unsigned int num_settings)
{}

static int imx290_set_clock(struct imx290 *imx290)
{}

static int imx290_set_data_lanes(struct imx290 *imx290)
{}

static int imx290_set_black_level(struct imx290 *imx290,
				  const struct v4l2_mbus_framefmt *format,
				  unsigned int black_level, int *err)
{}

static int imx290_set_csi_config(struct imx290 *imx290)
{}

static int imx290_setup_format(struct imx290 *imx290,
			       const struct v4l2_mbus_framefmt *format)
{}

/* ----------------------------------------------------------------------------
 * Controls
 */
static void imx290_exposure_update(struct imx290 *imx290,
				   const struct imx290_mode *mode)
{}

static int imx290_set_ctrl(struct v4l2_ctrl *ctrl)
{}

static const struct v4l2_ctrl_ops imx290_ctrl_ops =;

static const char * const imx290_test_pattern_menu[] =;

static void imx290_ctrl_update(struct imx290 *imx290,
			       const struct imx290_mode *mode)
{}

static int imx290_ctrl_init(struct imx290 *imx290)
{}

/* ----------------------------------------------------------------------------
 * Subdev operations
 */

/* Start streaming */
static int imx290_start_streaming(struct imx290 *imx290,
				  struct v4l2_subdev_state *state)
{}

/* Stop streaming */
static int imx290_stop_streaming(struct imx290 *imx290)
{}

static int imx290_set_stream(struct v4l2_subdev *sd, int enable)
{}

static int imx290_enum_mbus_code(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_mbus_code_enum *code)
{}

static int imx290_enum_frame_size(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *sd_state,
				  struct v4l2_subdev_frame_size_enum *fse)
{}

static int imx290_set_fmt(struct v4l2_subdev *sd,
			  struct v4l2_subdev_state *sd_state,
			  struct v4l2_subdev_format *fmt)
{}

static int imx290_get_selection(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_selection *sel)
{}

static int imx290_entity_init_state(struct v4l2_subdev *subdev,
				    struct v4l2_subdev_state *sd_state)
{}

static const struct v4l2_subdev_core_ops imx290_core_ops =;

static const struct v4l2_subdev_video_ops imx290_video_ops =;

static const struct v4l2_subdev_pad_ops imx290_pad_ops =;

static const struct v4l2_subdev_ops imx290_subdev_ops =;

static const struct v4l2_subdev_internal_ops imx290_internal_ops =;

static const struct media_entity_operations imx290_subdev_entity_ops =;

static int imx290_subdev_init(struct imx290 *imx290)
{}

static void imx290_subdev_cleanup(struct imx290 *imx290)
{}

/* ----------------------------------------------------------------------------
 * Power management
 */

static int imx290_power_on(struct imx290 *imx290)
{}

static void imx290_power_off(struct imx290 *imx290)
{}

static int imx290_runtime_resume(struct device *dev)
{}

static int imx290_runtime_suspend(struct device *dev)
{}

static const struct dev_pm_ops imx290_pm_ops =;

/* ----------------------------------------------------------------------------
 * Probe & remove
 */

static const char * const imx290_supply_name[IMX290_NUM_SUPPLIES] =;

static int imx290_get_regulators(struct device *dev, struct imx290 *imx290)
{}

static int imx290_init_clk(struct imx290 *imx290)
{}

/*
 * Returns 0 if all link frequencies used by the driver for the given number
 * of MIPI data lanes are mentioned in the device tree, or the value of the
 * first missing frequency otherwise.
 */
static s64 imx290_check_link_freqs(const struct imx290 *imx290,
				   const struct v4l2_fwnode_endpoint *ep)
{}

static const struct imx290_model_info imx290_models[] =;

static int imx290_parse_dt(struct imx290 *imx290)
{}

static int imx290_probe(struct i2c_client *client)
{}

static void imx290_remove(struct i2c_client *client)
{}

static const struct of_device_id imx290_of_match[] =;
MODULE_DEVICE_TABLE(of, imx290_of_match);

static struct i2c_driver imx290_i2c_driver =;

module_i2c_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_LICENSE();