linux/drivers/media/i2c/imx335.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Sony imx335 Camera Sensor Driver
 *
 * Copyright (C) 2021 Intel Corporation
 */
#include <asm/unaligned.h>

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>

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

/* Streaming Mode */
#define IMX335_REG_MODE_SELECT
#define IMX335_MODE_STANDBY
#define IMX335_MODE_STREAMING

/* Group hold register */
#define IMX335_REG_HOLD

#define IMX335_REG_MASTER_MODE
#define IMX335_REG_BCWAIT_TIME
#define IMX335_REG_CPWAIT_TIME
#define IMX335_REG_WINMODE
#define IMX335_REG_HTRIMMING_START
#define IMX335_REG_HNUM

/* Lines per frame */
#define IMX335_REG_VMAX

#define IMX335_REG_OPB_SIZE_V
#define IMX335_REG_ADBIT
#define IMX335_REG_Y_OUT_SIZE

#define IMX335_REG_SHUTTER
#define IMX335_EXPOSURE_MIN
#define IMX335_EXPOSURE_OFFSET
#define IMX335_EXPOSURE_STEP
#define IMX335_EXPOSURE_DEFAULT

#define IMX335_REG_AREA3_ST_ADR_1
#define IMX335_REG_AREA3_WIDTH_1

/* Analog and Digital gain control */
#define IMX335_REG_GAIN
#define IMX335_AGAIN_MIN
#define IMX335_AGAIN_MAX
#define IMX335_AGAIN_STEP
#define IMX335_AGAIN_DEFAULT

#define IMX335_REG_TPG_TESTCLKEN

#define IMX335_REG_INCLKSEL1
#define IMX335_REG_INCLKSEL2
#define IMX335_REG_INCLKSEL3
#define IMX335_REG_INCLKSEL4

#define IMX335_REG_MDBIT
#define IMX335_REG_SYSMODE

#define IMX335_REG_XVS_XHS_DRV

/* Test pattern generator */
#define IMX335_REG_TPG_DIG_CLP_MODE
#define IMX335_REG_TPG_EN_DUOUT
#define IMX335_REG_TPG
#define IMX335_TPG_ALL_000
#define IMX335_TPG_ALL_FFF
#define IMX335_TPG_ALL_555
#define IMX335_TPG_ALL_AAA
#define IMX335_TPG_TOG_555_AAA
#define IMX335_TPG_TOG_AAA_555
#define IMX335_TPG_TOG_000_555
#define IMX335_TPG_TOG_555_000
#define IMX335_TPG_TOG_000_FFF
#define IMX335_TPG_TOG_FFF_000
#define IMX335_TPG_H_COLOR_BARS
#define IMX335_TPG_V_COLOR_BARS
#define IMX335_REG_TPG_COLORWIDTH

#define IMX335_REG_BLKLEVEL

#define IMX335_REG_WRJ_OPEN

#define IMX335_REG_ADBIT1

/* Chip ID */
#define IMX335_REG_ID
#define IMX335_ID

/* Data Lanes */
#define IMX335_REG_LANEMODE
#define IMX335_2LANE
#define IMX335_4LANE

#define IMX335_REG_TCLKPOST
#define IMX335_REG_TCLKPREPARE
#define IMX335_REG_TCLK_TRAIL
#define IMX335_REG_TCLK_ZERO
#define IMX335_REG_THS_PREPARE
#define IMX335_REG_THS_ZERO
#define IMX335_REG_THS_TRAIL
#define IMX335_REG_THS_EXIT
#define IMX335_REG_TPLX

/* Input clock rate */
#define IMX335_INCLK_RATE

/* CSI2 HW configuration */
#define IMX335_LINK_FREQ_594MHz
#define IMX335_LINK_FREQ_445MHz

#define IMX335_NUM_DATA_LANES

/* IMX335 native and active pixel array size. */
#define IMX335_NATIVE_WIDTH
#define IMX335_NATIVE_HEIGHT
#define IMX335_PIXEL_ARRAY_LEFT
#define IMX335_PIXEL_ARRAY_TOP
#define IMX335_PIXEL_ARRAY_WIDTH
#define IMX335_PIXEL_ARRAY_HEIGHT

/**
 * struct imx335_reg_list - imx335 sensor register list
 * @num_of_regs: Number of registers in the list
 * @regs: Pointer to register list
 */
struct imx335_reg_list {};

static const char * const imx335_supply_name[] =;

/**
 * struct imx335_mode - imx335 sensor mode structure
 * @width: Frame width
 * @height: Frame height
 * @code: Format code
 * @hblank: Horizontal blanking in lines
 * @vblank: Vertical blanking in lines
 * @vblank_min: Minimum vertical blanking in lines
 * @vblank_max: Maximum vertical blanking in lines
 * @pclk: Sensor pixel clock
 * @reg_list: Register list for sensor mode
 */
struct imx335_mode {};

/**
 * struct imx335 - imx335 sensor device structure
 * @dev: Pointer to generic device
 * @client: Pointer to i2c client
 * @sd: V4L2 sub-device
 * @pad: Media pad. Only one pad supported
 * @reset_gpio: Sensor reset gpio
 * @supplies: Regulator supplies to handle power control
 * @cci: CCI register map
 * @inclk: Sensor input clock
 * @ctrl_handler: V4L2 control handler
 * @link_freq_ctrl: Pointer to link frequency control
 * @pclk_ctrl: Pointer to pixel clock control
 * @hblank_ctrl: Pointer to horizontal blanking control
 * @vblank_ctrl: Pointer to vertical blanking control
 * @exp_ctrl: Pointer to exposure control
 * @again_ctrl: Pointer to analog gain control
 * @vblank: Vertical blanking in lines
 * @lane_mode: Mode for number of connected data lanes
 * @cur_mode: Pointer to current selected sensor mode
 * @mutex: Mutex for serializing sensor controls
 * @link_freq_bitmap: Menu bitmap for link_freq_ctrl
 * @cur_mbus_code: Currently selected media bus format code
 */
struct imx335 {};

static const char * const imx335_tpg_menu[] =;

static const int imx335_tpg_val[] =;

/* Sensor mode registers */
static const struct cci_reg_sequence mode_2592x1940_regs[] =;

static const struct cci_reg_sequence raw10_framefmt_regs[] =;

static const struct cci_reg_sequence raw12_framefmt_regs[] =;

static const struct cci_reg_sequence mipi_data_rate_1188Mbps[] =;

static const struct cci_reg_sequence mipi_data_rate_891Mbps[] =;

static const s64 link_freq[] =;

static const struct imx335_reg_list link_freq_reglist[] =;

static const u32 imx335_mbus_codes[] =;

/* Supported sensor mode configurations */
static const struct imx335_mode supported_mode =;

/**
 * to_imx335() - imx335 V4L2 sub-device to imx335 device.
 * @subdev: pointer to imx335 V4L2 sub-device
 *
 * Return: pointer to imx335 device
 */
static inline struct imx335 *to_imx335(struct v4l2_subdev *subdev)
{}

/**
 * imx335_update_controls() - Update control ranges based on streaming mode
 * @imx335: pointer to imx335 device
 * @mode: pointer to imx335_mode sensor mode
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_update_controls(struct imx335 *imx335,
				  const struct imx335_mode *mode)
{}

/**
 * imx335_update_exp_gain() - Set updated exposure and gain
 * @imx335: pointer to imx335 device
 * @exposure: updated exposure value
 * @gain: updated analog gain value
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_update_exp_gain(struct imx335 *imx335, u32 exposure, u32 gain)
{}

static int imx335_update_test_pattern(struct imx335 *imx335, u32 pattern_index)
{}

/**
 * imx335_set_ctrl() - Set subdevice control
 * @ctrl: pointer to v4l2_ctrl structure
 *
 * Supported controls:
 * - V4L2_CID_VBLANK
 * - cluster controls:
 *   - V4L2_CID_ANALOGUE_GAIN
 *   - V4L2_CID_EXPOSURE
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_set_ctrl(struct v4l2_ctrl *ctrl)
{}

/* V4l2 subdevice control ops*/
static const struct v4l2_ctrl_ops imx335_ctrl_ops =;

static int imx335_get_format_code(struct imx335 *imx335, u32 code)
{}

/**
 * imx335_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 * @code: V4L2 sub-device code enumeration need to be filled
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_enum_mbus_code(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_mbus_code_enum *code)
{}

/**
 * imx335_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 * @fsize: V4L2 sub-device size enumeration need to be filled
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_enum_frame_size(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *sd_state,
				  struct v4l2_subdev_frame_size_enum *fsize)
{}

/**
 * imx335_fill_pad_format() - Fill subdevice pad format
 *                            from selected sensor mode
 * @imx335: pointer to imx335 device
 * @mode: pointer to imx335_mode sensor mode
 * @fmt: V4L2 sub-device format need to be filled
 */
static void imx335_fill_pad_format(struct imx335 *imx335,
				   const struct imx335_mode *mode,
				   struct v4l2_subdev_format *fmt)
{}

/**
 * imx335_get_pad_format() - Get subdevice pad format
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 * @fmt: V4L2 sub-device format need to be set
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_get_pad_format(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_format *fmt)
{}

/**
 * imx335_set_pad_format() - Set subdevice pad format
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 * @fmt: V4L2 sub-device format need to be set
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_set_pad_format(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_format *fmt)
{}

/**
 * imx335_init_state() - Initialize sub-device state
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_init_state(struct v4l2_subdev *sd,
			     struct v4l2_subdev_state *sd_state)
{}

/**
 * imx335_get_selection() - Selection API
 * @sd: pointer to imx335 V4L2 sub-device structure
 * @sd_state: V4L2 sub-device configuration
 * @sel: V4L2 selection info
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_get_selection(struct v4l2_subdev *sd,
				struct v4l2_subdev_state *sd_state,
				struct v4l2_subdev_selection *sel)
{}

static int imx335_set_framefmt(struct imx335 *imx335)
{}

/**
 * imx335_start_streaming() - Start sensor stream
 * @imx335: pointer to imx335 device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_start_streaming(struct imx335 *imx335)
{}

/**
 * imx335_stop_streaming() - Stop sensor stream
 * @imx335: pointer to imx335 device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_stop_streaming(struct imx335 *imx335)
{}

/**
 * imx335_set_stream() - Enable sensor streaming
 * @sd: pointer to imx335 subdevice
 * @enable: set to enable sensor streaming
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_set_stream(struct v4l2_subdev *sd, int enable)
{}

/**
 * imx335_detect() - Detect imx335 sensor
 * @imx335: pointer to imx335 device
 *
 * Return: 0 if successful, -EIO if sensor id does not match
 */
static int imx335_detect(struct imx335 *imx335)
{}

/**
 * imx335_parse_hw_config() - Parse HW configuration and check if supported
 * @imx335: pointer to imx335 device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_parse_hw_config(struct imx335 *imx335)
{}

/* V4l2 subdevice ops */
static const struct v4l2_subdev_video_ops imx335_video_ops =;

static const struct v4l2_subdev_pad_ops imx335_pad_ops =;

static const struct v4l2_subdev_ops imx335_subdev_ops =;

static const struct v4l2_subdev_internal_ops imx335_internal_ops =;

/**
 * imx335_power_on() - Sensor power on sequence
 * @dev: pointer to i2c device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_power_on(struct device *dev)
{}

/**
 * imx335_power_off() - Sensor power off sequence
 * @dev: pointer to i2c device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_power_off(struct device *dev)
{}

/**
 * imx335_init_controls() - Initialize sensor subdevice controls
 * @imx335: pointer to imx335 device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_init_controls(struct imx335 *imx335)
{}

/**
 * imx335_probe() - I2C client device binding
 * @client: pointer to i2c client device
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx335_probe(struct i2c_client *client)
{}

/**
 * imx335_remove() - I2C client device unbinding
 * @client: pointer to I2C client device
 *
 * Return: 0 if successful, error code otherwise.
 */
static void imx335_remove(struct i2c_client *client)
{}

static const struct dev_pm_ops imx335_pm_ops =;

static const struct of_device_id imx335_of_match[] =;

MODULE_DEVICE_TABLE(of, imx335_of_match);

static struct i2c_driver imx335_driver =;

module_i2c_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();