linux/drivers/media/i2c/ov9282.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * OmniVision ov9282 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/regulator/consumer.h>

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

/* Streaming Mode */
#define OV9282_REG_MODE_SELECT
#define OV9282_MODE_STANDBY
#define OV9282_MODE_STREAMING

#define OV9282_REG_PLL_CTRL_0D
#define OV9282_PLL_CTRL_0D_RAW8
#define OV9282_PLL_CTRL_0D_RAW10

#define OV9282_REG_TIMING_HTS
#define OV9282_TIMING_HTS_MAX

/* Lines per frame */
#define OV9282_REG_LPFR

/* Chip ID */
#define OV9282_REG_ID
#define OV9282_ID

/* Exposure control */
#define OV9282_REG_EXPOSURE
#define OV9282_EXPOSURE_MIN
#define OV9282_EXPOSURE_OFFSET
#define OV9282_EXPOSURE_STEP
#define OV9282_EXPOSURE_DEFAULT

/* Analog gain control */
#define OV9282_REG_AGAIN
#define OV9282_AGAIN_MIN
#define OV9282_AGAIN_MAX
#define OV9282_AGAIN_STEP
#define OV9282_AGAIN_DEFAULT

/* Group hold register */
#define OV9282_REG_HOLD

#define OV9282_REG_ANA_CORE_2
#define OV9282_ANA_CORE2_RAW8
#define OV9282_ANA_CORE2_RAW10

#define OV9282_REG_TIMING_FORMAT_1
#define OV9282_REG_TIMING_FORMAT_2
#define OV9282_FLIP_BIT

#define OV9282_REG_MIPI_CTRL00
#define OV9282_GATED_CLOCK

/* Input clock rate */
#define OV9282_INCLK_RATE

/* CSI2 HW configuration */
#define OV9282_LINK_FREQ
#define OV9282_NUM_DATA_LANES

/* Pixel rate */
#define OV9282_PIXEL_RATE_10BIT
#define OV9282_PIXEL_RATE_8BIT

/*
 * OV9282 native and active pixel array size.
 * 8 dummy rows/columns on each edge of a 1280x800 active array
 */
#define OV9282_NATIVE_WIDTH
#define OV9282_NATIVE_HEIGHT
#define OV9282_PIXEL_ARRAY_LEFT
#define OV9282_PIXEL_ARRAY_TOP
#define OV9282_PIXEL_ARRAY_WIDTH
#define OV9282_PIXEL_ARRAY_HEIGHT

#define OV9282_REG_MIN
#define OV9282_REG_MAX

static const char * const ov9282_supply_names[] =;

#define OV9282_NUM_SUPPLIES

/**
 * struct ov9282_reg - ov9282 sensor register
 * @address: Register address
 * @val: Register value
 */
struct ov9282_reg {};

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

/**
 * struct ov9282_mode - ov9282 sensor mode structure
 * @width: Frame width
 * @height: Frame height
 * @hblank_min: Minimum horizontal blanking in lines for non-continuous[0] and
 *		continuous[1] clock modes
 * @vblank: Vertical blanking in lines
 * @vblank_min: Minimum vertical blanking in lines
 * @vblank_max: Maximum vertical blanking in lines
 * @link_freq_idx: Link frequency index
 * @crop: on-sensor cropping for this mode
 * @reg_list: Register list for sensor mode
 */
struct ov9282_mode {};

/**
 * struct ov9282 - ov9282 sensor device structure
 * @dev: Pointer to generic device
 * @sd: V4L2 sub-device
 * @pad: Media pad. Only one pad supported
 * @reset_gpio: Sensor reset gpio
 * @inclk: Sensor input clock
 * @supplies: Regulator supplies for the sensor
 * @ctrl_handler: V4L2 control handler
 * @link_freq_ctrl: Pointer to link frequency 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
 * @pixel_rate: Pointer to pixel rate control
 * @vblank: Vertical blanking in lines
 * @noncontinuous_clock: Selection of CSI2 noncontinuous clock mode
 * @cur_mode: Pointer to current selected sensor mode
 * @code: Mbus code currently selected
 * @mutex: Mutex for serializing sensor controls
 */
struct ov9282 {};

static const s64 link_freq[] =;

/*
 * Common registers
 *
 * Note: Do NOT include a software reset (0x0103, 0x01) in any of these
 * register arrays as some settings are written as part of ov9282_power_on,
 * and the reset will clear them.
 */
static const struct ov9282_reg common_regs[] =;

static struct ov9282_reg_list common_regs_list =;

#define MODE_1280_800
#define MODE_1280_720
#define MODE_640_400

#define DEFAULT_MODE

/* Sensor mode registers */
static const struct ov9282_reg mode_1280x800_regs[] =;

static const struct ov9282_reg mode_1280x720_regs[] =;

static const struct ov9282_reg mode_640x400_regs[] =;

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

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

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

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

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

/**
 * ov9282_update_controls() - Update control ranges based on streaming mode
 * @ov9282: pointer to ov9282 device
 * @mode: pointer to ov9282_mode sensor mode
 * @fmt: pointer to the requested mode
 *
 * Return: 0 if successful, error code otherwise.
 */
static int ov9282_update_controls(struct ov9282 *ov9282,
				  const struct ov9282_mode *mode,
				  const struct v4l2_subdev_format *fmt)
{}

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

static int ov9282_set_ctrl_hflip(struct ov9282 *ov9282, int value)
{}

static int ov9282_set_ctrl_vflip(struct ov9282 *ov9282, int value)
{}

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

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

/**
 * ov9282_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
 * @sd: pointer to ov9282 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 ov9282_enum_mbus_code(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_mbus_code_enum *code)
{}

/**
 * ov9282_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
 * @sd: pointer to ov9282 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 ov9282_enum_frame_size(struct v4l2_subdev *sd,
				  struct v4l2_subdev_state *sd_state,
				  struct v4l2_subdev_frame_size_enum *fsize)
{}

/**
 * ov9282_fill_pad_format() - Fill subdevice pad format
 *                            from selected sensor mode
 * @ov9282: pointer to ov9282 device
 * @mode: pointer to ov9282_mode sensor mode
 * @code: mbus code to be stored
 * @fmt: V4L2 sub-device format need to be filled
 */
static void ov9282_fill_pad_format(struct ov9282 *ov9282,
				   const struct ov9282_mode *mode,
				   u32 code,
				   struct v4l2_subdev_format *fmt)
{}

/**
 * ov9282_get_pad_format() - Get subdevice pad format
 * @sd: pointer to ov9282 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 ov9282_get_pad_format(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_format *fmt)
{}

/**
 * ov9282_set_pad_format() - Set subdevice pad format
 * @sd: pointer to ov9282 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 ov9282_set_pad_format(struct v4l2_subdev *sd,
				 struct v4l2_subdev_state *sd_state,
				 struct v4l2_subdev_format *fmt)
{}

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

static const struct v4l2_rect *
__ov9282_get_pad_crop(struct ov9282 *ov9282,
		      struct v4l2_subdev_state *sd_state,
		      unsigned int pad, enum v4l2_subdev_format_whence which)
{}

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

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

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

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

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

static int ov9282_configure_regulators(struct ov9282 *ov9282)
{}

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

/* V4l2 subdevice ops */
static const struct v4l2_subdev_core_ops ov9282_core_ops =;

static const struct v4l2_subdev_video_ops ov9282_video_ops =;

static const struct v4l2_subdev_pad_ops ov9282_pad_ops =;

static const struct v4l2_subdev_ops ov9282_subdev_ops =;

static const struct v4l2_subdev_internal_ops ov9282_internal_ops =;

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

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

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

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

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

static const struct dev_pm_ops ov9282_pm_ops =;

static const struct of_device_id ov9282_of_match[] =;

MODULE_DEVICE_TABLE(of, ov9282_of_match);

static struct i2c_driver ov9282_driver =;

module_i2c_driver();

MODULE_DESCRIPTION();
MODULE_LICENSE();