// 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 <manivannan.sadhasivam@linaro.org>
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>
#define IMX290_STANDBY 0x3000
#define IMX290_REGHOLD 0x3001
#define IMX290_XMSTA 0x3002
#define IMX290_FR_FDG_SEL 0x3009
#define IMX290_BLKLEVEL_LOW 0x300a
#define IMX290_BLKLEVEL_HIGH 0x300b
#define IMX290_GAIN 0x3014
#define IMX290_HMAX_LOW 0x301c
#define IMX290_HMAX_HIGH 0x301d
#define IMX290_PGCTRL 0x308c
#define IMX290_PHY_LANE_NUM 0x3407
#define IMX290_CSI_LANE_MODE 0x3443
#define IMX290_PGCTRL_REGEN BIT(0)
#define IMX290_PGCTRL_THRU BIT(1)
#define IMX290_PGCTRL_MODE(n) ((n) << 4)
static const char * const imx290_supply_name[] = {
"vdda",
"vddd",
"vdddo",
};
#define IMX290_NUM_SUPPLIES ARRAY_SIZE(imx290_supply_name)
struct imx290_regval {
u16 reg;
u8 val;
};
struct imx290_mode {
u32 width;
u32 height;
u32 hmax;
u8 link_freq_index;
const struct imx290_regval *data;
u32 data_size;
};
struct imx290 {
struct device *dev;
struct clk *xclk;
struct regmap *regmap;
u8 nlanes;
u8 bpp;
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_mbus_framefmt current_format;
const struct imx290_mode *current_mode;
struct regulator_bulk_data supplies[IMX290_NUM_SUPPLIES];
struct gpio_desc *rst_gpio;
struct v4l2_ctrl_handler ctrls;
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *pixel_rate;
struct mutex lock;
};
struct imx290_pixfmt {
u32 code;
u8 bpp;
};
static const struct imx290_pixfmt imx290_formats[] = {
{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
};
static const struct regmap_config imx290_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
};
static const char * const imx290_test_pattern_menu[] = {
"Disabled",
"Sequence Pattern 1",
"Horizontal Color-bar Chart",
"Vertical Color-bar Chart",
"Sequence Pattern 2",
"Gradation Pattern 1",
"Gradation Pattern 2",
"000/555h Toggle Pattern",
};
static const struct imx290_regval imx290_global_init_settings[] = {
{ 0x3007, 0x00 },
{ 0x3018, 0x65 },
{ 0x3019, 0x04 },
{ 0x301a, 0x00 },
{ 0x3444, 0x20 },
{ 0x3445, 0x25 },
{ 0x303a, 0x0c },
{ 0x3040, 0x00 },
{ 0x3041, 0x00 },
{ 0x303c, 0x00 },
{ 0x303d, 0x00 },
{ 0x3042, 0x9c },
{ 0x3043, 0x07 },
{ 0x303e, 0x49 },
{ 0x303f, 0x04 },
{ 0x304b, 0x0a },
{ 0x300f, 0x00 },
{ 0x3010, 0x21 },
{ 0x3012, 0x64 },
{ 0x3016, 0x09 },
{ 0x3070,