#include <linux/array_size.h>
#include <linux/bitops.h>
#include <linux/container_of.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <linux/units.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-mediabus.h>
#define IMX283_REG_CHIP_ID …
#define IMX283_CHIP_ID …
#define IMX283_REG_STANDBY …
#define IMX283_ACTIVE …
#define IMX283_STANDBY …
#define IMX283_STBLOGIC …
#define IMX283_STBMIPI …
#define IMX283_STBDV …
#define IMX283_SLEEP …
#define IMX283_REG_CLAMP …
#define IMX283_CLPSQRST …
#define IMX283_REG_PLSTMG08 …
#define IMX283_PLSTMG08_VAL …
#define IMX283_REG_MDSEL1 …
#define IMX283_REG_MDSEL2 …
#define IMX283_REG_MDSEL3 …
#define IMX283_MDSEL3_VCROP_EN …
#define IMX283_REG_MDSEL4 …
#define IMX283_MDSEL4_VCROP_EN …
#define IMX283_REG_SVR …
#define IMX283_REG_HTRIMMING …
#define IMX283_MDVREV …
#define IMX283_HTRIMMING_EN …
#define IMX283_REG_VWINPOS …
#define IMX283_REG_VWIDCUT …
#define IMX283_REG_MDSEL7 …
#define IMX283_REG_TCLKPOST …
#define IMX283_REG_THSPREPARE …
#define IMX283_REG_THSZERO …
#define IMX283_REG_THSTRAIL …
#define IMX283_REG_TCLKTRAIL …
#define IMX283_REG_TCLKPREPARE …
#define IMX283_REG_TCLKZERO …
#define IMX283_REG_TLPX …
#define IMX283_REG_THSEXIT …
#define IMX283_REG_TCLKPRE …
#define IMX283_REG_SYSMODE …
#define IMX283_REG_Y_OUT_SIZE …
#define IMX283_REG_WRITE_VSIZE …
#define IMX283_REG_OB_SIZE_V …
#define IMX283_REG_HMAX …
#define IMX283_HMAX_MAX …
#define IMX283_REG_VMAX …
#define IMX283_VMAX_MAX …
#define IMX283_REG_SHR …
#define IMX283_SHR_MIN …
#define IMX283_REG_ANALOG_GAIN …
#define IMX283_ANA_GAIN_MIN …
#define IMX283_ANA_GAIN_MAX …
#define IMX283_ANA_GAIN_STEP …
#define IMX283_ANA_GAIN_DEFAULT …
#define IMX283_REG_DIGITAL_GAIN …
#define IMX283_DGTL_GAIN_MIN …
#define IMX283_DGTL_GAIN_MAX …
#define IMX283_DGTL_GAIN_DEFAULT …
#define IMX283_DGTL_GAIN_STEP …
#define IMX283_REG_HTRIMMING_START …
#define IMX283_REG_HTRIMMING_END …
#define IMX283_REG_MDSEL18 …
#define IMX283_REG_XMSTA …
#define IMX283_XMSTA …
#define IMX283_REG_SYNCDRV …
#define IMX283_SYNCDRV_XHS_XVS …
#define IMX283_SYNCDRV_HIZ …
#define IMX283_REG_STBPL …
#define IMX283_STBPL_NORMAL …
#define IMX283_STBPL_STANDBY …
#define IMX283_REG_PLRD1 …
#define IMX283_REG_PLRD2 …
#define IMX283_REG_PLRD3 …
#define IMX283_REG_PLRD4 …
#define IMX283_REG_PLSTMG02 …
#define IMX283_PLSTMG02_VAL …
#define IMX283_REG_EBD_X_OUT_SIZE …
#define IMX283_REG_TPG_CTRL …
#define IMX283_TPG_CTRL_CLKEN …
#define IMX283_TPG_CTRL_PATEN …
#define IMX283_REG_TPG_PAT …
#define IMX283_TPG_PAT_ALL_000 …
#define IMX283_TPG_PAT_ALL_FFF …
#define IMX283_TPG_PAT_ALL_555 …
#define IMX283_TPG_PAT_ALL_AAA …
#define IMX283_TPG_PAT_H_COLOR_BARS …
#define IMX283_TPG_PAT_V_COLOR_BARS …
#define IMX283_EXPOSURE_MIN …
#define IMX283_EXPOSURE_STEP …
#define IMX283_EXPOSURE_DEFAULT …
#define IMX283_EXPOSURE_MAX …
#define IMAGE_PAD …
#define IMX283_XCLR_MIN_DELAY_US …
#define IMX283_XCLR_DELAY_RANGE_US …
static const struct v4l2_rect imx283_native_area = …;
static const struct v4l2_rect imx283_active_area = …;
struct imx283_reg_list { … };
struct imx283_mode { … };
struct imx283_input_frequency { … };
static const struct imx283_input_frequency imx283_frequencies[] = …;
enum imx283_modes { … };
struct imx283_readout_mode { … };
static const struct imx283_readout_mode imx283_readout_modes[] = …;
static const struct cci_reg_sequence mipi_data_rate_1440Mbps[] = …;
static const struct cci_reg_sequence mipi_data_rate_720Mbps[] = …;
static const s64 link_frequencies[] = …;
static const struct imx283_reg_list link_freq_reglist[] = …;
static const struct imx283_mode supported_modes_12bit[] = …;
static const struct imx283_mode supported_modes_10bit[] = …;
static const u32 imx283_mbus_codes[] = …;
static const char *const imx283_supply_name[] = …;
struct imx283 { … };
static inline struct imx283 *to_imx283(struct v4l2_subdev *sd)
{ … }
static inline void get_mode_table(unsigned int code,
const struct imx283_mode **mode_list,
unsigned int *num_modes)
{ … }
static u64 imx283_pixel_rate(struct imx283 *imx283,
const struct imx283_mode *mode)
{ … }
static u64 imx283_internal_clock(unsigned int pixel_rate, unsigned int pixels)
{ … }
static u64 imx283_iclk_to_pix(unsigned int pixel_rate, unsigned int cycles)
{ … }
static u32 imx283_exposure(struct imx283 *imx283,
const struct imx283_mode *mode, u64 shr)
{ … }
static void imx283_exposure_limits(struct imx283 *imx283,
const struct imx283_mode *mode,
s64 *min_exposure, s64 *max_exposure)
{ … }
static u32 imx283_shr(struct imx283 *imx283, const struct imx283_mode *mode,
u32 exposure)
{ … }
static const char * const imx283_tpg_menu[] = …;
static const int imx283_tpg_val[] = …;
static int imx283_update_test_pattern(struct imx283 *imx283, u32 pattern_index)
{ … }
static int imx283_set_ctrl(struct v4l2_ctrl *ctrl)
{ … }
static const struct v4l2_ctrl_ops imx283_ctrl_ops = …;
static int imx283_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_mbus_code_enum *code)
{ … }
static int imx283_enum_frame_size(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_frame_size_enum *fse)
{ … }
static void imx283_update_image_pad_format(struct imx283 *imx283,
const struct imx283_mode *mode,
struct v4l2_mbus_framefmt *format)
{ … }
static int imx283_init_state(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state)
{ … }
static void imx283_set_framing_limits(struct imx283 *imx283,
const struct imx283_mode *mode)
{ … }
static int imx283_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_format *fmt)
{ … }
static int imx283_standby_cancel(struct imx283 *imx283)
{ … }
static int imx283_start_streaming(struct imx283 *imx283,
struct v4l2_subdev_state *state)
{ … }
static int imx283_enable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state, u32 pad,
u64 streams_mask)
{ … }
static int imx283_disable_streams(struct v4l2_subdev *sd,
struct v4l2_subdev_state *state, u32 pad,
u64 streams_mask)
{ … }
static int imx283_power_on(struct imx283 *imx283)
{ … }
static int imx283_power_off(struct imx283 *imx283)
{ … }
static int imx283_runtime_resume(struct device *dev)
{ … }
static int imx283_runtime_suspend(struct device *dev)
{ … }
static int imx283_get_regulators(struct imx283 *imx283)
{ … }
static int imx283_identify_module(struct imx283 *imx283)
{ … }
static int imx283_get_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_state *sd_state,
struct v4l2_subdev_selection *sel)
{ … }
static const struct v4l2_subdev_core_ops imx283_core_ops = …;
static const struct v4l2_subdev_video_ops imx283_video_ops = …;
static const struct v4l2_subdev_pad_ops imx283_pad_ops = …;
static const struct v4l2_subdev_internal_ops imx283_internal_ops = …;
static const struct v4l2_subdev_ops imx283_subdev_ops = …;
static int imx283_init_controls(struct imx283 *imx283)
{ … }
static int imx283_parse_endpoint(struct imx283 *imx283)
{
struct fwnode_handle *fwnode;
struct v4l2_fwnode_endpoint bus_cfg = {
.bus_type = V4L2_MBUS_CSI2_DPHY
};
struct fwnode_handle *ep;
int ret;
fwnode = dev_fwnode(imx283->dev);
ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
if (!ep) {
dev_err(imx283->dev, "Failed to get next endpoint\n");
return -ENXIO;
}
ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
fwnode_handle_put(ep);
if (ret)
return ret;
if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) {
dev_err(imx283->dev,
"number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto done_endpoint_free;
}
ret = v4l2_link_freq_to_bitmap(imx283->dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
link_frequencies, ARRAY_SIZE(link_frequencies),
&imx283->link_freq_bitmap);
done_endpoint_free:
v4l2_fwnode_endpoint_free(&bus_cfg);
return ret;
};
static int imx283_probe(struct i2c_client *client)
{ … }
static void imx283_remove(struct i2c_client *client)
{ … }
static DEFINE_RUNTIME_DEV_PM_OPS(imx283_pm_ops, imx283_runtime_suspend,
imx283_runtime_resume, NULL);
static const struct of_device_id imx283_dt_ids[] = …;
MODULE_DEVICE_TABLE(of, imx283_dt_ids);
static struct i2c_driver imx283_i2c_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;