linux/drivers/media/i2c/imx334.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Sony imx334 sensor driver
 *
 * Copyright (C) 2021 Intel Corporation
 */
#include <linux/unaligned.h>

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

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

/* Streaming Mode */
#define IMX334_REG_MODE_SELECT
#define IMX334_MODE_STANDBY
#define IMX334_MODE_STREAMING

/* Lines per frame */
#define IMX334_REG_LPFR

/* Chip ID */
#define IMX334_REG_ID
#define IMX334_ID

/* Exposure control */
#define IMX334_REG_SHUTTER
#define IMX334_EXPOSURE_MIN
#define IMX334_EXPOSURE_OFFSET
#define IMX334_EXPOSURE_STEP
#define IMX334_EXPOSURE_DEFAULT

/* Analog gain control */
#define IMX334_REG_AGAIN
#define IMX334_AGAIN_MIN
#define IMX334_AGAIN_MAX
#define IMX334_AGAIN_STEP
#define IMX334_AGAIN_DEFAULT

/* Group hold register */
#define IMX334_REG_HOLD

/* Input clock rate */
#define IMX334_INCLK_RATE

/* CSI2 HW configuration */
#define IMX334_LINK_FREQ_891M
#define IMX334_LINK_FREQ_445M
#define IMX334_NUM_DATA_LANES

#define IMX334_REG_MIN
#define IMX334_REG_MAX

/* Test Pattern Control */
#define IMX334_REG_TP
#define IMX334_TP_COLOR_HBARS
#define IMX334_TP_COLOR_VBARS

#define IMX334_TPG_EN_DOUT
#define IMX334_TP_ENABLE
#define IMX334_TP_DISABLE

#define IMX334_TPG_COLORW
#define IMX334_TPG_COLORW_120P

#define IMX334_TP_CLK_EN
#define IMX334_TP_CLK_EN_VAL
#define IMX334_TP_CLK_DIS_VAL

#define IMX334_DIG_CLP_MODE

/**
 * struct imx334_reg - imx334 sensor register
 * @address: Register address
 * @val: Register value
 */
struct imx334_reg {};

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

/**
 * struct imx334_mode - imx334 sensor mode structure
 * @width: Frame width
 * @height: Frame height
 * @hblank: Horizontal blanking in lines
 * @vblank: Vertical blanking in lines
 * @vblank_min: Minimal vertical blanking in lines
 * @vblank_max: Maximum vertical blanking in lines
 * @pclk: Sensor pixel clock
 * @link_freq_idx: Link frequency index
 * @reg_list: Register list for sensor mode
 */
struct imx334_mode {};

/**
 * struct imx334 - imx334 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
 * @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
 * @cur_mode: Pointer to current selected sensor mode
 * @mutex: Mutex for serializing sensor controls
 * @link_freq_bitmap: Menu bitmap for link_freq_ctrl
 * @cur_code: current selected format code
 */
struct imx334 {};

static const s64 link_freq[] =;

/* Sensor mode registers for 1920x1080@30fps */
static const struct imx334_reg mode_1920x1080_regs[] =;

/* Sensor mode registers for 3840x2160@30fps */
static const struct imx334_reg mode_3840x2160_regs[] =;

static const char * const imx334_test_pattern_menu[] =;

static const int imx334_test_pattern_val[] =;

static const struct imx334_reg raw10_framefmt_regs[] =;

static const struct imx334_reg raw12_framefmt_regs[] =;

static const u32 imx334_mbus_codes[] =;

/* Supported sensor mode configurations */
static const struct imx334_mode supported_modes[] =;

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

/**
 * imx334_read_reg() - Read registers.
 * @imx334: pointer to imx334 device
 * @reg: register address
 * @len: length of bytes to read. Max supported bytes is 4
 * @val: pointer to register value to be filled.
 *
 * Big endian register addresses with little endian values.
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx334_read_reg(struct imx334 *imx334, u16 reg, u32 len, u32 *val)
{}

/**
 * imx334_write_reg() - Write register
 * @imx334: pointer to imx334 device
 * @reg: register address
 * @len: length of bytes. Max supported bytes is 4
 * @val: register value
 *
 * Big endian register addresses with little endian values.
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx334_write_reg(struct imx334 *imx334, u16 reg, u32 len, u32 val)
{}

/**
 * imx334_write_regs() - Write a list of registers
 * @imx334: pointer to imx334 device
 * @regs: list of registers to be written
 * @len: length of registers array
 *
 * Return: 0 if successful, error code otherwise.
 */
static int imx334_write_regs(struct imx334 *imx334,
			     const struct imx334_reg *regs, u32 len)
{}

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

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

/**
 * imx334_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 imx334_set_ctrl(struct v4l2_ctrl *ctrl)
{}

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

static int imx334_get_format_code(struct imx334 *imx334, u32 code)
{}

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

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

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

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

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

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

static int imx334_set_framefmt(struct imx334 *imx334)
{}

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

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

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

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

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

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

static const struct v4l2_subdev_pad_ops imx334_pad_ops =;

static const struct v4l2_subdev_ops imx334_subdev_ops =;

static const struct v4l2_subdev_internal_ops imx334_internal_ops =;

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

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

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

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

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

static const struct dev_pm_ops imx334_pm_ops =;

static const struct of_device_id imx334_of_match[] =;

MODULE_DEVICE_TABLE(of, imx334_of_match);

static struct i2c_driver imx334_driver =;

module_i2c_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();