brintos

brintos / linux-shallow public Read only

0
0
Text · 80.4 KiB · 95ffe75 Raw
3178 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>4 * Copyright 2020 Bootlin5 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>6 */7 8#include <linux/clk.h>9#include <linux/delay.h>10#include <linux/device.h>11#include <linux/i2c.h>12#include <linux/mod_devicetable.h>13#include <linux/module.h>14#include <linux/of_graph.h>15#include <linux/pm_runtime.h>16#include <linux/regulator/consumer.h>17#include <linux/videodev2.h>18#include <media/v4l2-ctrls.h>19#include <media/v4l2-device.h>20#include <media/v4l2-fwnode.h>21#include <media/v4l2-image-sizes.h>22#include <media/v4l2-mediabus.h>23 24/* Register definitions */25 26/* System */27 28#define OV8865_SW_STANDBY_REG			0x10029#define OV8865_SW_STANDBY_STREAM_ON		BIT(0)30 31#define OV8865_SW_RESET_REG			0x10332#define OV8865_SW_RESET_RESET			BIT(0)33 34#define OV8865_PLL_CTRL0_REG			0x30035#define OV8865_PLL_CTRL0_PRE_DIV(v)		((v) & GENMASK(2, 0))36#define OV8865_PLL_CTRL1_REG			0x30137#define OV8865_PLL_CTRL1_MUL_H(v)		(((v) & GENMASK(9, 8)) >> 8)38#define OV8865_PLL_CTRL2_REG			0x30239#define OV8865_PLL_CTRL2_MUL_L(v)		((v) & GENMASK(7, 0))40#define OV8865_PLL_CTRL3_REG			0x30341#define OV8865_PLL_CTRL3_M_DIV(v)		(((v) - 1) & GENMASK(3, 0))42#define OV8865_PLL_CTRL4_REG			0x30443#define OV8865_PLL_CTRL4_MIPI_DIV(v)		((v) & GENMASK(1, 0))44#define OV8865_PLL_CTRL5_REG			0x30545#define OV8865_PLL_CTRL5_SYS_PRE_DIV(v)		((v) & GENMASK(1, 0))46#define OV8865_PLL_CTRL6_REG			0x30647#define OV8865_PLL_CTRL6_SYS_DIV(v)		(((v) - 1) & BIT(0))48 49#define OV8865_PLL_CTRL8_REG			0x30850#define OV8865_PLL_CTRL9_REG			0x30951#define OV8865_PLL_CTRLA_REG			0x30a52#define OV8865_PLL_CTRLA_PRE_DIV_HALF(v)	(((v) - 1) & BIT(0))53#define OV8865_PLL_CTRLB_REG			0x30b54#define OV8865_PLL_CTRLB_PRE_DIV(v)		((v) & GENMASK(2, 0))55#define OV8865_PLL_CTRLC_REG			0x30c56#define OV8865_PLL_CTRLC_MUL_H(v)		(((v) & GENMASK(9, 8)) >> 8)57#define OV8865_PLL_CTRLD_REG			0x30d58#define OV8865_PLL_CTRLD_MUL_L(v)		((v) & GENMASK(7, 0))59#define OV8865_PLL_CTRLE_REG			0x30e60#define OV8865_PLL_CTRLE_SYS_DIV(v)		((v) & GENMASK(2, 0))61#define OV8865_PLL_CTRLF_REG			0x30f62#define OV8865_PLL_CTRLF_SYS_PRE_DIV(v)		(((v) - 1) & GENMASK(3, 0))63#define OV8865_PLL_CTRL10_REG			0x31064#define OV8865_PLL_CTRL11_REG			0x31165#define OV8865_PLL_CTRL12_REG			0x31266#define OV8865_PLL_CTRL12_PRE_DIV_HALF(v)	((((v) - 1) << 4) & BIT(4))67#define OV8865_PLL_CTRL12_DAC_DIV(v)		(((v) - 1) & GENMASK(3, 0))68 69#define OV8865_PLL_CTRL1B_REG			0x31b70#define OV8865_PLL_CTRL1C_REG			0x31c71 72#define OV8865_PLL_CTRL1E_REG			0x31e73#define OV8865_PLL_CTRL1E_PLL1_NO_LAT		BIT(3)74 75#define OV8865_PAD_OEN0_REG			0x300076 77#define OV8865_PAD_OEN2_REG			0x300278 79#define OV8865_CLK_RST5_REG			0x300580 81#define OV8865_CHIP_ID_HH_REG			0x300a82#define OV8865_CHIP_ID_HH_VALUE			0x0083#define OV8865_CHIP_ID_H_REG			0x300b84#define OV8865_CHIP_ID_H_VALUE			0x8885#define OV8865_CHIP_ID_L_REG			0x300c86#define OV8865_CHIP_ID_L_VALUE			0x6587#define OV8865_PAD_OUT2_REG			0x300d88 89#define OV8865_PAD_SEL2_REG			0x301090#define OV8865_PAD_PK_REG			0x301191#define OV8865_PAD_PK_DRIVE_STRENGTH_1X		(0 << 5)92#define OV8865_PAD_PK_DRIVE_STRENGTH_2X		(1 << 5)93#define OV8865_PAD_PK_DRIVE_STRENGTH_3X		(2 << 5)94#define OV8865_PAD_PK_DRIVE_STRENGTH_4X		(3 << 5)95 96#define OV8865_PUMP_CLK_DIV_REG			0x301597#define OV8865_PUMP_CLK_DIV_PUMP_N(v)		(((v) << 4) & GENMASK(6, 4))98#define OV8865_PUMP_CLK_DIV_PUMP_P(v)		((v) & GENMASK(2, 0))99 100#define OV8865_MIPI_SC_CTRL0_REG		0x3018101#define OV8865_MIPI_SC_CTRL0_LANES(v)		((((v) - 1) << 5) & \102						 GENMASK(7, 5))103#define OV8865_MIPI_SC_CTRL0_MIPI_EN		BIT(4)104#define OV8865_MIPI_SC_CTRL0_UNKNOWN		BIT(1)105#define OV8865_MIPI_SC_CTRL0_LANES_PD_MIPI	BIT(0)106#define OV8865_MIPI_SC_CTRL1_REG		0x3019107#define OV8865_CLK_RST0_REG			0x301a108#define OV8865_CLK_RST1_REG			0x301b109#define OV8865_CLK_RST2_REG			0x301c110#define OV8865_CLK_RST3_REG			0x301d111#define OV8865_CLK_RST4_REG			0x301e112 113#define OV8865_PCLK_SEL_REG			0x3020114#define OV8865_PCLK_SEL_PCLK_DIV_MASK		BIT(3)115#define OV8865_PCLK_SEL_PCLK_DIV(v)		((((v) - 1) << 3) & BIT(3))116 117#define OV8865_MISC_CTRL_REG			0x3021118#define OV8865_MIPI_SC_CTRL2_REG		0x3022119#define OV8865_MIPI_SC_CTRL2_CLK_LANES_PD_MIPI	BIT(1)120#define OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC	BIT(0)121 122#define OV8865_MIPI_BIT_SEL_REG			0x3031123#define OV8865_MIPI_BIT_SEL(v)			(((v) << 0) & GENMASK(4, 0))124#define OV8865_CLK_SEL0_REG			0x3032125#define OV8865_CLK_SEL0_PLL1_SYS_SEL(v)		(((v) << 7) & BIT(7))126#define OV8865_CLK_SEL1_REG			0x3033127#define OV8865_CLK_SEL1_MIPI_EOF		BIT(5)128#define OV8865_CLK_SEL1_UNKNOWN			BIT(2)129#define OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK	BIT(1)130#define OV8865_CLK_SEL1_PLL_SCLK_SEL(v)		(((v) << 1) & BIT(1))131 132#define OV8865_SCLK_CTRL_REG			0x3106133#define OV8865_SCLK_CTRL_SCLK_DIV(v)		(((v) << 4) & GENMASK(7, 4))134#define OV8865_SCLK_CTRL_SCLK_PRE_DIV(v)	(((v) << 2) & GENMASK(3, 2))135#define OV8865_SCLK_CTRL_UNKNOWN		BIT(0)136 137/* Exposure/gain */138 139#define OV8865_EXPOSURE_CTRL_HH_REG		0x3500140#define OV8865_EXPOSURE_CTRL_HH(v)		(((v) & GENMASK(19, 16)) >> 16)141#define OV8865_EXPOSURE_CTRL_H_REG		0x3501142#define OV8865_EXPOSURE_CTRL_H(v)		(((v) & GENMASK(15, 8)) >> 8)143#define OV8865_EXPOSURE_CTRL_L_REG		0x3502144#define OV8865_EXPOSURE_CTRL_L(v)		((v) & GENMASK(7, 0))145#define OV8865_EXPOSURE_GAIN_MANUAL_REG		0x3503146#define OV8865_INTEGRATION_TIME_MARGIN		8147 148#define OV8865_GAIN_CTRL_H_REG			0x3508149#define OV8865_GAIN_CTRL_H(v)			(((v) & GENMASK(12, 8)) >> 8)150#define OV8865_GAIN_CTRL_L_REG			0x3509151#define OV8865_GAIN_CTRL_L(v)			((v) & GENMASK(7, 0))152 153/* Timing */154 155#define OV8865_CROP_START_X_H_REG		0x3800156#define OV8865_CROP_START_X_H(v)		(((v) & GENMASK(11, 8)) >> 8)157#define OV8865_CROP_START_X_L_REG		0x3801158#define OV8865_CROP_START_X_L(v)		((v) & GENMASK(7, 0))159#define OV8865_CROP_START_Y_H_REG		0x3802160#define OV8865_CROP_START_Y_H(v)		(((v) & GENMASK(11, 8)) >> 8)161#define OV8865_CROP_START_Y_L_REG		0x3803162#define OV8865_CROP_START_Y_L(v)		((v) & GENMASK(7, 0))163#define OV8865_CROP_END_X_H_REG			0x3804164#define OV8865_CROP_END_X_H(v)			(((v) & GENMASK(11, 8)) >> 8)165#define OV8865_CROP_END_X_L_REG			0x3805166#define OV8865_CROP_END_X_L(v)			((v) & GENMASK(7, 0))167#define OV8865_CROP_END_Y_H_REG			0x3806168#define OV8865_CROP_END_Y_H(v)			(((v) & GENMASK(11, 8)) >> 8)169#define OV8865_CROP_END_Y_L_REG			0x3807170#define OV8865_CROP_END_Y_L(v)			((v) & GENMASK(7, 0))171#define OV8865_OUTPUT_SIZE_X_H_REG		0x3808172#define OV8865_OUTPUT_SIZE_X_H(v)		(((v) & GENMASK(11, 8)) >> 8)173#define OV8865_OUTPUT_SIZE_X_L_REG		0x3809174#define OV8865_OUTPUT_SIZE_X_L(v)		((v) & GENMASK(7, 0))175#define OV8865_OUTPUT_SIZE_Y_H_REG		0x380a176#define OV8865_OUTPUT_SIZE_Y_H(v)		(((v) & GENMASK(11, 8)) >> 8)177#define OV8865_OUTPUT_SIZE_Y_L_REG		0x380b178#define OV8865_OUTPUT_SIZE_Y_L(v)		((v) & GENMASK(7, 0))179#define OV8865_HTS_H_REG			0x380c180#define OV8865_HTS_H(v)				(((v) & GENMASK(11, 8)) >> 8)181#define OV8865_HTS_L_REG			0x380d182#define OV8865_HTS_L(v)				((v) & GENMASK(7, 0))183#define OV8865_VTS_H_REG			0x380e184#define OV8865_VTS_H(v)				(((v) & GENMASK(11, 8)) >> 8)185#define OV8865_VTS_L_REG			0x380f186#define OV8865_VTS_L(v)				((v) & GENMASK(7, 0))187#define OV8865_TIMING_MAX_VTS			0xffff188#define OV8865_TIMING_MIN_VTS			0x04189#define OV8865_OFFSET_X_H_REG			0x3810190#define OV8865_OFFSET_X_H(v)			(((v) & GENMASK(15, 8)) >> 8)191#define OV8865_OFFSET_X_L_REG			0x3811192#define OV8865_OFFSET_X_L(v)			((v) & GENMASK(7, 0))193#define OV8865_OFFSET_Y_H_REG			0x3812194#define OV8865_OFFSET_Y_H(v)			(((v) & GENMASK(14, 8)) >> 8)195#define OV8865_OFFSET_Y_L_REG			0x3813196#define OV8865_OFFSET_Y_L(v)			((v) & GENMASK(7, 0))197#define OV8865_INC_X_ODD_REG			0x3814198#define OV8865_INC_X_ODD(v)			((v) & GENMASK(4, 0))199#define OV8865_INC_X_EVEN_REG			0x3815200#define OV8865_INC_X_EVEN(v)			((v) & GENMASK(4, 0))201#define OV8865_VSYNC_START_H_REG		0x3816202#define OV8865_VSYNC_START_H(v)			(((v) & GENMASK(15, 8)) >> 8)203#define OV8865_VSYNC_START_L_REG		0x3817204#define OV8865_VSYNC_START_L(v)			((v) & GENMASK(7, 0))205#define OV8865_VSYNC_END_H_REG			0x3818206#define OV8865_VSYNC_END_H(v)			(((v) & GENMASK(15, 8)) >> 8)207#define OV8865_VSYNC_END_L_REG			0x3819208#define OV8865_VSYNC_END_L(v)			((v) & GENMASK(7, 0))209#define OV8865_HSYNC_FIRST_H_REG		0x381a210#define OV8865_HSYNC_FIRST_H(v)			(((v) & GENMASK(15, 8)) >> 8)211#define OV8865_HSYNC_FIRST_L_REG		0x381b212#define OV8865_HSYNC_FIRST_L(v)			((v) & GENMASK(7, 0))213 214#define OV8865_FORMAT1_REG			0x3820215#define OV8865_FORMAT1_FLIP_VERT_ISP_EN		BIT(2)216#define OV8865_FORMAT1_FLIP_VERT_SENSOR_EN	BIT(1)217#define OV8865_FORMAT2_REG			0x3821218#define OV8865_FORMAT2_HSYNC_EN			BIT(6)219#define OV8865_FORMAT2_FST_VBIN_EN		BIT(5)220#define OV8865_FORMAT2_FST_HBIN_EN		BIT(4)221#define OV8865_FORMAT2_ISP_HORZ_VAR2_EN		BIT(3)222#define OV8865_FORMAT2_FLIP_HORZ_ISP_EN		BIT(2)223#define OV8865_FORMAT2_FLIP_HORZ_SENSOR_EN	BIT(1)224#define OV8865_FORMAT2_SYNC_HBIN_EN		BIT(0)225 226#define OV8865_INC_Y_ODD_REG			0x382a227#define OV8865_INC_Y_ODD(v)			((v) & GENMASK(4, 0))228#define OV8865_INC_Y_EVEN_REG			0x382b229#define OV8865_INC_Y_EVEN(v)			((v) & GENMASK(4, 0))230 231#define OV8865_ABLC_NUM_REG			0x3830232#define OV8865_ABLC_NUM(v)			((v) & GENMASK(4, 0))233 234#define OV8865_ZLINE_NUM_REG			0x3836235#define OV8865_ZLINE_NUM(v)			((v) & GENMASK(4, 0))236 237#define OV8865_AUTO_SIZE_CTRL_REG		0x3841238#define OV8865_AUTO_SIZE_CTRL_OFFSET_Y_REG	BIT(5)239#define OV8865_AUTO_SIZE_CTRL_OFFSET_X_REG	BIT(4)240#define OV8865_AUTO_SIZE_CTRL_CROP_END_Y_REG	BIT(3)241#define OV8865_AUTO_SIZE_CTRL_CROP_END_X_REG	BIT(2)242#define OV8865_AUTO_SIZE_CTRL_CROP_START_Y_REG	BIT(1)243#define OV8865_AUTO_SIZE_CTRL_CROP_START_X_REG	BIT(0)244#define OV8865_AUTO_SIZE_X_OFFSET_H_REG		0x3842245#define OV8865_AUTO_SIZE_X_OFFSET_L_REG		0x3843246#define OV8865_AUTO_SIZE_Y_OFFSET_H_REG		0x3844247#define OV8865_AUTO_SIZE_Y_OFFSET_L_REG		0x3845248#define OV8865_AUTO_SIZE_BOUNDARIES_REG		0x3846249#define OV8865_AUTO_SIZE_BOUNDARIES_Y(v)	(((v) << 4) & GENMASK(7, 4))250#define OV8865_AUTO_SIZE_BOUNDARIES_X(v)	((v) & GENMASK(3, 0))251 252/* PSRAM */253 254#define OV8865_PSRAM_CTRL8_REG			0x3f08255 256/* Black Level */257 258#define OV8865_BLC_CTRL0_REG			0x4000259#define OV8865_BLC_CTRL0_TRIG_RANGE_EN		BIT(7)260#define OV8865_BLC_CTRL0_TRIG_FORMAT_EN		BIT(6)261#define OV8865_BLC_CTRL0_TRIG_GAIN_EN		BIT(5)262#define OV8865_BLC_CTRL0_TRIG_EXPOSURE_EN	BIT(4)263#define OV8865_BLC_CTRL0_TRIG_MANUAL_EN		BIT(3)264#define OV8865_BLC_CTRL0_FREEZE_EN		BIT(2)265#define OV8865_BLC_CTRL0_ALWAYS_EN		BIT(1)266#define OV8865_BLC_CTRL0_FILTER_EN		BIT(0)267#define OV8865_BLC_CTRL1_REG			0x4001268#define OV8865_BLC_CTRL1_DITHER_EN		BIT(7)269#define OV8865_BLC_CTRL1_ZERO_LINE_DIFF_EN	BIT(6)270#define OV8865_BLC_CTRL1_COL_SHIFT_256		(0 << 4)271#define OV8865_BLC_CTRL1_COL_SHIFT_128		(1 << 4)272#define OV8865_BLC_CTRL1_COL_SHIFT_64		(2 << 4)273#define OV8865_BLC_CTRL1_COL_SHIFT_32		(3 << 4)274#define OV8865_BLC_CTRL1_OFFSET_LIMIT_EN	BIT(2)275#define OV8865_BLC_CTRL1_COLUMN_CANCEL_EN	BIT(1)276#define OV8865_BLC_CTRL2_REG			0x4002277#define OV8865_BLC_CTRL3_REG			0x4003278#define OV8865_BLC_CTRL4_REG			0x4004279#define OV8865_BLC_CTRL5_REG			0x4005280#define OV8865_BLC_CTRL6_REG			0x4006281#define OV8865_BLC_CTRL7_REG			0x4007282#define OV8865_BLC_CTRL8_REG			0x4008283#define OV8865_BLC_CTRL9_REG			0x4009284#define OV8865_BLC_CTRLA_REG			0x400a285#define OV8865_BLC_CTRLB_REG			0x400b286#define OV8865_BLC_CTRLC_REG			0x400c287#define OV8865_BLC_CTRLD_REG			0x400d288#define OV8865_BLC_CTRLD_OFFSET_TRIGGER(v)	((v) & GENMASK(7, 0))289 290#define OV8865_BLC_CTRL1F_REG			0x401f291#define OV8865_BLC_CTRL1F_RB_REVERSE		BIT(3)292#define OV8865_BLC_CTRL1F_INTERPOL_X_EN		BIT(2)293#define OV8865_BLC_CTRL1F_INTERPOL_Y_EN		BIT(1)294 295#define OV8865_BLC_ANCHOR_LEFT_START_H_REG	0x4020296#define OV8865_BLC_ANCHOR_LEFT_START_H(v)	(((v) & GENMASK(11, 8)) >> 8)297#define OV8865_BLC_ANCHOR_LEFT_START_L_REG	0x4021298#define OV8865_BLC_ANCHOR_LEFT_START_L(v)	((v) & GENMASK(7, 0))299#define OV8865_BLC_ANCHOR_LEFT_END_H_REG	0x4022300#define OV8865_BLC_ANCHOR_LEFT_END_H(v)		(((v) & GENMASK(11, 8)) >> 8)301#define OV8865_BLC_ANCHOR_LEFT_END_L_REG	0x4023302#define OV8865_BLC_ANCHOR_LEFT_END_L(v)		((v) & GENMASK(7, 0))303#define OV8865_BLC_ANCHOR_RIGHT_START_H_REG	0x4024304#define OV8865_BLC_ANCHOR_RIGHT_START_H(v)	(((v) & GENMASK(11, 8)) >> 8)305#define OV8865_BLC_ANCHOR_RIGHT_START_L_REG	0x4025306#define OV8865_BLC_ANCHOR_RIGHT_START_L(v)	((v) & GENMASK(7, 0))307#define OV8865_BLC_ANCHOR_RIGHT_END_H_REG	0x4026308#define OV8865_BLC_ANCHOR_RIGHT_END_H(v)	(((v) & GENMASK(11, 8)) >> 8)309#define OV8865_BLC_ANCHOR_RIGHT_END_L_REG	0x4027310#define OV8865_BLC_ANCHOR_RIGHT_END_L(v)	((v) & GENMASK(7, 0))311 312#define OV8865_BLC_TOP_ZLINE_START_REG		0x4028313#define OV8865_BLC_TOP_ZLINE_START(v)		((v) & GENMASK(5, 0))314#define OV8865_BLC_TOP_ZLINE_NUM_REG		0x4029315#define OV8865_BLC_TOP_ZLINE_NUM(v)		((v) & GENMASK(4, 0))316#define OV8865_BLC_TOP_BLKLINE_START_REG	0x402a317#define OV8865_BLC_TOP_BLKLINE_START(v)		((v) & GENMASK(5, 0))318#define OV8865_BLC_TOP_BLKLINE_NUM_REG		0x402b319#define OV8865_BLC_TOP_BLKLINE_NUM(v)		((v) & GENMASK(4, 0))320#define OV8865_BLC_BOT_ZLINE_START_REG		0x402c321#define OV8865_BLC_BOT_ZLINE_START(v)		((v) & GENMASK(5, 0))322#define OV8865_BLC_BOT_ZLINE_NUM_REG		0x402d323#define OV8865_BLC_BOT_ZLINE_NUM(v)		((v) & GENMASK(4, 0))324#define OV8865_BLC_BOT_BLKLINE_START_REG	0x402e325#define OV8865_BLC_BOT_BLKLINE_START(v)		((v) & GENMASK(5, 0))326#define OV8865_BLC_BOT_BLKLINE_NUM_REG		0x402f327#define OV8865_BLC_BOT_BLKLINE_NUM(v)		((v) & GENMASK(4, 0))328 329#define OV8865_BLC_OFFSET_LIMIT_REG		0x4034330#define OV8865_BLC_OFFSET_LIMIT(v)		((v) & GENMASK(7, 0))331 332/* VFIFO */333 334#define OV8865_VFIFO_READ_START_H_REG		0x4600335#define OV8865_VFIFO_READ_START_H(v)		(((v) & GENMASK(15, 8)) >> 8)336#define OV8865_VFIFO_READ_START_L_REG		0x4601337#define OV8865_VFIFO_READ_START_L(v)		((v) & GENMASK(7, 0))338 339/* MIPI */340 341#define OV8865_MIPI_CTRL0_REG			0x4800342#define OV8865_MIPI_CTRL1_REG			0x4801343#define OV8865_MIPI_CTRL2_REG			0x4802344#define OV8865_MIPI_CTRL3_REG			0x4803345#define OV8865_MIPI_CTRL4_REG			0x4804346#define OV8865_MIPI_CTRL5_REG			0x4805347#define OV8865_MIPI_CTRL6_REG			0x4806348#define OV8865_MIPI_CTRL7_REG			0x4807349#define OV8865_MIPI_CTRL8_REG			0x4808350 351#define OV8865_MIPI_FCNT_MAX_H_REG		0x4810352#define OV8865_MIPI_FCNT_MAX_L_REG		0x4811353 354#define OV8865_MIPI_CTRL13_REG			0x4813355#define OV8865_MIPI_CTRL14_REG			0x4814356#define OV8865_MIPI_CTRL15_REG			0x4815357#define OV8865_MIPI_EMBEDDED_DT_REG		0x4816358 359#define OV8865_MIPI_HS_ZERO_MIN_H_REG		0x4818360#define OV8865_MIPI_HS_ZERO_MIN_L_REG		0x4819361#define OV8865_MIPI_HS_TRAIL_MIN_H_REG		0x481a362#define OV8865_MIPI_HS_TRAIL_MIN_L_REG		0x481b363#define OV8865_MIPI_CLK_ZERO_MIN_H_REG		0x481c364#define OV8865_MIPI_CLK_ZERO_MIN_L_REG		0x481d365#define OV8865_MIPI_CLK_PREPARE_MAX_REG		0x481e366#define OV8865_MIPI_CLK_PREPARE_MIN_REG		0x481f367#define OV8865_MIPI_CLK_POST_MIN_H_REG		0x4820368#define OV8865_MIPI_CLK_POST_MIN_L_REG		0x4821369#define OV8865_MIPI_CLK_TRAIL_MIN_H_REG		0x4822370#define OV8865_MIPI_CLK_TRAIL_MIN_L_REG		0x4823371#define OV8865_MIPI_LPX_P_MIN_H_REG		0x4824372#define OV8865_MIPI_LPX_P_MIN_L_REG		0x4825373#define OV8865_MIPI_HS_PREPARE_MIN_REG		0x4826374#define OV8865_MIPI_HS_PREPARE_MAX_REG		0x4827375#define OV8865_MIPI_HS_EXIT_MIN_H_REG		0x4828376#define OV8865_MIPI_HS_EXIT_MIN_L_REG		0x4829377#define OV8865_MIPI_UI_HS_ZERO_MIN_REG		0x482a378#define OV8865_MIPI_UI_HS_TRAIL_MIN_REG		0x482b379#define OV8865_MIPI_UI_CLK_ZERO_MIN_REG		0x482c380#define OV8865_MIPI_UI_CLK_PREPARE_REG		0x482d381#define OV8865_MIPI_UI_CLK_POST_MIN_REG		0x482e382#define OV8865_MIPI_UI_CLK_TRAIL_MIN_REG	0x482f383#define OV8865_MIPI_UI_LPX_P_MIN_REG		0x4830384#define OV8865_MIPI_UI_HS_PREPARE_REG		0x4831385#define OV8865_MIPI_UI_HS_EXIT_MIN_REG		0x4832386#define OV8865_MIPI_PKT_START_SIZE_REG		0x4833387 388#define OV8865_MIPI_PCLK_PERIOD_REG		0x4837389#define OV8865_MIPI_LP_GPIO0_REG		0x4838390#define OV8865_MIPI_LP_GPIO1_REG		0x4839391 392#define OV8865_MIPI_CTRL3C_REG			0x483c393#define OV8865_MIPI_LP_GPIO4_REG		0x483d394 395#define OV8865_MIPI_CTRL4A_REG			0x484a396#define OV8865_MIPI_CTRL4B_REG			0x484b397#define OV8865_MIPI_CTRL4C_REG			0x484c398#define OV8865_MIPI_LANE_TEST_PATTERN_REG	0x484d399#define OV8865_MIPI_FRAME_END_DELAY_REG		0x484e400#define OV8865_MIPI_CLOCK_TEST_PATTERN_REG	0x484f401#define OV8865_MIPI_LANE_SEL01_REG		0x4850402#define OV8865_MIPI_LANE_SEL01_LANE0(v)		(((v) << 0) & GENMASK(2, 0))403#define OV8865_MIPI_LANE_SEL01_LANE1(v)		(((v) << 4) & GENMASK(6, 4))404#define OV8865_MIPI_LANE_SEL23_REG		0x4851405#define OV8865_MIPI_LANE_SEL23_LANE2(v)		(((v) << 0) & GENMASK(2, 0))406#define OV8865_MIPI_LANE_SEL23_LANE3(v)		(((v) << 4) & GENMASK(6, 4))407 408/* ISP */409 410#define OV8865_ISP_CTRL0_REG			0x5000411#define OV8865_ISP_CTRL0_LENC_EN		BIT(7)412#define OV8865_ISP_CTRL0_WHITE_BALANCE_EN	BIT(4)413#define OV8865_ISP_CTRL0_DPC_BLACK_EN		BIT(2)414#define OV8865_ISP_CTRL0_DPC_WHITE_EN		BIT(1)415#define OV8865_ISP_CTRL1_REG			0x5001416#define OV8865_ISP_CTRL1_BLC_EN			BIT(0)417#define OV8865_ISP_CTRL2_REG			0x5002418#define OV8865_ISP_CTRL2_DEBUG			BIT(3)419#define OV8865_ISP_CTRL2_VARIOPIXEL_EN		BIT(2)420#define OV8865_ISP_CTRL2_VSYNC_LATCH_EN		BIT(0)421#define OV8865_ISP_CTRL3_REG			0x5003422 423#define OV8865_ISP_GAIN_RED_H_REG		0x5018424#define OV8865_ISP_GAIN_RED_H(v)		(((v) & GENMASK(13, 6)) >> 6)425#define OV8865_ISP_GAIN_RED_L_REG		0x5019426#define OV8865_ISP_GAIN_RED_L(v)		((v) & GENMASK(5, 0))427#define OV8865_ISP_GAIN_GREEN_H_REG		0x501a428#define OV8865_ISP_GAIN_GREEN_H(v)		(((v) & GENMASK(13, 6)) >> 6)429#define OV8865_ISP_GAIN_GREEN_L_REG		0x501b430#define OV8865_ISP_GAIN_GREEN_L(v)		((v) & GENMASK(5, 0))431#define OV8865_ISP_GAIN_BLUE_H_REG		0x501c432#define OV8865_ISP_GAIN_BLUE_H(v)		(((v) & GENMASK(13, 6)) >> 6)433#define OV8865_ISP_GAIN_BLUE_L_REG		0x501d434#define OV8865_ISP_GAIN_BLUE_L(v)		((v) & GENMASK(5, 0))435 436/* VarioPixel */437 438#define OV8865_VAP_CTRL0_REG			0x5900439#define OV8865_VAP_CTRL1_REG			0x5901440#define OV8865_VAP_CTRL1_HSUB_COEF(v)		((((v) - 1) << 2) & \441						 GENMASK(3, 2))442#define OV8865_VAP_CTRL1_VSUB_COEF(v)		(((v) - 1) & GENMASK(1, 0))443 444/* Pre-DSP */445 446#define OV8865_PRE_CTRL0_REG			0x5e00447#define OV8865_PRE_CTRL0_PATTERN_EN		BIT(7)448#define OV8865_PRE_CTRL0_ROLLING_BAR_EN		BIT(6)449#define OV8865_PRE_CTRL0_TRANSPARENT_MODE	BIT(5)450#define OV8865_PRE_CTRL0_SQUARES_BW_MODE	BIT(4)451#define OV8865_PRE_CTRL0_PATTERN_COLOR_BARS	0452#define OV8865_PRE_CTRL0_PATTERN_RANDOM_DATA	1453#define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES	2454#define OV8865_PRE_CTRL0_PATTERN_BLACK		3455 456/* Pixel Array */457 458#define OV8865_NATIVE_WIDTH			3296459#define OV8865_NATIVE_HEIGHT			2528460#define OV8865_ACTIVE_START_LEFT		16461#define OV8865_ACTIVE_START_TOP			40462#define OV8865_ACTIVE_WIDTH			3264463#define OV8865_ACTIVE_HEIGHT			2448464 465/* Macros */466 467#define ov8865_subdev_sensor(s) \468	container_of(s, struct ov8865_sensor, subdev)469 470#define ov8865_ctrl_subdev(c) \471	(&container_of((c)->handler, struct ov8865_sensor, \472		       ctrls.handler)->subdev)473 474/* Data structures */475 476struct ov8865_register_value {477	u16 address;478	u8 value;479	unsigned int delay_ms;480};481 482/*483 * PLL1 Clock Tree:484 *485 * +-< EXTCLK486 * |487 * +-+ pll_pre_div_half (0x30a [0])488 *   |489 *   +-+ pll_pre_div (0x300 [2:0], special values:490 *     |              0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 4, 7: 8)491 *     +-+ pll_mul (0x301 [1:0], 0x302 [7:0])492 *       |493 *       +-+ m_div (0x303 [3:0])494 *       | |495 *       | +-> PHY_SCLK496 *       | |497 *       | +-+ mipi_div (0x304 [1:0], special values: 0: 4, 1: 5, 2: 6, 3: 8)498 *       |   |499 *       |   +-+ pclk_div (0x3020 [3])500 *       |     |501 *       |     +-> PCLK502 *       |503 *       +-+ sys_pre_div (0x305 [1:0], special values: 0: 3, 1: 4, 2: 5, 3: 6)504 *         |505 *         +-+ sys_div (0x306 [0])506 *           |507 *           +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)508 *             |509 *             +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)510 *               |511 *               +-+ sclk_pre_div (0x3106 [3:2], special values:512 *                 |               0: 1, 1: 2, 2: 4, 3: 1)513 *                 |514 *                 +-+ sclk_div (0x3106 [7:4], special values: 0: 1)515 *                   |516 *                   +-> SCLK517 */518 519struct ov8865_pll1_config {520	unsigned int pll_pre_div_half;521	unsigned int pll_pre_div;522	unsigned int pll_mul;523	unsigned int m_div;524	unsigned int mipi_div;525	unsigned int pclk_div;526	unsigned int sys_pre_div;527	unsigned int sys_div;528};529 530/*531 * PLL2 Clock Tree:532 *533 * +-< EXTCLK534 * |535 * +-+ pll_pre_div_half (0x312 [4])536 *   |537 *   +-+ pll_pre_div (0x30b [2:0], special values:538 *     |              0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 4, 7: 8)539 *     +-+ pll_mul (0x30c [1:0], 0x30d [7:0])540 *       |541 *       +-+ dac_div (0x312 [3:0])542 *       | |543 *       | +-> DAC_CLK544 *       |545 *       +-+ sys_pre_div (0x30f [3:0])546 *         |547 *         +-+ sys_div (0x30e [2:0], special values:548 *           |          0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 3.5, 6: 4, 7:5)549 *           |550 *           +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)551 *             |552 *             +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)553 *               |554 *               +-+ sclk_pre_div (0x3106 [3:2], special values:555 *                 |               0: 1, 1: 2, 2: 4, 3: 1)556 *                 |557 *                 +-+ sclk_div (0x3106 [7:4], special values: 0: 1)558 *                   |559 *                   +-> SCLK560 */561 562struct ov8865_pll2_config {563	unsigned int pll_pre_div_half;564	unsigned int pll_pre_div;565	unsigned int pll_mul;566	unsigned int dac_div;567	unsigned int sys_pre_div;568	unsigned int sys_div;569};570 571struct ov8865_sclk_config {572	unsigned int sys_sel;573	unsigned int sclk_sel;574	unsigned int sclk_pre_div;575	unsigned int sclk_div;576};577 578struct ov8865_pll_configs {579	const struct ov8865_pll1_config *pll1_config;580	const struct ov8865_pll2_config *pll2_config_native;581	const struct ov8865_pll2_config *pll2_config_binning;582};583 584/* Clock rate */585 586enum extclk_rate {587	OV8865_19_2_MHZ,588	OV8865_24_MHZ,589	OV8865_NUM_SUPPORTED_RATES590};591 592static const unsigned long supported_extclk_rates[] = {593	[OV8865_19_2_MHZ] = 19200000,594	[OV8865_24_MHZ] = 24000000,595};596 597/*598 * General formulas for (array-centered) mode calculation:599 * - photo_array_width = 3296600 * - crop_start_x = (photo_array_width - output_size_x) / 2601 * - crop_end_x = crop_start_x + offset_x + output_size_x - 1602 *603 * - photo_array_height = 2480604 * - crop_start_y = (photo_array_height - output_size_y) / 2605 * - crop_end_y = crop_start_y + offset_y + output_size_y - 1606 */607 608struct ov8865_mode {609	unsigned int crop_start_x;610	unsigned int offset_x;611	unsigned int output_size_x;612	unsigned int crop_end_x;613	unsigned int hts;614 615	unsigned int crop_start_y;616	unsigned int offset_y;617	unsigned int output_size_y;618	unsigned int crop_end_y;619	unsigned int vts;620 621	/* With auto size, only output and total sizes need to be set. */622	bool size_auto;623	unsigned int size_auto_boundary_x;624	unsigned int size_auto_boundary_y;625 626	bool binning_x;627	bool binning_y;628	bool variopixel;629	unsigned int variopixel_hsub_coef;630	unsigned int variopixel_vsub_coef;631 632	/* Bits for the format register, used for binning. */633	bool sync_hbin;634	bool horz_var2;635 636	unsigned int inc_x_odd;637	unsigned int inc_x_even;638	unsigned int inc_y_odd;639	unsigned int inc_y_even;640 641	unsigned int vfifo_read_start;642 643	unsigned int ablc_num;644	unsigned int zline_num;645 646	unsigned int blc_top_zero_line_start;647	unsigned int blc_top_zero_line_num;648	unsigned int blc_top_black_line_start;649	unsigned int blc_top_black_line_num;650 651	unsigned int blc_bottom_zero_line_start;652	unsigned int blc_bottom_zero_line_num;653	unsigned int blc_bottom_black_line_start;654	unsigned int blc_bottom_black_line_num;655 656	u8 blc_col_shift_mask;657 658	unsigned int blc_anchor_left_start;659	unsigned int blc_anchor_left_end;660	unsigned int blc_anchor_right_start;661	unsigned int blc_anchor_right_end;662 663	bool pll2_binning;664 665	const struct ov8865_register_value *register_values;666	unsigned int register_values_count;667};668 669struct ov8865_state {670	const struct ov8865_mode *mode;671	u32 mbus_code;672 673	bool streaming;674};675 676struct ov8865_ctrls {677	struct v4l2_ctrl *link_freq;678	struct v4l2_ctrl *pixel_rate;679	struct v4l2_ctrl *hblank;680	struct v4l2_ctrl *vblank;681	struct v4l2_ctrl *exposure;682 683	struct v4l2_ctrl_handler handler;684};685 686struct ov8865_sensor {687	struct device *dev;688	struct i2c_client *i2c_client;689	struct gpio_desc *reset;690	struct gpio_desc *powerdown;691	struct regulator *avdd;692	struct regulator *dvdd;693	struct regulator *dovdd;694 695	unsigned long extclk_rate;696	const struct ov8865_pll_configs *pll_configs;697	struct clk *extclk;698 699	struct v4l2_fwnode_endpoint endpoint;700	struct v4l2_subdev subdev;701	struct media_pad pad;702 703	struct mutex mutex;704 705	struct ov8865_state state;706	struct ov8865_ctrls ctrls;707};708 709/* Static definitions */710 711/*712 * PHY_SCLK = 720 MHz713 * MIPI_PCLK = 90 MHz714 */715 716static const struct ov8865_pll1_config ov8865_pll1_config_native_19_2mhz = {717		.pll_pre_div_half	= 1,718		.pll_pre_div		= 2,719		.pll_mul		= 75,720		.m_div			= 1,721		.mipi_div		= 3,722		.pclk_div		= 1,723		.sys_pre_div		= 1,724		.sys_div		= 2,725};726 727static const struct ov8865_pll1_config ov8865_pll1_config_native_24mhz = {728		.pll_pre_div_half	= 1,729		.pll_pre_div		= 0,730		.pll_mul		= 30,731		.m_div			= 1,732		.mipi_div		= 3,733		.pclk_div		= 1,734		.sys_pre_div		= 1,735		.sys_div		= 2,736};737 738/*739 * DAC_CLK = 360 MHz740 * SCLK = 144 MHz741 */742 743static const struct ov8865_pll2_config ov8865_pll2_config_native_19_2mhz = {744		.pll_pre_div_half	= 1,745		.pll_pre_div		= 5,746		.pll_mul		= 75,747		.dac_div		= 1,748		.sys_pre_div		= 1,749		.sys_div		= 3,750};751 752static const struct ov8865_pll2_config ov8865_pll2_config_native_24mhz = {753		.pll_pre_div_half	= 1,754		.pll_pre_div		= 0,755		.pll_mul		= 30,756		.dac_div		= 2,757		.sys_pre_div		= 5,758		.sys_div		= 0,759};760 761/*762 * DAC_CLK = 360 MHz763 * SCLK = 72 MHz764 */765 766static const struct ov8865_pll2_config ov8865_pll2_config_binning_19_2mhz = {767	.pll_pre_div_half	= 1,768	.pll_pre_div		= 2,769	.pll_mul		= 75,770	.dac_div		= 2,771	.sys_pre_div		= 10,772	.sys_div		= 0,773};774 775static const struct ov8865_pll2_config ov8865_pll2_config_binning_24mhz = {776	.pll_pre_div_half	= 1,777	.pll_pre_div		= 0,778	.pll_mul		= 30,779	.dac_div		= 2,780	.sys_pre_div		= 10,781	.sys_div		= 0,782};783 784static const struct ov8865_pll_configs ov8865_pll_configs_19_2mhz = {785	.pll1_config = &ov8865_pll1_config_native_19_2mhz,786	.pll2_config_native = &ov8865_pll2_config_native_19_2mhz,787	.pll2_config_binning = &ov8865_pll2_config_binning_19_2mhz,788};789 790static const struct ov8865_pll_configs ov8865_pll_configs_24mhz = {791	.pll1_config = &ov8865_pll1_config_native_24mhz,792	.pll2_config_native = &ov8865_pll2_config_native_24mhz,793	.pll2_config_binning = &ov8865_pll2_config_binning_24mhz,794};795 796static const struct ov8865_pll_configs *ov8865_pll_configs[] = {797	&ov8865_pll_configs_19_2mhz,798	&ov8865_pll_configs_24mhz,799};800 801static const struct ov8865_sclk_config ov8865_sclk_config_native = {802	.sys_sel		= 1,803	.sclk_sel		= 0,804	.sclk_pre_div		= 0,805	.sclk_div		= 0,806};807 808static const struct ov8865_register_value ov8865_register_values_native[] = {809	/* Sensor */810 811	{ 0x3700, 0x48 },812	{ 0x3701, 0x18 },813	{ 0x3702, 0x50 },814	{ 0x3703, 0x32 },815	{ 0x3704, 0x28 },816	{ 0x3706, 0x70 },817	{ 0x3707, 0x08 },818	{ 0x3708, 0x48 },819	{ 0x3709, 0x80 },820	{ 0x370a, 0x01 },821	{ 0x370b, 0x70 },822	{ 0x370c, 0x07 },823	{ 0x3718, 0x14 },824	{ 0x3712, 0x44 },825	{ 0x371e, 0x31 },826	{ 0x371f, 0x7f },827	{ 0x3720, 0x0a },828	{ 0x3721, 0x0a },829	{ 0x3724, 0x04 },830	{ 0x3725, 0x04 },831	{ 0x3726, 0x0c },832	{ 0x3728, 0x0a },833	{ 0x3729, 0x03 },834	{ 0x372a, 0x06 },835	{ 0x372b, 0xa6 },836	{ 0x372c, 0xa6 },837	{ 0x372d, 0xa6 },838	{ 0x372e, 0x0c },839	{ 0x372f, 0x20 },840	{ 0x3730, 0x02 },841	{ 0x3731, 0x0c },842	{ 0x3732, 0x28 },843	{ 0x3736, 0x30 },844	{ 0x373a, 0x04 },845	{ 0x373b, 0x18 },846	{ 0x373c, 0x14 },847	{ 0x373e, 0x06 },848	{ 0x375a, 0x0c },849	{ 0x375b, 0x26 },850	{ 0x375d, 0x04 },851	{ 0x375f, 0x28 },852	{ 0x3767, 0x1e },853	{ 0x3772, 0x46 },854	{ 0x3773, 0x04 },855	{ 0x3774, 0x2c },856	{ 0x3775, 0x13 },857	{ 0x3776, 0x10 },858	{ 0x37a0, 0x88 },859	{ 0x37a1, 0x7a },860	{ 0x37a2, 0x7a },861	{ 0x37a3, 0x02 },862	{ 0x37a5, 0x09 },863	{ 0x37a7, 0x88 },864	{ 0x37a8, 0xb0 },865	{ 0x37a9, 0xb0 },866	{ 0x37aa, 0x88 },867	{ 0x37ab, 0x5c },868	{ 0x37ac, 0x5c },869	{ 0x37ad, 0x55 },870	{ 0x37ae, 0x19 },871	{ 0x37af, 0x19 },872	{ 0x37b3, 0x84 },873	{ 0x37b4, 0x84 },874	{ 0x37b5, 0x66 },875 876	/* PSRAM */877 878	{ OV8865_PSRAM_CTRL8_REG, 0x16 },879 880	/* ADC Sync */881 882	{ 0x4500, 0x68 },883};884 885static const struct ov8865_register_value ov8865_register_values_binning[] = {886	/* Sensor */887 888	{ 0x3700, 0x24 },889	{ 0x3701, 0x0c },890	{ 0x3702, 0x28 },891	{ 0x3703, 0x19 },892	{ 0x3704, 0x14 },893	{ 0x3706, 0x38 },894	{ 0x3707, 0x04 },895	{ 0x3708, 0x24 },896	{ 0x3709, 0x40 },897	{ 0x370a, 0x00 },898	{ 0x370b, 0xb8 },899	{ 0x370c, 0x04 },900	{ 0x3718, 0x12 },901	{ 0x3712, 0x42 },902	{ 0x371e, 0x19 },903	{ 0x371f, 0x40 },904	{ 0x3720, 0x05 },905	{ 0x3721, 0x05 },906	{ 0x3724, 0x02 },907	{ 0x3725, 0x02 },908	{ 0x3726, 0x06 },909	{ 0x3728, 0x05 },910	{ 0x3729, 0x02 },911	{ 0x372a, 0x03 },912	{ 0x372b, 0x53 },913	{ 0x372c, 0xa3 },914	{ 0x372d, 0x53 },915	{ 0x372e, 0x06 },916	{ 0x372f, 0x10 },917	{ 0x3730, 0x01 },918	{ 0x3731, 0x06 },919	{ 0x3732, 0x14 },920	{ 0x3736, 0x20 },921	{ 0x373a, 0x02 },922	{ 0x373b, 0x0c },923	{ 0x373c, 0x0a },924	{ 0x373e, 0x03 },925	{ 0x375a, 0x06 },926	{ 0x375b, 0x13 },927	{ 0x375d, 0x02 },928	{ 0x375f, 0x14 },929	{ 0x3767, 0x1c },930	{ 0x3772, 0x23 },931	{ 0x3773, 0x02 },932	{ 0x3774, 0x16 },933	{ 0x3775, 0x12 },934	{ 0x3776, 0x08 },935	{ 0x37a0, 0x44 },936	{ 0x37a1, 0x3d },937	{ 0x37a2, 0x3d },938	{ 0x37a3, 0x01 },939	{ 0x37a5, 0x08 },940	{ 0x37a7, 0x44 },941	{ 0x37a8, 0x58 },942	{ 0x37a9, 0x58 },943	{ 0x37aa, 0x44 },944	{ 0x37ab, 0x2e },945	{ 0x37ac, 0x2e },946	{ 0x37ad, 0x33 },947	{ 0x37ae, 0x0d },948	{ 0x37af, 0x0d },949	{ 0x37b3, 0x42 },950	{ 0x37b4, 0x42 },951	{ 0x37b5, 0x33 },952 953	/* PSRAM */954 955	{ OV8865_PSRAM_CTRL8_REG, 0x0b },956 957	/* ADC Sync */958 959	{ 0x4500, 0x40 },960};961 962static const struct ov8865_mode ov8865_modes[] = {963	/* 3264x2448 */964	{965		/* Horizontal */966		.output_size_x			= 3264,967		.hts				= 3888,968 969		/* Vertical */970		.output_size_y			= 2448,971		.vts				= 2470,972 973		.size_auto			= true,974		.size_auto_boundary_x		= 8,975		.size_auto_boundary_y		= 4,976 977		/* Subsample increase */978		.inc_x_odd			= 1,979		.inc_x_even			= 1,980		.inc_y_odd			= 1,981		.inc_y_even			= 1,982 983		/* VFIFO */984		.vfifo_read_start		= 16,985 986		.ablc_num			= 4,987		.zline_num			= 1,988 989		/* Black Level */990 991		.blc_top_zero_line_start	= 0,992		.blc_top_zero_line_num		= 2,993		.blc_top_black_line_start	= 4,994		.blc_top_black_line_num		= 4,995 996		.blc_bottom_zero_line_start	= 2,997		.blc_bottom_zero_line_num	= 2,998		.blc_bottom_black_line_start	= 8,999		.blc_bottom_black_line_num	= 2,1000 1001		.blc_anchor_left_start		= 576,1002		.blc_anchor_left_end		= 831,1003		.blc_anchor_right_start		= 1984,1004		.blc_anchor_right_end		= 2239,1005 1006		/* PLL */1007		.pll2_binning			= false,1008 1009		/* Registers */1010		.register_values	= ov8865_register_values_native,1011		.register_values_count	=1012			ARRAY_SIZE(ov8865_register_values_native),1013	},1014	/* 3264x1836 */1015	{1016		/* Horizontal */1017		.output_size_x			= 3264,1018		.hts				= 3888,1019 1020		/* Vertical */1021		.output_size_y			= 1836,1022		.vts				= 2470,1023 1024		.size_auto			= true,1025		.size_auto_boundary_x		= 8,1026		.size_auto_boundary_y		= 4,1027 1028		/* Subsample increase */1029		.inc_x_odd			= 1,1030		.inc_x_even			= 1,1031		.inc_y_odd			= 1,1032		.inc_y_even			= 1,1033 1034		/* VFIFO */1035		.vfifo_read_start		= 16,1036 1037		.ablc_num			= 4,1038		.zline_num			= 1,1039 1040		/* Black Level */1041 1042		.blc_top_zero_line_start	= 0,1043		.blc_top_zero_line_num		= 2,1044		.blc_top_black_line_start	= 4,1045		.blc_top_black_line_num		= 4,1046 1047		.blc_bottom_zero_line_start	= 2,1048		.blc_bottom_zero_line_num	= 2,1049		.blc_bottom_black_line_start	= 8,1050		.blc_bottom_black_line_num	= 2,1051 1052		.blc_anchor_left_start		= 576,1053		.blc_anchor_left_end		= 831,1054		.blc_anchor_right_start		= 1984,1055		.blc_anchor_right_end		= 2239,1056 1057		/* PLL */1058		.pll2_binning			= false,1059 1060		/* Registers */1061		.register_values	= ov8865_register_values_native,1062		.register_values_count	=1063			ARRAY_SIZE(ov8865_register_values_native),1064	},1065	/* 1632x1224 */1066	{1067		/* Horizontal */1068		.output_size_x			= 1632,1069		.hts				= 1923,1070 1071		/* Vertical */1072		.output_size_y			= 1224,1073		.vts				= 1248,1074 1075		.size_auto			= true,1076		.size_auto_boundary_x		= 8,1077		.size_auto_boundary_y		= 8,1078 1079		/* Subsample increase */1080		.inc_x_odd			= 3,1081		.inc_x_even			= 1,1082		.inc_y_odd			= 3,1083		.inc_y_even			= 1,1084 1085		/* Binning */1086		.binning_y			= true,1087		.sync_hbin			= true,1088 1089		/* VFIFO */1090		.vfifo_read_start		= 116,1091 1092		.ablc_num			= 8,1093		.zline_num			= 2,1094 1095		/* Black Level */1096 1097		.blc_top_zero_line_start	= 0,1098		.blc_top_zero_line_num		= 2,1099		.blc_top_black_line_start	= 4,1100		.blc_top_black_line_num		= 4,1101 1102		.blc_bottom_zero_line_start	= 2,1103		.blc_bottom_zero_line_num	= 2,1104		.blc_bottom_black_line_start	= 8,1105		.blc_bottom_black_line_num	= 2,1106 1107		.blc_anchor_left_start		= 288,1108		.blc_anchor_left_end		= 415,1109		.blc_anchor_right_start		= 992,1110		.blc_anchor_right_end		= 1119,1111 1112		/* PLL */1113		.pll2_binning			= true,1114 1115		/* Registers */1116		.register_values	= ov8865_register_values_binning,1117		.register_values_count	=1118			ARRAY_SIZE(ov8865_register_values_binning),1119	},1120	/* 800x600 (SVGA) */1121	{1122		/* Horizontal */1123		.output_size_x			= 800,1124		.hts				= 1250,1125 1126		/* Vertical */1127		.output_size_y			= 600,1128		.vts				= 640,1129 1130		.size_auto			= true,1131		.size_auto_boundary_x		= 8,1132		.size_auto_boundary_y		= 8,1133 1134		/* Subsample increase */1135		.inc_x_odd			= 3,1136		.inc_x_even			= 1,1137		.inc_y_odd			= 5,1138		.inc_y_even			= 3,1139 1140		/* Binning */1141		.binning_y			= true,1142		.variopixel			= true,1143		.variopixel_hsub_coef		= 2,1144		.variopixel_vsub_coef		= 1,1145		.sync_hbin			= true,1146		.horz_var2			= true,1147 1148		/* VFIFO */1149		.vfifo_read_start		= 80,1150 1151		.ablc_num			= 8,1152		.zline_num			= 2,1153 1154		/* Black Level */1155 1156		.blc_top_zero_line_start	= 0,1157		.blc_top_zero_line_num		= 2,1158		.blc_top_black_line_start	= 2,1159		.blc_top_black_line_num		= 2,1160 1161		.blc_bottom_zero_line_start	= 0,1162		.blc_bottom_zero_line_num	= 0,1163		.blc_bottom_black_line_start	= 4,1164		.blc_bottom_black_line_num	= 2,1165 1166		.blc_col_shift_mask	= OV8865_BLC_CTRL1_COL_SHIFT_128,1167 1168		.blc_anchor_left_start		= 288,1169		.blc_anchor_left_end		= 415,1170		.blc_anchor_right_start		= 992,1171		.blc_anchor_right_end		= 1119,1172 1173		/* PLL */1174		.pll2_binning			= true,1175 1176		/* Registers */1177		.register_values	= ov8865_register_values_binning,1178		.register_values_count	=1179			ARRAY_SIZE(ov8865_register_values_binning),1180	},1181};1182 1183static const u32 ov8865_mbus_codes[] = {1184	MEDIA_BUS_FMT_SBGGR10_1X10,1185};1186 1187static const struct ov8865_register_value ov8865_init_sequence[] = {1188	/* Analog */1189 1190	{ 0x3604, 0x04 },1191	{ 0x3602, 0x30 },1192	{ 0x3605, 0x00 },1193	{ 0x3607, 0x20 },1194	{ 0x3608, 0x11 },1195	{ 0x3609, 0x68 },1196	{ 0x360a, 0x40 },1197	{ 0x360c, 0xdd },1198	{ 0x360e, 0x0c },1199	{ 0x3610, 0x07 },1200	{ 0x3612, 0x86 },1201	{ 0x3613, 0x58 },1202	{ 0x3614, 0x28 },1203	{ 0x3617, 0x40 },1204	{ 0x3618, 0x5a },1205	{ 0x3619, 0x9b },1206	{ 0x361c, 0x00 },1207	{ 0x361d, 0x60 },1208	{ 0x3631, 0x60 },1209	{ 0x3633, 0x10 },1210	{ 0x3634, 0x10 },1211	{ 0x3635, 0x10 },1212	{ 0x3636, 0x10 },1213	{ 0x3638, 0xff },1214	{ 0x3641, 0x55 },1215	{ 0x3646, 0x86 },1216	{ 0x3647, 0x27 },1217	{ 0x364a, 0x1b },1218 1219	/* Sensor */1220 1221	{ 0x3700, 0x24 },1222	{ 0x3701, 0x0c },1223	{ 0x3702, 0x28 },1224	{ 0x3703, 0x19 },1225	{ 0x3704, 0x14 },1226	{ 0x3705, 0x00 },1227	{ 0x3706, 0x38 },1228	{ 0x3707, 0x04 },1229	{ 0x3708, 0x24 },1230	{ 0x3709, 0x40 },1231	{ 0x370a, 0x00 },1232	{ 0x370b, 0xb8 },1233	{ 0x370c, 0x04 },1234	{ 0x3718, 0x12 },1235	{ 0x3719, 0x31 },1236	{ 0x3712, 0x42 },1237	{ 0x3714, 0x12 },1238	{ 0x371e, 0x19 },1239	{ 0x371f, 0x40 },1240	{ 0x3720, 0x05 },1241	{ 0x3721, 0x05 },1242	{ 0x3724, 0x02 },1243	{ 0x3725, 0x02 },1244	{ 0x3726, 0x06 },1245	{ 0x3728, 0x05 },1246	{ 0x3729, 0x02 },1247	{ 0x372a, 0x03 },1248	{ 0x372b, 0x53 },1249	{ 0x372c, 0xa3 },1250	{ 0x372d, 0x53 },1251	{ 0x372e, 0x06 },1252	{ 0x372f, 0x10 },1253	{ 0x3730, 0x01 },1254	{ 0x3731, 0x06 },1255	{ 0x3732, 0x14 },1256	{ 0x3733, 0x10 },1257	{ 0x3734, 0x40 },1258	{ 0x3736, 0x20 },1259	{ 0x373a, 0x02 },1260	{ 0x373b, 0x0c },1261	{ 0x373c, 0x0a },1262	{ 0x373e, 0x03 },1263	{ 0x3755, 0x40 },1264	{ 0x3758, 0x00 },1265	{ 0x3759, 0x4c },1266	{ 0x375a, 0x06 },1267	{ 0x375b, 0x13 },1268	{ 0x375c, 0x40 },1269	{ 0x375d, 0x02 },1270	{ 0x375e, 0x00 },1271	{ 0x375f, 0x14 },1272	{ 0x3767, 0x1c },1273	{ 0x3768, 0x04 },1274	{ 0x3769, 0x20 },1275	{ 0x376c, 0xc0 },1276	{ 0x376d, 0xc0 },1277	{ 0x376a, 0x08 },1278	{ 0x3761, 0x00 },1279	{ 0x3762, 0x00 },1280	{ 0x3763, 0x00 },1281	{ 0x3766, 0xff },1282	{ 0x376b, 0x42 },1283	{ 0x3772, 0x23 },1284	{ 0x3773, 0x02 },1285	{ 0x3774, 0x16 },1286	{ 0x3775, 0x12 },1287	{ 0x3776, 0x08 },1288	{ 0x37a0, 0x44 },1289	{ 0x37a1, 0x3d },1290	{ 0x37a2, 0x3d },1291	{ 0x37a3, 0x01 },1292	{ 0x37a4, 0x00 },1293	{ 0x37a5, 0x08 },1294	{ 0x37a6, 0x00 },1295	{ 0x37a7, 0x44 },1296	{ 0x37a8, 0x58 },1297	{ 0x37a9, 0x58 },1298	{ 0x3760, 0x00 },1299	{ 0x376f, 0x01 },1300	{ 0x37aa, 0x44 },1301	{ 0x37ab, 0x2e },1302	{ 0x37ac, 0x2e },1303	{ 0x37ad, 0x33 },1304	{ 0x37ae, 0x0d },1305	{ 0x37af, 0x0d },1306	{ 0x37b0, 0x00 },1307	{ 0x37b1, 0x00 },1308	{ 0x37b2, 0x00 },1309	{ 0x37b3, 0x42 },1310	{ 0x37b4, 0x42 },1311	{ 0x37b5, 0x33 },1312	{ 0x37b6, 0x00 },1313	{ 0x37b7, 0x00 },1314	{ 0x37b8, 0x00 },1315	{ 0x37b9, 0xff },1316 1317	/* ADC Sync */1318 1319	{ 0x4503, 0x10 },1320};1321 1322static const s64 ov8865_link_freq_menu[] = {1323	360000000,1324};1325 1326static const char *const ov8865_test_pattern_menu[] = {1327	"Disabled",1328	"Random data",1329	"Color bars",1330	"Color bars with rolling bar",1331	"Color squares",1332	"Color squares with rolling bar"1333};1334 1335static const u8 ov8865_test_pattern_bits[] = {1336	0,1337	OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_RANDOM_DATA,1338	OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_COLOR_BARS,1339	OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_ROLLING_BAR_EN |1340	OV8865_PRE_CTRL0_PATTERN_COLOR_BARS,1341	OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES,1342	OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_ROLLING_BAR_EN |1343	OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES,1344};1345 1346/* Input/Output */1347 1348static int ov8865_read(struct ov8865_sensor *sensor, u16 address, u8 *value)1349{1350	unsigned char data[2] = { address >> 8, address & 0xff };1351	struct i2c_client *client = sensor->i2c_client;1352	int ret;1353 1354	ret = i2c_master_send(client, data, sizeof(data));1355	if (ret < 0) {1356		dev_dbg(&client->dev, "i2c send error at address %#04x\n",1357			address);1358		return ret;1359	}1360 1361	ret = i2c_master_recv(client, value, 1);1362	if (ret < 0) {1363		dev_dbg(&client->dev, "i2c recv error at address %#04x\n",1364			address);1365		return ret;1366	}1367 1368	return 0;1369}1370 1371static int ov8865_write(struct ov8865_sensor *sensor, u16 address, u8 value)1372{1373	unsigned char data[3] = { address >> 8, address & 0xff, value };1374	struct i2c_client *client = sensor->i2c_client;1375	int ret;1376 1377	ret = i2c_master_send(client, data, sizeof(data));1378	if (ret < 0) {1379		dev_dbg(&client->dev, "i2c send error at address %#04x\n",1380			address);1381		return ret;1382	}1383 1384	return 0;1385}1386 1387static int ov8865_write_sequence(struct ov8865_sensor *sensor,1388				 const struct ov8865_register_value *sequence,1389				 unsigned int sequence_count)1390{1391	unsigned int i;1392	int ret = 0;1393 1394	for (i = 0; i < sequence_count; i++) {1395		ret = ov8865_write(sensor, sequence[i].address,1396				   sequence[i].value);1397		if (ret)1398			break;1399 1400		if (sequence[i].delay_ms)1401			msleep(sequence[i].delay_ms);1402	}1403 1404	return ret;1405}1406 1407static int ov8865_update_bits(struct ov8865_sensor *sensor, u16 address,1408			      u8 mask, u8 bits)1409{1410	u8 value = 0;1411	int ret;1412 1413	ret = ov8865_read(sensor, address, &value);1414	if (ret)1415		return ret;1416 1417	value &= ~mask;1418	value |= bits;1419 1420	return ov8865_write(sensor, address, value);1421}1422 1423/* Sensor */1424 1425static int ov8865_sw_reset(struct ov8865_sensor *sensor)1426{1427	return ov8865_write(sensor, OV8865_SW_RESET_REG, OV8865_SW_RESET_RESET);1428}1429 1430static int ov8865_sw_standby(struct ov8865_sensor *sensor, int standby)1431{1432	u8 value = 0;1433 1434	if (!standby)1435		value = OV8865_SW_STANDBY_STREAM_ON;1436 1437	return ov8865_write(sensor, OV8865_SW_STANDBY_REG, value);1438}1439 1440static int ov8865_chip_id_check(struct ov8865_sensor *sensor)1441{1442	u16 regs[] = { OV8865_CHIP_ID_HH_REG, OV8865_CHIP_ID_H_REG,1443		       OV8865_CHIP_ID_L_REG };1444	u8 values[] = { OV8865_CHIP_ID_HH_VALUE, OV8865_CHIP_ID_H_VALUE,1445			OV8865_CHIP_ID_L_VALUE };1446	unsigned int i;1447	u8 value;1448	int ret;1449 1450	for (i = 0; i < ARRAY_SIZE(regs); i++) {1451		ret = ov8865_read(sensor, regs[i], &value);1452		if (ret < 0)1453			return ret;1454 1455		if (value != values[i]) {1456			dev_err(sensor->dev,1457				"chip id value mismatch: %#x instead of %#x\n",1458				value, values[i]);1459			return -EINVAL;1460		}1461	}1462 1463	return 0;1464}1465 1466static int ov8865_charge_pump_configure(struct ov8865_sensor *sensor)1467{1468	return ov8865_write(sensor, OV8865_PUMP_CLK_DIV_REG,1469			    OV8865_PUMP_CLK_DIV_PUMP_P(1));1470}1471 1472static int ov8865_mipi_configure(struct ov8865_sensor *sensor)1473{1474	struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =1475		&sensor->endpoint.bus.mipi_csi2;1476	unsigned int lanes_count = bus_mipi_csi2->num_data_lanes;1477	int ret;1478 1479	ret = ov8865_write(sensor, OV8865_MIPI_SC_CTRL0_REG,1480			   OV8865_MIPI_SC_CTRL0_LANES(lanes_count) |1481			   OV8865_MIPI_SC_CTRL0_MIPI_EN |1482			   OV8865_MIPI_SC_CTRL0_UNKNOWN);1483	if (ret)1484		return ret;1485 1486	ret = ov8865_write(sensor, OV8865_MIPI_SC_CTRL2_REG,1487			   OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC);1488	if (ret)1489		return ret;1490 1491	if (lanes_count >= 2) {1492		ret = ov8865_write(sensor, OV8865_MIPI_LANE_SEL01_REG,1493				   OV8865_MIPI_LANE_SEL01_LANE0(0) |1494				   OV8865_MIPI_LANE_SEL01_LANE1(1));1495		if (ret)1496			return ret;1497	}1498 1499	if (lanes_count >= 4) {1500		ret = ov8865_write(sensor, OV8865_MIPI_LANE_SEL23_REG,1501				   OV8865_MIPI_LANE_SEL23_LANE2(2) |1502				   OV8865_MIPI_LANE_SEL23_LANE3(3));1503		if (ret)1504			return ret;1505	}1506 1507	ret = ov8865_update_bits(sensor, OV8865_CLK_SEL1_REG,1508				 OV8865_CLK_SEL1_MIPI_EOF,1509				 OV8865_CLK_SEL1_MIPI_EOF);1510	if (ret)1511		return ret;1512 1513	/*1514	 * This value might need to change depending on PCLK rate,1515	 * but it's unclear how. This value seems to generally work1516	 * while the default value was found to cause transmission errors.1517	 */1518	return ov8865_write(sensor, OV8865_MIPI_PCLK_PERIOD_REG, 0x16);1519}1520 1521static int ov8865_black_level_configure(struct ov8865_sensor *sensor)1522{1523	int ret;1524 1525	/* Trigger BLC on relevant events and enable filter. */1526	ret = ov8865_write(sensor, OV8865_BLC_CTRL0_REG,1527			   OV8865_BLC_CTRL0_TRIG_RANGE_EN |1528			   OV8865_BLC_CTRL0_TRIG_FORMAT_EN |1529			   OV8865_BLC_CTRL0_TRIG_GAIN_EN |1530			   OV8865_BLC_CTRL0_TRIG_EXPOSURE_EN |1531			   OV8865_BLC_CTRL0_FILTER_EN);1532	if (ret)1533		return ret;1534 1535	/* Lower BLC offset trigger threshold. */1536	ret = ov8865_write(sensor, OV8865_BLC_CTRLD_REG,1537			   OV8865_BLC_CTRLD_OFFSET_TRIGGER(16));1538	if (ret)1539		return ret;1540 1541	ret = ov8865_write(sensor, OV8865_BLC_CTRL1F_REG, 0);1542	if (ret)1543		return ret;1544 1545	/* Increase BLC offset maximum limit. */1546	return ov8865_write(sensor, OV8865_BLC_OFFSET_LIMIT_REG,1547			    OV8865_BLC_OFFSET_LIMIT(63));1548}1549 1550static int ov8865_isp_configure(struct ov8865_sensor *sensor)1551{1552	int ret;1553 1554	/* Disable lens correction. */1555	ret = ov8865_write(sensor, OV8865_ISP_CTRL0_REG,1556			   OV8865_ISP_CTRL0_WHITE_BALANCE_EN |1557			   OV8865_ISP_CTRL0_DPC_BLACK_EN |1558			   OV8865_ISP_CTRL0_DPC_WHITE_EN);1559	if (ret)1560		return ret;1561 1562	return ov8865_write(sensor, OV8865_ISP_CTRL1_REG,1563			    OV8865_ISP_CTRL1_BLC_EN);1564}1565 1566static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,1567					   const struct ov8865_mode *mode)1568{1569	const struct ov8865_pll1_config *config;1570	unsigned long pll1_rate;1571 1572	config = sensor->pll_configs->pll1_config;1573	pll1_rate = sensor->extclk_rate * config->pll_mul / config->pll_pre_div_half;1574 1575	switch (config->pll_pre_div) {1576	case 0:1577		break;1578	case 1:1579		pll1_rate *= 3;1580		pll1_rate /= 2;1581		break;1582	case 3:1583		pll1_rate *= 5;1584		pll1_rate /= 2;1585		break;1586	case 4:1587		pll1_rate /= 3;1588		break;1589	case 5:1590		pll1_rate /= 4;1591		break;1592	case 7:1593		pll1_rate /= 8;1594		break;1595	default:1596		pll1_rate /= config->pll_pre_div;1597		break;1598	}1599 1600	return pll1_rate;1601}1602 1603static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,1604				      const struct ov8865_mode *mode,1605				      u32 mbus_code)1606{1607	const struct ov8865_pll1_config *config;1608	u8 value;1609	int ret;1610 1611	config = sensor->pll_configs->pll1_config;1612 1613	switch (mbus_code) {1614	case MEDIA_BUS_FMT_SBGGR10_1X10:1615		value = OV8865_MIPI_BIT_SEL(10);1616		break;1617	default:1618		return -EINVAL;1619	}1620 1621	ret = ov8865_write(sensor, OV8865_MIPI_BIT_SEL_REG, value);1622	if (ret)1623		return ret;1624 1625	ret = ov8865_write(sensor, OV8865_PLL_CTRLA_REG,1626			   OV8865_PLL_CTRLA_PRE_DIV_HALF(config->pll_pre_div_half));1627	if (ret)1628		return ret;1629 1630	ret = ov8865_write(sensor, OV8865_PLL_CTRL0_REG,1631			   OV8865_PLL_CTRL0_PRE_DIV(config->pll_pre_div));1632	if (ret)1633		return ret;1634 1635	ret = ov8865_write(sensor, OV8865_PLL_CTRL1_REG,1636			   OV8865_PLL_CTRL1_MUL_H(config->pll_mul));1637	if (ret)1638		return ret;1639 1640	ret = ov8865_write(sensor, OV8865_PLL_CTRL2_REG,1641			   OV8865_PLL_CTRL2_MUL_L(config->pll_mul));1642	if (ret)1643		return ret;1644 1645	ret = ov8865_write(sensor, OV8865_PLL_CTRL3_REG,1646			   OV8865_PLL_CTRL3_M_DIV(config->m_div));1647	if (ret)1648		return ret;1649 1650	ret = ov8865_write(sensor, OV8865_PLL_CTRL4_REG,1651			   OV8865_PLL_CTRL4_MIPI_DIV(config->mipi_div));1652	if (ret)1653		return ret;1654 1655	ret = ov8865_update_bits(sensor, OV8865_PCLK_SEL_REG,1656				 OV8865_PCLK_SEL_PCLK_DIV_MASK,1657				 OV8865_PCLK_SEL_PCLK_DIV(config->pclk_div));1658	if (ret)1659		return ret;1660 1661	ret = ov8865_write(sensor, OV8865_PLL_CTRL5_REG,1662			   OV8865_PLL_CTRL5_SYS_PRE_DIV(config->sys_pre_div));1663	if (ret)1664		return ret;1665 1666	ret = ov8865_write(sensor, OV8865_PLL_CTRL6_REG,1667			   OV8865_PLL_CTRL6_SYS_DIV(config->sys_div));1668	if (ret)1669		return ret;1670 1671	return ov8865_update_bits(sensor, OV8865_PLL_CTRL1E_REG,1672				  OV8865_PLL_CTRL1E_PLL1_NO_LAT,1673				  OV8865_PLL_CTRL1E_PLL1_NO_LAT);1674}1675 1676static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,1677				      const struct ov8865_mode *mode)1678{1679	const struct ov8865_pll2_config *config;1680	int ret;1681 1682	config = mode->pll2_binning ? sensor->pll_configs->pll2_config_binning :1683				      sensor->pll_configs->pll2_config_native;1684 1685	ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,1686			   OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |1687			   OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));1688	if (ret)1689		return ret;1690 1691	ret = ov8865_write(sensor, OV8865_PLL_CTRLB_REG,1692			   OV8865_PLL_CTRLB_PRE_DIV(config->pll_pre_div));1693	if (ret)1694		return ret;1695 1696	ret = ov8865_write(sensor, OV8865_PLL_CTRLC_REG,1697			   OV8865_PLL_CTRLC_MUL_H(config->pll_mul));1698	if (ret)1699		return ret;1700 1701	ret = ov8865_write(sensor, OV8865_PLL_CTRLD_REG,1702			   OV8865_PLL_CTRLD_MUL_L(config->pll_mul));1703	if (ret)1704		return ret;1705 1706	ret = ov8865_write(sensor, OV8865_PLL_CTRLF_REG,1707			   OV8865_PLL_CTRLF_SYS_PRE_DIV(config->sys_pre_div));1708	if (ret)1709		return ret;1710 1711	return ov8865_write(sensor, OV8865_PLL_CTRLE_REG,1712			    OV8865_PLL_CTRLE_SYS_DIV(config->sys_div));1713}1714 1715static int ov8865_mode_sclk_configure(struct ov8865_sensor *sensor,1716				      const struct ov8865_mode *mode)1717{1718	const struct ov8865_sclk_config *config = &ov8865_sclk_config_native;1719	int ret;1720 1721	ret = ov8865_write(sensor, OV8865_CLK_SEL0_REG,1722			   OV8865_CLK_SEL0_PLL1_SYS_SEL(config->sys_sel));1723	if (ret)1724		return ret;1725 1726	ret = ov8865_update_bits(sensor, OV8865_CLK_SEL1_REG,1727				 OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK,1728				 OV8865_CLK_SEL1_PLL_SCLK_SEL(config->sclk_sel));1729	if (ret)1730		return ret;1731 1732	return ov8865_write(sensor, OV8865_SCLK_CTRL_REG,1733			    OV8865_SCLK_CTRL_UNKNOWN |1734			    OV8865_SCLK_CTRL_SCLK_DIV(config->sclk_div) |1735			    OV8865_SCLK_CTRL_SCLK_PRE_DIV(config->sclk_pre_div));1736}1737 1738static int ov8865_mode_binning_configure(struct ov8865_sensor *sensor,1739					 const struct ov8865_mode *mode)1740{1741	unsigned int variopixel_hsub_coef, variopixel_vsub_coef;1742	u8 value;1743	int ret;1744 1745	ret = ov8865_write(sensor, OV8865_FORMAT1_REG, 0);1746	if (ret)1747		return ret;1748 1749	value = OV8865_FORMAT2_HSYNC_EN;1750 1751	if (mode->binning_x)1752		value |= OV8865_FORMAT2_FST_HBIN_EN;1753 1754	if (mode->binning_y)1755		value |= OV8865_FORMAT2_FST_VBIN_EN;1756 1757	if (mode->sync_hbin)1758		value |= OV8865_FORMAT2_SYNC_HBIN_EN;1759 1760	if (mode->horz_var2)1761		value |= OV8865_FORMAT2_ISP_HORZ_VAR2_EN;1762 1763	ret = ov8865_write(sensor, OV8865_FORMAT2_REG, value);1764	if (ret)1765		return ret;1766 1767	ret = ov8865_update_bits(sensor, OV8865_ISP_CTRL2_REG,1768				 OV8865_ISP_CTRL2_VARIOPIXEL_EN,1769				 mode->variopixel ?1770				 OV8865_ISP_CTRL2_VARIOPIXEL_EN : 0);1771	if (ret)1772		return ret;1773 1774	if (mode->variopixel) {1775		/* VarioPixel coefs needs to be > 1. */1776		variopixel_hsub_coef = mode->variopixel_hsub_coef;1777		variopixel_vsub_coef = mode->variopixel_vsub_coef;1778	} else {1779		variopixel_hsub_coef = 1;1780		variopixel_vsub_coef = 1;1781	}1782 1783	ret = ov8865_write(sensor, OV8865_VAP_CTRL1_REG,1784			   OV8865_VAP_CTRL1_HSUB_COEF(variopixel_hsub_coef) |1785			   OV8865_VAP_CTRL1_VSUB_COEF(variopixel_vsub_coef));1786	if (ret)1787		return ret;1788 1789	ret = ov8865_write(sensor, OV8865_INC_X_ODD_REG,1790			   OV8865_INC_X_ODD(mode->inc_x_odd));1791	if (ret)1792		return ret;1793 1794	ret = ov8865_write(sensor, OV8865_INC_X_EVEN_REG,1795			   OV8865_INC_X_EVEN(mode->inc_x_even));1796	if (ret)1797		return ret;1798 1799	ret = ov8865_write(sensor, OV8865_INC_Y_ODD_REG,1800			   OV8865_INC_Y_ODD(mode->inc_y_odd));1801	if (ret)1802		return ret;1803 1804	return ov8865_write(sensor, OV8865_INC_Y_EVEN_REG,1805			    OV8865_INC_Y_EVEN(mode->inc_y_even));1806}1807 1808static int ov8865_mode_black_level_configure(struct ov8865_sensor *sensor,1809					     const struct ov8865_mode *mode)1810{1811	int ret;1812 1813	/* Note that a zero value for blc_col_shift_mask is the default 256. */1814	ret = ov8865_write(sensor, OV8865_BLC_CTRL1_REG,1815			   mode->blc_col_shift_mask |1816			   OV8865_BLC_CTRL1_OFFSET_LIMIT_EN);1817	if (ret)1818		return ret;1819 1820	/* BLC top zero line */1821 1822	ret = ov8865_write(sensor, OV8865_BLC_TOP_ZLINE_START_REG,1823			   OV8865_BLC_TOP_ZLINE_START(mode->blc_top_zero_line_start));1824	if (ret)1825		return ret;1826 1827	ret = ov8865_write(sensor, OV8865_BLC_TOP_ZLINE_NUM_REG,1828			   OV8865_BLC_TOP_ZLINE_NUM(mode->blc_top_zero_line_num));1829	if (ret)1830		return ret;1831 1832	/* BLC top black line */1833 1834	ret = ov8865_write(sensor, OV8865_BLC_TOP_BLKLINE_START_REG,1835			   OV8865_BLC_TOP_BLKLINE_START(mode->blc_top_black_line_start));1836	if (ret)1837		return ret;1838 1839	ret = ov8865_write(sensor, OV8865_BLC_TOP_BLKLINE_NUM_REG,1840			   OV8865_BLC_TOP_BLKLINE_NUM(mode->blc_top_black_line_num));1841	if (ret)1842		return ret;1843 1844	/* BLC bottom zero line */1845 1846	ret = ov8865_write(sensor, OV8865_BLC_BOT_ZLINE_START_REG,1847			   OV8865_BLC_BOT_ZLINE_START(mode->blc_bottom_zero_line_start));1848	if (ret)1849		return ret;1850 1851	ret = ov8865_write(sensor, OV8865_BLC_BOT_ZLINE_NUM_REG,1852			   OV8865_BLC_BOT_ZLINE_NUM(mode->blc_bottom_zero_line_num));1853	if (ret)1854		return ret;1855 1856	/* BLC bottom black line */1857 1858	ret = ov8865_write(sensor, OV8865_BLC_BOT_BLKLINE_START_REG,1859			   OV8865_BLC_BOT_BLKLINE_START(mode->blc_bottom_black_line_start));1860	if (ret)1861		return ret;1862 1863	ret = ov8865_write(sensor, OV8865_BLC_BOT_BLKLINE_NUM_REG,1864			   OV8865_BLC_BOT_BLKLINE_NUM(mode->blc_bottom_black_line_num));1865	if (ret)1866		return ret;1867 1868	/* BLC anchor */1869 1870	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_START_H_REG,1871			   OV8865_BLC_ANCHOR_LEFT_START_H(mode->blc_anchor_left_start));1872	if (ret)1873		return ret;1874 1875	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_START_L_REG,1876			   OV8865_BLC_ANCHOR_LEFT_START_L(mode->blc_anchor_left_start));1877	if (ret)1878		return ret;1879 1880	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_END_H_REG,1881			   OV8865_BLC_ANCHOR_LEFT_END_H(mode->blc_anchor_left_end));1882	if (ret)1883		return ret;1884 1885	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_END_L_REG,1886			   OV8865_BLC_ANCHOR_LEFT_END_L(mode->blc_anchor_left_end));1887	if (ret)1888		return ret;1889 1890	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_START_H_REG,1891			   OV8865_BLC_ANCHOR_RIGHT_START_H(mode->blc_anchor_right_start));1892	if (ret)1893		return ret;1894 1895	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_START_L_REG,1896			   OV8865_BLC_ANCHOR_RIGHT_START_L(mode->blc_anchor_right_start));1897	if (ret)1898		return ret;1899 1900	ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_END_H_REG,1901			   OV8865_BLC_ANCHOR_RIGHT_END_H(mode->blc_anchor_right_end));1902	if (ret)1903		return ret;1904 1905	return ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_END_L_REG,1906			    OV8865_BLC_ANCHOR_RIGHT_END_L(mode->blc_anchor_right_end));1907}1908 1909static int ov8865_mode_configure(struct ov8865_sensor *sensor,1910				 const struct ov8865_mode *mode, u32 mbus_code)1911{1912	int ret;1913 1914	/* Output Size X */1915 1916	ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_X_H_REG,1917			   OV8865_OUTPUT_SIZE_X_H(mode->output_size_x));1918	if (ret)1919		return ret;1920 1921	ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_X_L_REG,1922			   OV8865_OUTPUT_SIZE_X_L(mode->output_size_x));1923	if (ret)1924		return ret;1925 1926	/* Horizontal Total Size */1927 1928	ret = ov8865_write(sensor, OV8865_HTS_H_REG, OV8865_HTS_H(mode->hts));1929	if (ret)1930		return ret;1931 1932	ret = ov8865_write(sensor, OV8865_HTS_L_REG, OV8865_HTS_L(mode->hts));1933	if (ret)1934		return ret;1935 1936	/* Output Size Y */1937 1938	ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_Y_H_REG,1939			   OV8865_OUTPUT_SIZE_Y_H(mode->output_size_y));1940	if (ret)1941		return ret;1942 1943	ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_Y_L_REG,1944			   OV8865_OUTPUT_SIZE_Y_L(mode->output_size_y));1945	if (ret)1946		return ret;1947 1948	/* Vertical Total Size */1949 1950	ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(mode->vts));1951	if (ret)1952		return ret;1953 1954	ret = ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(mode->vts));1955	if (ret)1956		return ret;1957 1958	if (mode->size_auto) {1959		/* Auto Size */1960 1961		ret = ov8865_write(sensor, OV8865_AUTO_SIZE_CTRL_REG,1962				   OV8865_AUTO_SIZE_CTRL_OFFSET_Y_REG |1963				   OV8865_AUTO_SIZE_CTRL_OFFSET_X_REG |1964				   OV8865_AUTO_SIZE_CTRL_CROP_END_Y_REG |1965				   OV8865_AUTO_SIZE_CTRL_CROP_END_X_REG |1966				   OV8865_AUTO_SIZE_CTRL_CROP_START_Y_REG |1967				   OV8865_AUTO_SIZE_CTRL_CROP_START_X_REG);1968		if (ret)1969			return ret;1970 1971		ret = ov8865_write(sensor, OV8865_AUTO_SIZE_BOUNDARIES_REG,1972				   OV8865_AUTO_SIZE_BOUNDARIES_Y(mode->size_auto_boundary_y) |1973				   OV8865_AUTO_SIZE_BOUNDARIES_X(mode->size_auto_boundary_x));1974		if (ret)1975			return ret;1976	} else {1977		/* Crop Start X */1978 1979		ret = ov8865_write(sensor, OV8865_CROP_START_X_H_REG,1980				   OV8865_CROP_START_X_H(mode->crop_start_x));1981		if (ret)1982			return ret;1983 1984		ret = ov8865_write(sensor, OV8865_CROP_START_X_L_REG,1985				   OV8865_CROP_START_X_L(mode->crop_start_x));1986		if (ret)1987			return ret;1988 1989		/* Offset X */1990 1991		ret = ov8865_write(sensor, OV8865_OFFSET_X_H_REG,1992				   OV8865_OFFSET_X_H(mode->offset_x));1993		if (ret)1994			return ret;1995 1996		ret = ov8865_write(sensor, OV8865_OFFSET_X_L_REG,1997				   OV8865_OFFSET_X_L(mode->offset_x));1998		if (ret)1999			return ret;2000 2001		/* Crop End X */2002 2003		ret = ov8865_write(sensor, OV8865_CROP_END_X_H_REG,2004				   OV8865_CROP_END_X_H(mode->crop_end_x));2005		if (ret)2006			return ret;2007 2008		ret = ov8865_write(sensor, OV8865_CROP_END_X_L_REG,2009				   OV8865_CROP_END_X_L(mode->crop_end_x));2010		if (ret)2011			return ret;2012 2013		/* Crop Start Y */2014 2015		ret = ov8865_write(sensor, OV8865_CROP_START_Y_H_REG,2016				   OV8865_CROP_START_Y_H(mode->crop_start_y));2017		if (ret)2018			return ret;2019 2020		ret = ov8865_write(sensor, OV8865_CROP_START_Y_L_REG,2021				   OV8865_CROP_START_Y_L(mode->crop_start_y));2022		if (ret)2023			return ret;2024 2025		/* Offset Y */2026 2027		ret = ov8865_write(sensor, OV8865_OFFSET_Y_H_REG,2028				   OV8865_OFFSET_Y_H(mode->offset_y));2029		if (ret)2030			return ret;2031 2032		ret = ov8865_write(sensor, OV8865_OFFSET_Y_L_REG,2033				   OV8865_OFFSET_Y_L(mode->offset_y));2034		if (ret)2035			return ret;2036 2037		/* Crop End Y */2038 2039		ret = ov8865_write(sensor, OV8865_CROP_END_Y_H_REG,2040				   OV8865_CROP_END_Y_H(mode->crop_end_y));2041		if (ret)2042			return ret;2043 2044		ret = ov8865_write(sensor, OV8865_CROP_END_Y_L_REG,2045				   OV8865_CROP_END_Y_L(mode->crop_end_y));2046		if (ret)2047			return ret;2048	}2049 2050	/* VFIFO */2051 2052	ret = ov8865_write(sensor, OV8865_VFIFO_READ_START_H_REG,2053			   OV8865_VFIFO_READ_START_H(mode->vfifo_read_start));2054	if (ret)2055		return ret;2056 2057	ret = ov8865_write(sensor, OV8865_VFIFO_READ_START_L_REG,2058			   OV8865_VFIFO_READ_START_L(mode->vfifo_read_start));2059	if (ret)2060		return ret;2061 2062	ret = ov8865_write(sensor, OV8865_ABLC_NUM_REG,2063			   OV8865_ABLC_NUM(mode->ablc_num));2064	if (ret)2065		return ret;2066 2067	ret = ov8865_write(sensor, OV8865_ZLINE_NUM_REG,2068			   OV8865_ZLINE_NUM(mode->zline_num));2069	if (ret)2070		return ret;2071 2072	/* Binning */2073 2074	ret = ov8865_mode_binning_configure(sensor, mode);2075	if (ret)2076		return ret;2077 2078	/* Black Level */2079 2080	ret = ov8865_mode_black_level_configure(sensor, mode);2081	if (ret)2082		return ret;2083 2084	/* PLLs */2085 2086	ret = ov8865_mode_pll1_configure(sensor, mode, mbus_code);2087	if (ret)2088		return ret;2089 2090	ret = ov8865_mode_pll2_configure(sensor, mode);2091	if (ret)2092		return ret;2093 2094	ret = ov8865_mode_sclk_configure(sensor, mode);2095	if (ret)2096		return ret;2097 2098	/* Extra registers */2099 2100	if (mode->register_values) {2101		ret = ov8865_write_sequence(sensor, mode->register_values,2102					    mode->register_values_count);2103		if (ret)2104			return ret;2105	}2106 2107	return 0;2108}2109 2110static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,2111					       const struct ov8865_mode *mode)2112{2113	const struct ov8865_pll1_config *config;2114	unsigned long pll1_rate;2115 2116	config = sensor->pll_configs->pll1_config;2117 2118	pll1_rate = ov8865_mode_pll1_rate(sensor, mode);2119 2120	return pll1_rate / config->m_div / 2;2121}2122 2123/* Exposure */2124 2125static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)2126{2127	int ret;2128 2129	/* The sensor stores exposure in units of 1/16th of a line */2130	exposure *= 16;2131 2132	ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,2133			   OV8865_EXPOSURE_CTRL_HH(exposure));2134	if (ret)2135		return ret;2136 2137	ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_H_REG,2138			   OV8865_EXPOSURE_CTRL_H(exposure));2139	if (ret)2140		return ret;2141 2142	return ov8865_write(sensor, OV8865_EXPOSURE_CTRL_L_REG,2143			    OV8865_EXPOSURE_CTRL_L(exposure));2144}2145 2146/* Gain */2147 2148static int ov8865_analog_gain_configure(struct ov8865_sensor *sensor, u32 gain)2149{2150	int ret;2151 2152	ret = ov8865_write(sensor, OV8865_GAIN_CTRL_H_REG,2153			   OV8865_GAIN_CTRL_H(gain));2154	if (ret)2155		return ret;2156 2157	return ov8865_write(sensor, OV8865_GAIN_CTRL_L_REG,2158			    OV8865_GAIN_CTRL_L(gain));2159}2160 2161/* White Balance */2162 2163static int ov8865_red_balance_configure(struct ov8865_sensor *sensor,2164					u32 red_balance)2165{2166	int ret;2167 2168	ret = ov8865_write(sensor, OV8865_ISP_GAIN_RED_H_REG,2169			   OV8865_ISP_GAIN_RED_H(red_balance));2170	if (ret)2171		return ret;2172 2173	return ov8865_write(sensor, OV8865_ISP_GAIN_RED_L_REG,2174			    OV8865_ISP_GAIN_RED_L(red_balance));2175}2176 2177static int ov8865_blue_balance_configure(struct ov8865_sensor *sensor,2178					 u32 blue_balance)2179{2180	int ret;2181 2182	ret = ov8865_write(sensor, OV8865_ISP_GAIN_BLUE_H_REG,2183			   OV8865_ISP_GAIN_BLUE_H(blue_balance));2184	if (ret)2185		return ret;2186 2187	return ov8865_write(sensor, OV8865_ISP_GAIN_BLUE_L_REG,2188			    OV8865_ISP_GAIN_BLUE_L(blue_balance));2189}2190 2191/* Flip */2192 2193static int ov8865_flip_vert_configure(struct ov8865_sensor *sensor, bool enable)2194{2195	u8 bits = OV8865_FORMAT1_FLIP_VERT_ISP_EN |2196		  OV8865_FORMAT1_FLIP_VERT_SENSOR_EN;2197 2198	return ov8865_update_bits(sensor, OV8865_FORMAT1_REG, bits,2199				  enable ? bits : 0);2200}2201 2202static int ov8865_flip_horz_configure(struct ov8865_sensor *sensor, bool enable)2203{2204	u8 bits = OV8865_FORMAT2_FLIP_HORZ_ISP_EN |2205		  OV8865_FORMAT2_FLIP_HORZ_SENSOR_EN;2206 2207	return ov8865_update_bits(sensor, OV8865_FORMAT2_REG, bits,2208				  enable ? bits : 0);2209}2210 2211/* Test Pattern */2212 2213static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,2214					 unsigned int index)2215{2216	if (index >= ARRAY_SIZE(ov8865_test_pattern_bits))2217		return -EINVAL;2218 2219	return ov8865_write(sensor, OV8865_PRE_CTRL0_REG,2220			    ov8865_test_pattern_bits[index]);2221}2222 2223/* Blanking */2224 2225static int ov8865_vts_configure(struct ov8865_sensor *sensor, u32 vblank)2226{2227	u16 vts = sensor->state.mode->output_size_y + vblank;2228	int ret;2229 2230	ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(vts));2231	if (ret)2232		return ret;2233 2234	return ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(vts));2235}2236 2237/* State */2238 2239static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,2240				       const struct ov8865_mode *mode,2241				       u32 mbus_code)2242{2243	struct ov8865_ctrls *ctrls = &sensor->ctrls;2244	struct v4l2_mbus_config_mipi_csi2 *bus_mipi_csi2 =2245		&sensor->endpoint.bus.mipi_csi2;2246	unsigned long mipi_clk_rate;2247	unsigned int bits_per_sample;2248	unsigned int lanes_count;2249	unsigned int i, j;2250	s64 mipi_pixel_rate;2251 2252	mipi_clk_rate = ov8865_mode_mipi_clk_rate(sensor, mode);2253	if (!mipi_clk_rate)2254		return -EINVAL;2255 2256	for (i = 0; i < ARRAY_SIZE(ov8865_link_freq_menu); i++) {2257		s64 freq = ov8865_link_freq_menu[i];2258 2259		if (freq == mipi_clk_rate)2260			break;2261	}2262 2263	for (j = 0; j < sensor->endpoint.nr_of_link_frequencies; j++) {2264		u64 freq = sensor->endpoint.link_frequencies[j];2265 2266		if (freq == mipi_clk_rate)2267			break;2268	}2269 2270	if (i == ARRAY_SIZE(ov8865_link_freq_menu)) {2271		dev_err(sensor->dev,2272			"failed to find %lu clk rate in link freq\n",2273			mipi_clk_rate);2274	} else if (j == sensor->endpoint.nr_of_link_frequencies) {2275		dev_err(sensor->dev,2276			"failed to find %lu clk rate in endpoint link-frequencies\n",2277			mipi_clk_rate);2278	} else {2279		__v4l2_ctrl_s_ctrl(ctrls->link_freq, i);2280	}2281 2282	switch (mbus_code) {2283	case MEDIA_BUS_FMT_SBGGR10_1X10:2284		bits_per_sample = 10;2285		break;2286	default:2287		return -EINVAL;2288	}2289 2290	lanes_count = bus_mipi_csi2->num_data_lanes;2291	mipi_pixel_rate = mipi_clk_rate * 2 * lanes_count / bits_per_sample;2292 2293	__v4l2_ctrl_s_ctrl_int64(ctrls->pixel_rate, mipi_pixel_rate);2294 2295	return 0;2296}2297 2298static int ov8865_state_configure(struct ov8865_sensor *sensor,2299				  const struct ov8865_mode *mode,2300				  u32 mbus_code)2301{2302	int ret;2303 2304	if (sensor->state.streaming)2305		return -EBUSY;2306 2307	/* State will be configured at first power on otherwise. */2308	if (pm_runtime_enabled(sensor->dev) &&2309	    !pm_runtime_suspended(sensor->dev)) {2310		ret = ov8865_mode_configure(sensor, mode, mbus_code);2311		if (ret)2312			return ret;2313	}2314 2315	ret = ov8865_state_mipi_configure(sensor, mode, mbus_code);2316	if (ret)2317		return ret;2318 2319	sensor->state.mode = mode;2320	sensor->state.mbus_code = mbus_code;2321 2322	return 0;2323}2324 2325static int ov8865_state_init(struct ov8865_sensor *sensor)2326{2327	return ov8865_state_configure(sensor, &ov8865_modes[0],2328				      ov8865_mbus_codes[0]);2329}2330 2331/* Sensor Base */2332 2333static int ov8865_sensor_init(struct ov8865_sensor *sensor)2334{2335	int ret;2336 2337	ret = ov8865_sw_reset(sensor);2338	if (ret) {2339		dev_err(sensor->dev, "failed to perform sw reset\n");2340		return ret;2341	}2342 2343	ret = ov8865_sw_standby(sensor, 1);2344	if (ret) {2345		dev_err(sensor->dev, "failed to set sensor standby\n");2346		return ret;2347	}2348 2349	ret = ov8865_chip_id_check(sensor);2350	if (ret) {2351		dev_err(sensor->dev, "failed to check sensor chip id\n");2352		return ret;2353	}2354 2355	ret = ov8865_write_sequence(sensor, ov8865_init_sequence,2356				    ARRAY_SIZE(ov8865_init_sequence));2357	if (ret) {2358		dev_err(sensor->dev, "failed to write init sequence\n");2359		return ret;2360	}2361 2362	ret = ov8865_charge_pump_configure(sensor);2363	if (ret) {2364		dev_err(sensor->dev, "failed to configure pad\n");2365		return ret;2366	}2367 2368	ret = ov8865_mipi_configure(sensor);2369	if (ret) {2370		dev_err(sensor->dev, "failed to configure MIPI\n");2371		return ret;2372	}2373 2374	ret = ov8865_isp_configure(sensor);2375	if (ret) {2376		dev_err(sensor->dev, "failed to configure ISP\n");2377		return ret;2378	}2379 2380	ret = ov8865_black_level_configure(sensor);2381	if (ret) {2382		dev_err(sensor->dev, "failed to configure black level\n");2383		return ret;2384	}2385 2386	/* Configure current mode. */2387	ret = ov8865_state_configure(sensor, sensor->state.mode,2388				     sensor->state.mbus_code);2389	if (ret) {2390		dev_err(sensor->dev, "failed to configure state\n");2391		return ret;2392	}2393 2394	return 0;2395}2396 2397static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on)2398{2399	/* Keep initialized to zero for disable label. */2400	int ret = 0;2401 2402	if (on) {2403		gpiod_set_value_cansleep(sensor->reset, 1);2404		gpiod_set_value_cansleep(sensor->powerdown, 1);2405 2406		ret = regulator_enable(sensor->dovdd);2407		if (ret) {2408			dev_err(sensor->dev,2409				"failed to enable DOVDD regulator\n");2410			return ret;2411		}2412 2413		ret = regulator_enable(sensor->avdd);2414		if (ret) {2415			dev_err(sensor->dev,2416				"failed to enable AVDD regulator\n");2417			goto disable_dovdd;2418		}2419 2420		ret = regulator_enable(sensor->dvdd);2421		if (ret) {2422			dev_err(sensor->dev,2423				"failed to enable DVDD regulator\n");2424			goto disable_avdd;2425		}2426 2427		ret = clk_prepare_enable(sensor->extclk);2428		if (ret) {2429			dev_err(sensor->dev, "failed to enable EXTCLK clock\n");2430			goto disable_dvdd;2431		}2432 2433		gpiod_set_value_cansleep(sensor->reset, 0);2434		gpiod_set_value_cansleep(sensor->powerdown, 0);2435 2436		/* Time to enter streaming mode according to power timings. */2437		usleep_range(10000, 12000);2438	} else {2439		gpiod_set_value_cansleep(sensor->powerdown, 1);2440		gpiod_set_value_cansleep(sensor->reset, 1);2441 2442		clk_disable_unprepare(sensor->extclk);2443 2444disable_dvdd:2445		regulator_disable(sensor->dvdd);2446disable_avdd:2447		regulator_disable(sensor->avdd);2448disable_dovdd:2449		regulator_disable(sensor->dovdd);2450	}2451 2452	return ret;2453}2454 2455/* Controls */2456 2457static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)2458{2459	struct v4l2_subdev *subdev = ov8865_ctrl_subdev(ctrl);2460	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2461	unsigned int index;2462	int ret;2463 2464	/* If VBLANK is altered we need to update exposure to compensate */2465	if (ctrl->id == V4L2_CID_VBLANK) {2466		int exposure_max;2467 2468		exposure_max = sensor->state.mode->output_size_y + ctrl->val -2469			       OV8865_INTEGRATION_TIME_MARGIN;2470		__v4l2_ctrl_modify_range(sensor->ctrls.exposure,2471					 sensor->ctrls.exposure->minimum,2472					 exposure_max,2473					 sensor->ctrls.exposure->step,2474					 min(sensor->ctrls.exposure->val,2475					     exposure_max));2476	}2477 2478	/* Wait for the sensor to be on before setting controls. */2479	if (pm_runtime_suspended(sensor->dev))2480		return 0;2481 2482	switch (ctrl->id) {2483	case V4L2_CID_EXPOSURE:2484		ret = ov8865_exposure_configure(sensor, ctrl->val);2485		if (ret)2486			return ret;2487		break;2488	case V4L2_CID_ANALOGUE_GAIN:2489		ret = ov8865_analog_gain_configure(sensor, ctrl->val);2490		if (ret)2491			return ret;2492		break;2493	case V4L2_CID_RED_BALANCE:2494		return ov8865_red_balance_configure(sensor, ctrl->val);2495	case V4L2_CID_BLUE_BALANCE:2496		return ov8865_blue_balance_configure(sensor, ctrl->val);2497	case V4L2_CID_HFLIP:2498		return ov8865_flip_horz_configure(sensor, !!ctrl->val);2499	case V4L2_CID_VFLIP:2500		return ov8865_flip_vert_configure(sensor, !!ctrl->val);2501	case V4L2_CID_TEST_PATTERN:2502		index = (unsigned int)ctrl->val;2503		return ov8865_test_pattern_configure(sensor, index);2504	case V4L2_CID_VBLANK:2505		return ov8865_vts_configure(sensor, ctrl->val);2506	default:2507		return -EINVAL;2508	}2509 2510	return 0;2511}2512 2513static const struct v4l2_ctrl_ops ov8865_ctrl_ops = {2514	.s_ctrl			= ov8865_s_ctrl,2515};2516 2517static int ov8865_ctrls_init(struct ov8865_sensor *sensor)2518{2519	struct ov8865_ctrls *ctrls = &sensor->ctrls;2520	struct v4l2_ctrl_handler *handler = &ctrls->handler;2521	const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;2522	const struct ov8865_mode *mode = &ov8865_modes[0];2523	struct v4l2_fwnode_device_properties props;2524	unsigned int vblank_max, vblank_def;2525	unsigned int hblank;2526	int ret;2527 2528	v4l2_ctrl_handler_init(handler, 32);2529 2530	/* Use our mutex for ctrl locking. */2531	handler->lock = &sensor->mutex;2532 2533	/* Exposure */2534 2535	ctrls->exposure = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 2,2536					    65535, 1, 32);2537 2538	/* Gain */2539 2540	v4l2_ctrl_new_std(handler, ops, V4L2_CID_ANALOGUE_GAIN, 128, 2048, 128,2541			  128);2542 2543	/* White Balance */2544 2545	v4l2_ctrl_new_std(handler, ops, V4L2_CID_RED_BALANCE, 1, 32767, 1,2546			  1024);2547 2548	v4l2_ctrl_new_std(handler, ops, V4L2_CID_BLUE_BALANCE, 1, 32767, 1,2549			  1024);2550 2551	/* Flip */2552 2553	v4l2_ctrl_new_std(handler, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);2554	v4l2_ctrl_new_std(handler, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);2555 2556	/* Test Pattern */2557 2558	v4l2_ctrl_new_std_menu_items(handler, ops, V4L2_CID_TEST_PATTERN,2559				     ARRAY_SIZE(ov8865_test_pattern_menu) - 1,2560				     0, 0, ov8865_test_pattern_menu);2561 2562	/* Blanking */2563	hblank = mode->hts - mode->output_size_x;2564	ctrls->hblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HBLANK, hblank,2565					  hblank, 1, hblank);2566 2567	if (ctrls->hblank)2568		ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;2569 2570	vblank_max = OV8865_TIMING_MAX_VTS - mode->output_size_y;2571	vblank_def = mode->vts - mode->output_size_y;2572	ctrls->vblank = v4l2_ctrl_new_std(handler, ops, V4L2_CID_VBLANK,2573					  OV8865_TIMING_MIN_VTS, vblank_max, 1,2574					  vblank_def);2575 2576	/* MIPI CSI-2 */2577 2578	ctrls->link_freq =2579		v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,2580				       ARRAY_SIZE(ov8865_link_freq_menu) - 1,2581				       0, ov8865_link_freq_menu);2582 2583	ctrls->pixel_rate =2584		v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,2585				  INT_MAX, 1, 1);2586 2587	/* set properties from fwnode (e.g. rotation, orientation) */2588	ret = v4l2_fwnode_device_parse(sensor->dev, &props);2589	if (ret)2590		goto error_ctrls;2591 2592	ret = v4l2_ctrl_new_fwnode_properties(handler, ops, &props);2593	if (ret)2594		goto error_ctrls;2595 2596	if (handler->error) {2597		ret = handler->error;2598		goto error_ctrls;2599	}2600 2601	ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;2602	ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;2603 2604	sensor->subdev.ctrl_handler = handler;2605 2606	return 0;2607 2608error_ctrls:2609	v4l2_ctrl_handler_free(handler);2610 2611	return ret;2612}2613 2614/* Subdev Video Operations */2615 2616static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)2617{2618	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2619	struct ov8865_state *state = &sensor->state;2620	int ret;2621 2622	if (enable) {2623		ret = pm_runtime_resume_and_get(sensor->dev);2624		if (ret < 0)2625			return ret;2626	}2627 2628	mutex_lock(&sensor->mutex);2629	ret = ov8865_sw_standby(sensor, !enable);2630	mutex_unlock(&sensor->mutex);2631 2632	if (ret)2633		return ret;2634 2635	state->streaming = !!enable;2636 2637	if (!enable)2638		pm_runtime_put(sensor->dev);2639 2640	return 0;2641}2642 2643static const struct v4l2_subdev_video_ops ov8865_subdev_video_ops = {2644	.s_stream		= ov8865_s_stream,2645};2646 2647/* Subdev Pad Operations */2648 2649static int ov8865_enum_mbus_code(struct v4l2_subdev *subdev,2650				 struct v4l2_subdev_state *sd_state,2651				 struct v4l2_subdev_mbus_code_enum *code_enum)2652{2653	if (code_enum->index >= ARRAY_SIZE(ov8865_mbus_codes))2654		return -EINVAL;2655 2656	code_enum->code = ov8865_mbus_codes[code_enum->index];2657 2658	return 0;2659}2660 2661static void ov8865_mbus_format_fill(struct v4l2_mbus_framefmt *mbus_format,2662				    u32 mbus_code,2663				    const struct ov8865_mode *mode)2664{2665	mbus_format->width = mode->output_size_x;2666	mbus_format->height = mode->output_size_y;2667	mbus_format->code = mbus_code;2668 2669	mbus_format->field = V4L2_FIELD_NONE;2670	mbus_format->colorspace = V4L2_COLORSPACE_RAW;2671	mbus_format->ycbcr_enc =2672		V4L2_MAP_YCBCR_ENC_DEFAULT(mbus_format->colorspace);2673	mbus_format->quantization = V4L2_QUANTIZATION_FULL_RANGE;2674	mbus_format->xfer_func =2675		V4L2_MAP_XFER_FUNC_DEFAULT(mbus_format->colorspace);2676}2677 2678static int ov8865_get_fmt(struct v4l2_subdev *subdev,2679			  struct v4l2_subdev_state *sd_state,2680			  struct v4l2_subdev_format *format)2681{2682	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2683	struct v4l2_mbus_framefmt *mbus_format = &format->format;2684 2685	mutex_lock(&sensor->mutex);2686 2687	if (format->which == V4L2_SUBDEV_FORMAT_TRY)2688		*mbus_format = *v4l2_subdev_state_get_format(sd_state,2689							     format->pad);2690	else2691		ov8865_mbus_format_fill(mbus_format, sensor->state.mbus_code,2692					sensor->state.mode);2693 2694	mutex_unlock(&sensor->mutex);2695 2696	return 0;2697}2698 2699static int ov8865_set_fmt(struct v4l2_subdev *subdev,2700			  struct v4l2_subdev_state *sd_state,2701			  struct v4l2_subdev_format *format)2702{2703	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2704	struct v4l2_mbus_framefmt *mbus_format = &format->format;2705	const struct ov8865_mode *mode;2706	u32 mbus_code = 0;2707	unsigned int hblank;2708	unsigned int index;2709	int exposure_max;2710	int ret = 0;2711 2712	mutex_lock(&sensor->mutex);2713 2714	if (sensor->state.streaming) {2715		ret = -EBUSY;2716		goto complete;2717	}2718 2719	/* Try to find requested mbus code. */2720	for (index = 0; index < ARRAY_SIZE(ov8865_mbus_codes); index++) {2721		if (ov8865_mbus_codes[index] == mbus_format->code) {2722			mbus_code = mbus_format->code;2723			break;2724		}2725	}2726 2727	/* Fallback to default. */2728	if (!mbus_code)2729		mbus_code = ov8865_mbus_codes[0];2730 2731	/* Find the mode with nearest dimensions. */2732	mode = v4l2_find_nearest_size(ov8865_modes, ARRAY_SIZE(ov8865_modes),2733				      output_size_x, output_size_y,2734				      mbus_format->width, mbus_format->height);2735	if (!mode) {2736		ret = -EINVAL;2737		goto complete;2738	}2739 2740	ov8865_mbus_format_fill(mbus_format, mbus_code, mode);2741 2742	if (format->which == V4L2_SUBDEV_FORMAT_TRY)2743		*v4l2_subdev_state_get_format(sd_state, format->pad) =2744			*mbus_format;2745	else if (sensor->state.mode != mode ||2746		 sensor->state.mbus_code != mbus_code)2747		ret = ov8865_state_configure(sensor, mode, mbus_code);2748 2749	__v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV8865_TIMING_MIN_VTS,2750				 OV8865_TIMING_MAX_VTS - mode->output_size_y,2751				 1, mode->vts - mode->output_size_y);2752 2753	hblank = mode->hts - mode->output_size_x;2754	__v4l2_ctrl_modify_range(sensor->ctrls.hblank, hblank, hblank, 1,2755				 hblank);2756 2757	exposure_max = mode->vts - OV8865_INTEGRATION_TIME_MARGIN;2758	__v4l2_ctrl_modify_range(sensor->ctrls.exposure,2759				 sensor->ctrls.exposure->minimum, exposure_max,2760				 sensor->ctrls.exposure->step,2761				 min(sensor->ctrls.exposure->val,2762				     exposure_max));2763 2764complete:2765	mutex_unlock(&sensor->mutex);2766 2767	return ret;2768}2769 2770static int ov8865_enum_frame_size(struct v4l2_subdev *subdev,2771				  struct v4l2_subdev_state *sd_state,2772				  struct v4l2_subdev_frame_size_enum *size_enum)2773{2774	const struct ov8865_mode *mode;2775 2776	if (size_enum->index >= ARRAY_SIZE(ov8865_modes))2777		return -EINVAL;2778 2779	mode = &ov8865_modes[size_enum->index];2780 2781	size_enum->min_width = size_enum->max_width = mode->output_size_x;2782	size_enum->min_height = size_enum->max_height = mode->output_size_y;2783 2784	return 0;2785}2786 2787static void2788__ov8865_get_pad_crop(struct ov8865_sensor *sensor,2789		      struct v4l2_subdev_state *state, unsigned int pad,2790		      enum v4l2_subdev_format_whence which, struct v4l2_rect *r)2791{2792	const struct ov8865_mode *mode = sensor->state.mode;2793 2794	switch (which) {2795	case V4L2_SUBDEV_FORMAT_TRY:2796		*r = *v4l2_subdev_state_get_crop(state, pad);2797		break;2798	case V4L2_SUBDEV_FORMAT_ACTIVE:2799		r->height = mode->output_size_y;2800		r->width = mode->output_size_x;2801		r->top = (OV8865_NATIVE_HEIGHT - mode->output_size_y) / 2;2802		r->left = (OV8865_NATIVE_WIDTH - mode->output_size_x) / 2;2803		break;2804	}2805}2806 2807static int ov8865_get_selection(struct v4l2_subdev *subdev,2808				struct v4l2_subdev_state *state,2809				struct v4l2_subdev_selection *sel)2810{2811	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2812 2813	switch (sel->target) {2814	case V4L2_SEL_TGT_CROP:2815		mutex_lock(&sensor->mutex);2816		__ov8865_get_pad_crop(sensor, state, sel->pad,2817				      sel->which, &sel->r);2818		mutex_unlock(&sensor->mutex);2819		break;2820	case V4L2_SEL_TGT_NATIVE_SIZE:2821		sel->r.top = 0;2822		sel->r.left = 0;2823		sel->r.width = OV8865_NATIVE_WIDTH;2824		sel->r.height = OV8865_NATIVE_HEIGHT;2825		break;2826	case V4L2_SEL_TGT_CROP_BOUNDS:2827	case V4L2_SEL_TGT_CROP_DEFAULT:2828		sel->r.top = OV8865_ACTIVE_START_TOP;2829		sel->r.left = OV8865_ACTIVE_START_LEFT;2830		sel->r.width = OV8865_ACTIVE_WIDTH;2831		sel->r.height = OV8865_ACTIVE_HEIGHT;2832		break;2833	default:2834		return -EINVAL;2835	}2836 2837	return 0;2838}2839 2840static int ov8865_get_frame_interval(struct v4l2_subdev *subdev,2841				     struct v4l2_subdev_state *sd_state,2842				     struct v4l2_subdev_frame_interval *interval)2843{2844	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2845	const struct ov8865_mode *mode;2846	unsigned int framesize;2847	unsigned int fps;2848 2849	/*2850	 * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L22851	 * subdev active state API.2852	 */2853	if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)2854		return -EINVAL;2855 2856	mutex_lock(&sensor->mutex);2857 2858	mode = sensor->state.mode;2859	framesize = mode->hts * (mode->output_size_y +2860				 sensor->ctrls.vblank->val);2861	fps = DIV_ROUND_CLOSEST(sensor->ctrls.pixel_rate->val, framesize);2862 2863	interval->interval.numerator = 1;2864	interval->interval.denominator = fps;2865 2866	mutex_unlock(&sensor->mutex);2867 2868	return 0;2869}2870 2871static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {2872	.enum_mbus_code		= ov8865_enum_mbus_code,2873	.get_fmt		= ov8865_get_fmt,2874	.set_fmt		= ov8865_set_fmt,2875	.enum_frame_size	= ov8865_enum_frame_size,2876	.get_selection		= ov8865_get_selection,2877	.set_selection		= ov8865_get_selection,2878	.get_frame_interval	= ov8865_get_frame_interval,2879	.set_frame_interval	= ov8865_get_frame_interval,2880};2881 2882static const struct v4l2_subdev_ops ov8865_subdev_ops = {2883	.video		= &ov8865_subdev_video_ops,2884	.pad		= &ov8865_subdev_pad_ops,2885};2886 2887static int ov8865_suspend(struct device *dev)2888{2889	struct i2c_client *client = to_i2c_client(dev);2890	struct v4l2_subdev *subdev = i2c_get_clientdata(client);2891	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2892	struct ov8865_state *state = &sensor->state;2893	int ret = 0;2894 2895	mutex_lock(&sensor->mutex);2896 2897	if (state->streaming) {2898		ret = ov8865_sw_standby(sensor, true);2899		if (ret)2900			goto complete;2901	}2902 2903	ret = ov8865_sensor_power(sensor, false);2904	if (ret)2905		ov8865_sw_standby(sensor, false);2906 2907complete:2908	mutex_unlock(&sensor->mutex);2909 2910	return ret;2911}2912 2913static int ov8865_resume(struct device *dev)2914{2915	struct i2c_client *client = to_i2c_client(dev);2916	struct v4l2_subdev *subdev = i2c_get_clientdata(client);2917	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);2918	struct ov8865_state *state = &sensor->state;2919	int ret = 0;2920 2921	mutex_lock(&sensor->mutex);2922 2923	ret = ov8865_sensor_power(sensor, true);2924	if (ret)2925		goto complete;2926 2927	ret = ov8865_sensor_init(sensor);2928	if (ret)2929		goto error_power;2930 2931	ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);2932	if (ret)2933		goto error_power;2934 2935	if (state->streaming) {2936		ret = ov8865_sw_standby(sensor, false);2937		if (ret)2938			goto error_power;2939	}2940 2941	goto complete;2942 2943error_power:2944	ov8865_sensor_power(sensor, false);2945 2946complete:2947	mutex_unlock(&sensor->mutex);2948 2949	return ret;2950}2951 2952static int ov8865_probe(struct i2c_client *client)2953{2954	struct device *dev = &client->dev;2955	struct fwnode_handle *handle;2956	struct ov8865_sensor *sensor;2957	struct v4l2_subdev *subdev;2958	struct media_pad *pad;2959	unsigned int rate = 0;2960	unsigned int i;2961	int ret;2962 2963	sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);2964	if (!sensor)2965		return -ENOMEM;2966 2967	sensor->dev = dev;2968	sensor->i2c_client = client;2969 2970	/* Regulators */2971 2972	/* DVDD: digital core */2973	sensor->dvdd = devm_regulator_get(dev, "dvdd");2974	if (IS_ERR(sensor->dvdd))2975		return dev_err_probe(dev, PTR_ERR(sensor->dvdd),2976				     "cannot get DVDD regulator\n");2977 2978	/* DOVDD: digital I/O */2979	sensor->dovdd = devm_regulator_get(dev, "dovdd");2980	if (IS_ERR(sensor->dovdd))2981		return dev_err_probe(dev, PTR_ERR(sensor->dovdd),2982				     "cannot get DOVDD regulator\n");2983 2984	/* AVDD: analog */2985	sensor->avdd = devm_regulator_get(dev, "avdd");2986	if (IS_ERR(sensor->avdd))2987		return dev_err_probe(dev, PTR_ERR(sensor->avdd),2988				     "cannot get AVDD (analog) regulator\n");2989 2990	/* Graph Endpoint */2991 2992	handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);2993	if (!handle)2994		return -EPROBE_DEFER;2995 2996	sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;2997 2998	ret = v4l2_fwnode_endpoint_alloc_parse(handle, &sensor->endpoint);2999	fwnode_handle_put(handle);3000	if (ret) {3001		dev_err(dev, "failed to parse endpoint node\n");3002		return ret;3003	}3004 3005	/* GPIOs */3006 3007	sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown",3008						    GPIOD_OUT_HIGH);3009	if (IS_ERR(sensor->powerdown)) {3010		ret = PTR_ERR(sensor->powerdown);3011		goto error_endpoint;3012	}3013 3014	sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);3015	if (IS_ERR(sensor->reset)) {3016		ret = PTR_ERR(sensor->reset);3017		goto error_endpoint;3018	}3019 3020	/* External Clock */3021 3022	sensor->extclk = devm_clk_get(dev, NULL);3023	if (PTR_ERR(sensor->extclk) == -ENOENT) {3024		dev_info(dev, "no external clock found, continuing...\n");3025		sensor->extclk = NULL;3026	} else if (IS_ERR(sensor->extclk)) {3027		dev_err(dev, "failed to get external clock\n");3028		ret = PTR_ERR(sensor->extclk);3029		goto error_endpoint;3030	}3031 3032	/*3033	 * We could have either a 24MHz or 19.2MHz clock rate from either dt or3034	 * ACPI...but we also need to support the weird IPU3 case which will3035	 * have an external clock AND a clock-frequency property. Check for the3036	 * clock-frequency property and if found, set that rate if we managed3037	 * to acquire a clock. This should cover the ACPI case. If the system3038	 * uses devicetree then the configured rate should already be set, so3039	 * we can just read it.3040	 */3041	ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",3042				       &rate);3043	if (!ret && sensor->extclk) {3044		ret = clk_set_rate(sensor->extclk, rate);3045		if (ret) {3046			dev_err_probe(dev, ret, "failed to set clock rate\n");3047			goto error_endpoint;3048		}3049	} else if (ret && !sensor->extclk) {3050		dev_err_probe(dev, ret, "invalid clock config\n");3051		goto error_endpoint;3052	}3053 3054	sensor->extclk_rate = rate ? rate : clk_get_rate(sensor->extclk);3055 3056	for (i = 0; i < ARRAY_SIZE(supported_extclk_rates); i++) {3057		if (sensor->extclk_rate == supported_extclk_rates[i])3058			break;3059	}3060 3061	if (i == ARRAY_SIZE(supported_extclk_rates)) {3062		dev_err(dev, "clock rate %lu Hz is unsupported\n",3063			sensor->extclk_rate);3064		ret = -EINVAL;3065		goto error_endpoint;3066	}3067 3068	sensor->pll_configs = ov8865_pll_configs[i];3069 3070	/* Subdev, entity and pad */3071 3072	subdev = &sensor->subdev;3073	v4l2_i2c_subdev_init(subdev, client, &ov8865_subdev_ops);3074 3075	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;3076	subdev->entity.function = MEDIA_ENT_F_CAM_SENSOR;3077 3078	pad = &sensor->pad;3079	pad->flags = MEDIA_PAD_FL_SOURCE;3080 3081	ret = media_entity_pads_init(&subdev->entity, 1, pad);3082	if (ret)3083		goto error_entity;3084 3085	/* Mutex */3086 3087	mutex_init(&sensor->mutex);3088 3089	/* Sensor */3090 3091	ret = ov8865_ctrls_init(sensor);3092	if (ret)3093		goto error_mutex;3094 3095	mutex_lock(&sensor->mutex);3096	ret = ov8865_state_init(sensor);3097	mutex_unlock(&sensor->mutex);3098	if (ret)3099		goto error_ctrls;3100 3101	/* Runtime PM */3102 3103	pm_runtime_set_suspended(sensor->dev);3104	pm_runtime_enable(sensor->dev);3105 3106	/* V4L2 subdev register */3107 3108	ret = v4l2_async_register_subdev_sensor(subdev);3109	if (ret)3110		goto error_pm;3111 3112	return 0;3113 3114error_pm:3115	pm_runtime_disable(sensor->dev);3116 3117error_ctrls:3118	v4l2_ctrl_handler_free(&sensor->ctrls.handler);3119 3120error_mutex:3121	mutex_destroy(&sensor->mutex);3122 3123error_entity:3124	media_entity_cleanup(&sensor->subdev.entity);3125 3126error_endpoint:3127	v4l2_fwnode_endpoint_free(&sensor->endpoint);3128 3129	return ret;3130}3131 3132static void ov8865_remove(struct i2c_client *client)3133{3134	struct v4l2_subdev *subdev = i2c_get_clientdata(client);3135	struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);3136 3137	v4l2_async_unregister_subdev(subdev);3138	pm_runtime_disable(sensor->dev);3139	v4l2_ctrl_handler_free(&sensor->ctrls.handler);3140	mutex_destroy(&sensor->mutex);3141	media_entity_cleanup(&subdev->entity);3142 3143	v4l2_fwnode_endpoint_free(&sensor->endpoint);3144}3145 3146static const struct dev_pm_ops ov8865_pm_ops = {3147	SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)3148};3149 3150static const struct acpi_device_id ov8865_acpi_match[] = {3151	{"INT347A"},3152	{ }3153};3154MODULE_DEVICE_TABLE(acpi, ov8865_acpi_match);3155 3156static const struct of_device_id ov8865_of_match[] = {3157	{ .compatible = "ovti,ov8865" },3158	{ }3159};3160MODULE_DEVICE_TABLE(of, ov8865_of_match);3161 3162static struct i2c_driver ov8865_driver = {3163	.driver = {3164		.name = "ov8865",3165		.of_match_table = ov8865_of_match,3166		.acpi_match_table = ov8865_acpi_match,3167		.pm = &ov8865_pm_ops,3168	},3169	.probe = ov8865_probe,3170	.remove = ov8865_remove,3171};3172 3173module_i2c_driver(ov8865_driver);3174 3175MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>");3176MODULE_DESCRIPTION("V4L2 driver for the OmniVision OV8865 image sensor");3177MODULE_LICENSE("GPL v2");3178