// SPDX-License-Identifier: GPL-2.0
/*
* imx214.c - imx214 sensor driver
*
* Copyright 2018 Qtechnology A/S
*
* Ricardo Ribalda <ricardo.ribalda@gmail.com>
*/
#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-fwnode.h>
#include <media/v4l2-subdev.h>
#define IMX214_DEFAULT_CLK_FREQ 24000000
#define IMX214_DEFAULT_LINK_FREQ 480000000
#define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
#define IMX214_FPS 30
#define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
static const char * const imx214_supply_name[] = {
"vdda",
"vddd",
"vdddo",
};
#define IMX214_NUM_SUPPLIES ARRAY_SIZE(imx214_supply_name)
struct imx214 {
struct device *dev;
struct clk *xclk;
struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
struct v4l2_mbus_framefmt fmt;
struct v4l2_rect crop;
struct v4l2_ctrl_handler ctrls;
struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *link_freq;
struct v4l2_ctrl *exposure;
struct regulator_bulk_data supplies[IMX214_NUM_SUPPLIES];
struct gpio_desc *enable_gpio;
/*
* Serialize control access, get/set format, get selection
* and start streaming.
*/
struct mutex mutex;
bool streaming;
};
struct reg_8 {
u16 addr;
u8 val;
};
enum {
IMX214_TABLE_WAIT_MS = 0,
IMX214_TABLE_END,
IMX214_MAX_RETRIES,
IMX214_WAIT_MS
};
/*From imx214_mode_tbls.h*/
static const struct reg_8 mode_4096x2304[] = {
{0x0114, 0x03},
{0x0220, 0x00},
{0x0221, 0x11},
{0x0222, 0x01},
{0x0340, 0x0C},
{0x0341, 0x7A},
{0x0342, 0x13},
{0x0343, 0x90},
{0x0344, 0x00},
{0x0345, 0x38},
{0x0346, 0x01},
{0x0347, 0x98},
{0x0348, 0x10},
{0x0349, 0x37},
{0x034A, 0x0A},
{0x034B, 0x97},
{0x0381, 0x01},
{0x0383, 0x01},
{0x0385, 0x01},
{0x0387, 0x01},
{0x0900, 0x00},
{0x0901, 0x00},
{0x0902, 0x00},
{0x3000, 0x35},
{0x3054, 0x01},
{0x305C, 0x11},
{0x0112, 0x0A},
{0x0113, 0x0A},
{0x034C, 0x10},
{0x034D, 0x00},
{0x034E, 0x09},
{0x034F, 0x00},
{0x0401, 0x00},
{0x0404, 0x00},
{0x0405, 0x10},
{0x0408, 0x00},
{0x0409, 0x00},
{0x040A, 0x00},
{0x040B, 0x00},
{0x040C, 0x10},
{0x040D, 0x00},
{0x040E, 0x09},
{0x040F, 0x00},
{0x0301, 0x05},
{0x0303, 0x02},
{0x0305, 0x03},
{0x0306, 0x00},
{0x0307, 0x96},
{0x0309, 0x0A},
{0x030B, 0x01},
{0x0310, 0x00},
{0x0820, 0x12},
{0x0821, 0xC0},
{0x0822, 0x00},
{0x0823, 0x00},
{0x3A03, 0x09},
{0x3A04, 0x50},
{0x3A05, 0x01},
{0x0B06, 0x01},
{0x30A2, 0x00},
{0x30B4, 0x00},
{0x3A02, 0xFF},
{0x3011, 0x00},
{0x3013, 0x01},
{0x0202, 0x0C},
{0x0203, 0x70},
{0x0224, 0x01},
{0x0225, 0xF4},
{0x0204, 0x00},
{0x0205, 0x00},
{0x020E, 0x01},
{0x020F, 0x00},
{0x0210, 0x01},
{0x0211, 0x00},
{0x0212, 0x01},
{0x0213, 0x00},
{0x0214, 0x01},
{0x0215, 0x00},
{0x0216, 0x00},
{0x0217, 0x00},
{0x4170, 0x00},
{0x4171, 0x10},
{0x4176, 0x00},
{0x4177, 0x3C},
{0xAE20, 0x04},
{0xAE21, 0x5C},
{IMX214_TABLE_WAIT_MS, 10},
{0x0138, 0x01},
{IMX214_TABLE_END, 0x00}
};
static const struct reg_8 mode_1920x1080[] = {
{0x0114, 0x03},
{0x0220