]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/i2c/ov8865.c
Merge tag 'firewire-update' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[mirror_ubuntu-jammy-kernel.git] / drivers / media / i2c / ov8865.c
CommitLineData
11c0d8fd
PK
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright 2020 Kévin L'hôpital <kevin.lhopital@bootlin.com>
4 * Copyright 2020 Bootlin
5 * 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/module.h>
13#include <linux/of_graph.h>
14#include <linux/pm_runtime.h>
15#include <linux/regulator/consumer.h>
16#include <linux/videodev2.h>
17#include <media/v4l2-ctrls.h>
18#include <media/v4l2-device.h>
19#include <media/v4l2-fwnode.h>
20#include <media/v4l2-image-sizes.h>
21#include <media/v4l2-mediabus.h>
22
23/* Clock rate */
24
25#define OV8865_EXTCLK_RATE 24000000
26
27/* Register definitions */
28
29/* System */
30
31#define OV8865_SW_STANDBY_REG 0x100
32#define OV8865_SW_STANDBY_STREAM_ON BIT(0)
33
34#define OV8865_SW_RESET_REG 0x103
35#define OV8865_SW_RESET_RESET BIT(0)
36
37#define OV8865_PLL_CTRL0_REG 0x300
38#define OV8865_PLL_CTRL0_PRE_DIV(v) ((v) & GENMASK(2, 0))
39#define OV8865_PLL_CTRL1_REG 0x301
40#define OV8865_PLL_CTRL1_MUL_H(v) (((v) & GENMASK(9, 8)) >> 8)
41#define OV8865_PLL_CTRL2_REG 0x302
42#define OV8865_PLL_CTRL2_MUL_L(v) ((v) & GENMASK(7, 0))
43#define OV8865_PLL_CTRL3_REG 0x303
44#define OV8865_PLL_CTRL3_M_DIV(v) (((v) - 1) & GENMASK(3, 0))
45#define OV8865_PLL_CTRL4_REG 0x304
46#define OV8865_PLL_CTRL4_MIPI_DIV(v) ((v) & GENMASK(1, 0))
47#define OV8865_PLL_CTRL5_REG 0x305
48#define OV8865_PLL_CTRL5_SYS_PRE_DIV(v) ((v) & GENMASK(1, 0))
49#define OV8865_PLL_CTRL6_REG 0x306
50#define OV8865_PLL_CTRL6_SYS_DIV(v) (((v) - 1) & BIT(0))
51
52#define OV8865_PLL_CTRL8_REG 0x308
53#define OV8865_PLL_CTRL9_REG 0x309
54#define OV8865_PLL_CTRLA_REG 0x30a
55#define OV8865_PLL_CTRLA_PRE_DIV_HALF(v) (((v) - 1) & BIT(0))
56#define OV8865_PLL_CTRLB_REG 0x30b
57#define OV8865_PLL_CTRLB_PRE_DIV(v) ((v) & GENMASK(2, 0))
58#define OV8865_PLL_CTRLC_REG 0x30c
59#define OV8865_PLL_CTRLC_MUL_H(v) (((v) & GENMASK(9, 8)) >> 8)
60#define OV8865_PLL_CTRLD_REG 0x30d
61#define OV8865_PLL_CTRLD_MUL_L(v) ((v) & GENMASK(7, 0))
62#define OV8865_PLL_CTRLE_REG 0x30e
63#define OV8865_PLL_CTRLE_SYS_DIV(v) ((v) & GENMASK(2, 0))
64#define OV8865_PLL_CTRLF_REG 0x30f
65#define OV8865_PLL_CTRLF_SYS_PRE_DIV(v) (((v) - 1) & GENMASK(3, 0))
66#define OV8865_PLL_CTRL10_REG 0x310
67#define OV8865_PLL_CTRL11_REG 0x311
68#define OV8865_PLL_CTRL12_REG 0x312
69#define OV8865_PLL_CTRL12_PRE_DIV_HALF(v) ((((v) - 1) << 4) & BIT(4))
70#define OV8865_PLL_CTRL12_DAC_DIV(v) (((v) - 1) & GENMASK(3, 0))
71
72#define OV8865_PLL_CTRL1B_REG 0x31b
73#define OV8865_PLL_CTRL1C_REG 0x31c
74
75#define OV8865_PLL_CTRL1E_REG 0x31e
76#define OV8865_PLL_CTRL1E_PLL1_NO_LAT BIT(3)
77
78#define OV8865_PAD_OEN0_REG 0x3000
79
80#define OV8865_PAD_OEN2_REG 0x3002
81
82#define OV8865_CLK_RST5_REG 0x3005
83
84#define OV8865_CHIP_ID_HH_REG 0x300a
85#define OV8865_CHIP_ID_HH_VALUE 0x00
86#define OV8865_CHIP_ID_H_REG 0x300b
87#define OV8865_CHIP_ID_H_VALUE 0x88
88#define OV8865_CHIP_ID_L_REG 0x300c
89#define OV8865_CHIP_ID_L_VALUE 0x65
90#define OV8865_PAD_OUT2_REG 0x300d
91
92#define OV8865_PAD_SEL2_REG 0x3010
93#define OV8865_PAD_PK_REG 0x3011
94#define OV8865_PAD_PK_DRIVE_STRENGTH_1X (0 << 5)
95#define OV8865_PAD_PK_DRIVE_STRENGTH_2X (1 << 5)
96#define OV8865_PAD_PK_DRIVE_STRENGTH_3X (2 << 5)
97#define OV8865_PAD_PK_DRIVE_STRENGTH_4X (3 << 5)
98
99#define OV8865_PUMP_CLK_DIV_REG 0x3015
100#define OV8865_PUMP_CLK_DIV_PUMP_N(v) (((v) << 4) & GENMASK(6, 4))
101#define OV8865_PUMP_CLK_DIV_PUMP_P(v) ((v) & GENMASK(2, 0))
102
103#define OV8865_MIPI_SC_CTRL0_REG 0x3018
104#define OV8865_MIPI_SC_CTRL0_LANES(v) ((((v) - 1) << 5) & \
105 GENMASK(7, 5))
106#define OV8865_MIPI_SC_CTRL0_MIPI_EN BIT(4)
107#define OV8865_MIPI_SC_CTRL0_UNKNOWN BIT(1)
108#define OV8865_MIPI_SC_CTRL0_LANES_PD_MIPI BIT(0)
109#define OV8865_MIPI_SC_CTRL1_REG 0x3019
110#define OV8865_CLK_RST0_REG 0x301a
111#define OV8865_CLK_RST1_REG 0x301b
112#define OV8865_CLK_RST2_REG 0x301c
113#define OV8865_CLK_RST3_REG 0x301d
114#define OV8865_CLK_RST4_REG 0x301e
115
116#define OV8865_PCLK_SEL_REG 0x3020
117#define OV8865_PCLK_SEL_PCLK_DIV_MASK BIT(3)
118#define OV8865_PCLK_SEL_PCLK_DIV(v) ((((v) - 1) << 3) & BIT(3))
119
120#define OV8865_MISC_CTRL_REG 0x3021
121#define OV8865_MIPI_SC_CTRL2_REG 0x3022
122#define OV8865_MIPI_SC_CTRL2_CLK_LANES_PD_MIPI BIT(1)
123#define OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC BIT(0)
124
125#define OV8865_MIPI_BIT_SEL_REG 0x3031
126#define OV8865_MIPI_BIT_SEL(v) (((v) << 0) & GENMASK(4, 0))
127#define OV8865_CLK_SEL0_REG 0x3032
128#define OV8865_CLK_SEL0_PLL1_SYS_SEL(v) (((v) << 7) & BIT(7))
129#define OV8865_CLK_SEL1_REG 0x3033
130#define OV8865_CLK_SEL1_MIPI_EOF BIT(5)
131#define OV8865_CLK_SEL1_UNKNOWN BIT(2)
132#define OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK BIT(1)
133#define OV8865_CLK_SEL1_PLL_SCLK_SEL(v) (((v) << 1) & BIT(1))
134
135#define OV8865_SCLK_CTRL_REG 0x3106
136#define OV8865_SCLK_CTRL_SCLK_DIV(v) (((v) << 4) & GENMASK(7, 4))
137#define OV8865_SCLK_CTRL_SCLK_PRE_DIV(v) (((v) << 2) & GENMASK(3, 2))
138#define OV8865_SCLK_CTRL_UNKNOWN BIT(0)
139
140/* Exposure/gain */
141
142#define OV8865_EXPOSURE_CTRL_HH_REG 0x3500
143#define OV8865_EXPOSURE_CTRL_HH(v) (((v) & GENMASK(19, 16)) >> 16)
144#define OV8865_EXPOSURE_CTRL_H_REG 0x3501
145#define OV8865_EXPOSURE_CTRL_H(v) (((v) & GENMASK(15, 8)) >> 8)
146#define OV8865_EXPOSURE_CTRL_L_REG 0x3502
147#define OV8865_EXPOSURE_CTRL_L(v) ((v) & GENMASK(7, 0))
148#define OV8865_EXPOSURE_GAIN_MANUAL_REG 0x3503
149
150#define OV8865_GAIN_CTRL_H_REG 0x3508
151#define OV8865_GAIN_CTRL_H(v) (((v) & GENMASK(12, 8)) >> 8)
152#define OV8865_GAIN_CTRL_L_REG 0x3509
153#define OV8865_GAIN_CTRL_L(v) ((v) & GENMASK(7, 0))
154
155/* Timing */
156
157#define OV8865_CROP_START_X_H_REG 0x3800
158#define OV8865_CROP_START_X_H(v) (((v) & GENMASK(11, 8)) >> 8)
159#define OV8865_CROP_START_X_L_REG 0x3801
160#define OV8865_CROP_START_X_L(v) ((v) & GENMASK(7, 0))
161#define OV8865_CROP_START_Y_H_REG 0x3802
162#define OV8865_CROP_START_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
163#define OV8865_CROP_START_Y_L_REG 0x3803
164#define OV8865_CROP_START_Y_L(v) ((v) & GENMASK(7, 0))
165#define OV8865_CROP_END_X_H_REG 0x3804
166#define OV8865_CROP_END_X_H(v) (((v) & GENMASK(11, 8)) >> 8)
167#define OV8865_CROP_END_X_L_REG 0x3805
168#define OV8865_CROP_END_X_L(v) ((v) & GENMASK(7, 0))
169#define OV8865_CROP_END_Y_H_REG 0x3806
170#define OV8865_CROP_END_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
171#define OV8865_CROP_END_Y_L_REG 0x3807
172#define OV8865_CROP_END_Y_L(v) ((v) & GENMASK(7, 0))
173#define OV8865_OUTPUT_SIZE_X_H_REG 0x3808
174#define OV8865_OUTPUT_SIZE_X_H(v) (((v) & GENMASK(11, 8)) >> 8)
175#define OV8865_OUTPUT_SIZE_X_L_REG 0x3809
176#define OV8865_OUTPUT_SIZE_X_L(v) ((v) & GENMASK(7, 0))
177#define OV8865_OUTPUT_SIZE_Y_H_REG 0x380a
178#define OV8865_OUTPUT_SIZE_Y_H(v) (((v) & GENMASK(11, 8)) >> 8)
179#define OV8865_OUTPUT_SIZE_Y_L_REG 0x380b
180#define OV8865_OUTPUT_SIZE_Y_L(v) ((v) & GENMASK(7, 0))
181#define OV8865_HTS_H_REG 0x380c
182#define OV8865_HTS_H(v) (((v) & GENMASK(11, 8)) >> 8)
183#define OV8865_HTS_L_REG 0x380d
184#define OV8865_HTS_L(v) ((v) & GENMASK(7, 0))
185#define OV8865_VTS_H_REG 0x380e
186#define OV8865_VTS_H(v) (((v) & GENMASK(11, 8)) >> 8)
187#define OV8865_VTS_L_REG 0x380f
188#define OV8865_VTS_L(v) ((v) & GENMASK(7, 0))
189#define OV8865_OFFSET_X_H_REG 0x3810
190#define OV8865_OFFSET_X_H(v) (((v) & GENMASK(15, 8)) >> 8)
191#define OV8865_OFFSET_X_L_REG 0x3811
192#define OV8865_OFFSET_X_L(v) ((v) & GENMASK(7, 0))
193#define OV8865_OFFSET_Y_H_REG 0x3812
194#define OV8865_OFFSET_Y_H(v) (((v) & GENMASK(14, 8)) >> 8)
195#define OV8865_OFFSET_Y_L_REG 0x3813
196#define OV8865_OFFSET_Y_L(v) ((v) & GENMASK(7, 0))
197#define OV8865_INC_X_ODD_REG 0x3814
198#define OV8865_INC_X_ODD(v) ((v) & GENMASK(4, 0))
199#define OV8865_INC_X_EVEN_REG 0x3815
200#define OV8865_INC_X_EVEN(v) ((v) & GENMASK(4, 0))
201#define OV8865_VSYNC_START_H_REG 0x3816
202#define OV8865_VSYNC_START_H(v) (((v) & GENMASK(15, 8)) >> 8)
203#define OV8865_VSYNC_START_L_REG 0x3817
204#define OV8865_VSYNC_START_L(v) ((v) & GENMASK(7, 0))
205#define OV8865_VSYNC_END_H_REG 0x3818
206#define OV8865_VSYNC_END_H(v) (((v) & GENMASK(15, 8)) >> 8)
207#define OV8865_VSYNC_END_L_REG 0x3819
208#define OV8865_VSYNC_END_L(v) ((v) & GENMASK(7, 0))
209#define OV8865_HSYNC_FIRST_H_REG 0x381a
210#define OV8865_HSYNC_FIRST_H(v) (((v) & GENMASK(15, 8)) >> 8)
211#define OV8865_HSYNC_FIRST_L_REG 0x381b
212#define OV8865_HSYNC_FIRST_L(v) ((v) & GENMASK(7, 0))
213
214#define OV8865_FORMAT1_REG 0x3820
215#define OV8865_FORMAT1_FLIP_VERT_ISP_EN BIT(2)
216#define OV8865_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1)
217#define OV8865_FORMAT2_REG 0x3821
218#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
11c0d8fd
PK
226#define OV8865_INC_Y_ODD_REG 0x382a
227#define OV8865_INC_Y_ODD(v) ((v) & GENMASK(4, 0))
228#define OV8865_INC_Y_EVEN_REG 0x382b
229#define OV8865_INC_Y_EVEN(v) ((v) & GENMASK(4, 0))
230
231#define OV8865_ABLC_NUM_REG 0x3830
232#define OV8865_ABLC_NUM(v) ((v) & GENMASK(4, 0))
233
234#define OV8865_ZLINE_NUM_REG 0x3836
235#define OV8865_ZLINE_NUM(v) ((v) & GENMASK(4, 0))
236
237#define OV8865_AUTO_SIZE_CTRL_REG 0x3841
238#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 0x3842
245#define OV8865_AUTO_SIZE_X_OFFSET_L_REG 0x3843
246#define OV8865_AUTO_SIZE_Y_OFFSET_H_REG 0x3844
247#define OV8865_AUTO_SIZE_Y_OFFSET_L_REG 0x3845
248#define OV8865_AUTO_SIZE_BOUNDARIES_REG 0x3846
249#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 0x3f08
255
256/* Black Level */
257
258#define OV8865_BLC_CTRL0_REG 0x4000
259#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 0x4001
268#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 0x4002
277#define OV8865_BLC_CTRL3_REG 0x4003
278#define OV8865_BLC_CTRL4_REG 0x4004
279#define OV8865_BLC_CTRL5_REG 0x4005
280#define OV8865_BLC_CTRL6_REG 0x4006
281#define OV8865_BLC_CTRL7_REG 0x4007
282#define OV8865_BLC_CTRL8_REG 0x4008
283#define OV8865_BLC_CTRL9_REG 0x4009
284#define OV8865_BLC_CTRLA_REG 0x400a
285#define OV8865_BLC_CTRLB_REG 0x400b
286#define OV8865_BLC_CTRLC_REG 0x400c
287#define OV8865_BLC_CTRLD_REG 0x400d
288#define OV8865_BLC_CTRLD_OFFSET_TRIGGER(v) ((v) & GENMASK(7, 0))
289
290#define OV8865_BLC_CTRL1F_REG 0x401f
291#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 0x4020
296#define OV8865_BLC_ANCHOR_LEFT_START_H(v) (((v) & GENMASK(11, 8)) >> 8)
297#define OV8865_BLC_ANCHOR_LEFT_START_L_REG 0x4021
298#define OV8865_BLC_ANCHOR_LEFT_START_L(v) ((v) & GENMASK(7, 0))
299#define OV8865_BLC_ANCHOR_LEFT_END_H_REG 0x4022
300#define OV8865_BLC_ANCHOR_LEFT_END_H(v) (((v) & GENMASK(11, 8)) >> 8)
301#define OV8865_BLC_ANCHOR_LEFT_END_L_REG 0x4023
302#define OV8865_BLC_ANCHOR_LEFT_END_L(v) ((v) & GENMASK(7, 0))
303#define OV8865_BLC_ANCHOR_RIGHT_START_H_REG 0x4024
304#define OV8865_BLC_ANCHOR_RIGHT_START_H(v) (((v) & GENMASK(11, 8)) >> 8)
305#define OV8865_BLC_ANCHOR_RIGHT_START_L_REG 0x4025
306#define OV8865_BLC_ANCHOR_RIGHT_START_L(v) ((v) & GENMASK(7, 0))
307#define OV8865_BLC_ANCHOR_RIGHT_END_H_REG 0x4026
308#define OV8865_BLC_ANCHOR_RIGHT_END_H(v) (((v) & GENMASK(11, 8)) >> 8)
309#define OV8865_BLC_ANCHOR_RIGHT_END_L_REG 0x4027
310#define OV8865_BLC_ANCHOR_RIGHT_END_L(v) ((v) & GENMASK(7, 0))
311
312#define OV8865_BLC_TOP_ZLINE_START_REG 0x4028
313#define OV8865_BLC_TOP_ZLINE_START(v) ((v) & GENMASK(5, 0))
314#define OV8865_BLC_TOP_ZLINE_NUM_REG 0x4029
315#define OV8865_BLC_TOP_ZLINE_NUM(v) ((v) & GENMASK(4, 0))
316#define OV8865_BLC_TOP_BLKLINE_START_REG 0x402a
317#define OV8865_BLC_TOP_BLKLINE_START(v) ((v) & GENMASK(5, 0))
318#define OV8865_BLC_TOP_BLKLINE_NUM_REG 0x402b
319#define OV8865_BLC_TOP_BLKLINE_NUM(v) ((v) & GENMASK(4, 0))
320#define OV8865_BLC_BOT_ZLINE_START_REG 0x402c
321#define OV8865_BLC_BOT_ZLINE_START(v) ((v) & GENMASK(5, 0))
322#define OV8865_BLC_BOT_ZLINE_NUM_REG 0x402d
323#define OV8865_BLC_BOT_ZLINE_NUM(v) ((v) & GENMASK(4, 0))
324#define OV8865_BLC_BOT_BLKLINE_START_REG 0x402e
325#define OV8865_BLC_BOT_BLKLINE_START(v) ((v) & GENMASK(5, 0))
326#define OV8865_BLC_BOT_BLKLINE_NUM_REG 0x402f
327#define OV8865_BLC_BOT_BLKLINE_NUM(v) ((v) & GENMASK(4, 0))
328
329#define OV8865_BLC_OFFSET_LIMIT_REG 0x4034
330#define OV8865_BLC_OFFSET_LIMIT(v) ((v) & GENMASK(7, 0))
331
332/* VFIFO */
333
334#define OV8865_VFIFO_READ_START_H_REG 0x4600
335#define OV8865_VFIFO_READ_START_H(v) (((v) & GENMASK(15, 8)) >> 8)
336#define OV8865_VFIFO_READ_START_L_REG 0x4601
337#define OV8865_VFIFO_READ_START_L(v) ((v) & GENMASK(7, 0))
338
339/* MIPI */
340
341#define OV8865_MIPI_CTRL0_REG 0x4800
342#define OV8865_MIPI_CTRL1_REG 0x4801
343#define OV8865_MIPI_CTRL2_REG 0x4802
344#define OV8865_MIPI_CTRL3_REG 0x4803
345#define OV8865_MIPI_CTRL4_REG 0x4804
346#define OV8865_MIPI_CTRL5_REG 0x4805
347#define OV8865_MIPI_CTRL6_REG 0x4806
348#define OV8865_MIPI_CTRL7_REG 0x4807
349#define OV8865_MIPI_CTRL8_REG 0x4808
350
351#define OV8865_MIPI_FCNT_MAX_H_REG 0x4810
352#define OV8865_MIPI_FCNT_MAX_L_REG 0x4811
353
354#define OV8865_MIPI_CTRL13_REG 0x4813
355#define OV8865_MIPI_CTRL14_REG 0x4814
356#define OV8865_MIPI_CTRL15_REG 0x4815
357#define OV8865_MIPI_EMBEDDED_DT_REG 0x4816
358
359#define OV8865_MIPI_HS_ZERO_MIN_H_REG 0x4818
360#define OV8865_MIPI_HS_ZERO_MIN_L_REG 0x4819
361#define OV8865_MIPI_HS_TRAIL_MIN_H_REG 0x481a
362#define OV8865_MIPI_HS_TRAIL_MIN_L_REG 0x481b
363#define OV8865_MIPI_CLK_ZERO_MIN_H_REG 0x481c
364#define OV8865_MIPI_CLK_ZERO_MIN_L_REG 0x481d
365#define OV8865_MIPI_CLK_PREPARE_MAX_REG 0x481e
366#define OV8865_MIPI_CLK_PREPARE_MIN_REG 0x481f
367#define OV8865_MIPI_CLK_POST_MIN_H_REG 0x4820
368#define OV8865_MIPI_CLK_POST_MIN_L_REG 0x4821
369#define OV8865_MIPI_CLK_TRAIL_MIN_H_REG 0x4822
370#define OV8865_MIPI_CLK_TRAIL_MIN_L_REG 0x4823
371#define OV8865_MIPI_LPX_P_MIN_H_REG 0x4824
372#define OV8865_MIPI_LPX_P_MIN_L_REG 0x4825
373#define OV8865_MIPI_HS_PREPARE_MIN_REG 0x4826
374#define OV8865_MIPI_HS_PREPARE_MAX_REG 0x4827
375#define OV8865_MIPI_HS_EXIT_MIN_H_REG 0x4828
376#define OV8865_MIPI_HS_EXIT_MIN_L_REG 0x4829
377#define OV8865_MIPI_UI_HS_ZERO_MIN_REG 0x482a
378#define OV8865_MIPI_UI_HS_TRAIL_MIN_REG 0x482b
379#define OV8865_MIPI_UI_CLK_ZERO_MIN_REG 0x482c
380#define OV8865_MIPI_UI_CLK_PREPARE_REG 0x482d
381#define OV8865_MIPI_UI_CLK_POST_MIN_REG 0x482e
382#define OV8865_MIPI_UI_CLK_TRAIL_MIN_REG 0x482f
383#define OV8865_MIPI_UI_LPX_P_MIN_REG 0x4830
384#define OV8865_MIPI_UI_HS_PREPARE_REG 0x4831
385#define OV8865_MIPI_UI_HS_EXIT_MIN_REG 0x4832
386#define OV8865_MIPI_PKT_START_SIZE_REG 0x4833
387
388#define OV8865_MIPI_PCLK_PERIOD_REG 0x4837
389#define OV8865_MIPI_LP_GPIO0_REG 0x4838
390#define OV8865_MIPI_LP_GPIO1_REG 0x4839
391
392#define OV8865_MIPI_CTRL3C_REG 0x483c
393#define OV8865_MIPI_LP_GPIO4_REG 0x483d
394
395#define OV8865_MIPI_CTRL4A_REG 0x484a
396#define OV8865_MIPI_CTRL4B_REG 0x484b
397#define OV8865_MIPI_CTRL4C_REG 0x484c
398#define OV8865_MIPI_LANE_TEST_PATTERN_REG 0x484d
399#define OV8865_MIPI_FRAME_END_DELAY_REG 0x484e
400#define OV8865_MIPI_CLOCK_TEST_PATTERN_REG 0x484f
401#define OV8865_MIPI_LANE_SEL01_REG 0x4850
402#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 0x4851
405#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 0x5000
411#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 0x5001
416#define OV8865_ISP_CTRL1_BLC_EN BIT(0)
417#define OV8865_ISP_CTRL2_REG 0x5002
418#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 0x5003
422
423#define OV8865_ISP_GAIN_RED_H_REG 0x5018
424#define OV8865_ISP_GAIN_RED_H(v) (((v) & GENMASK(13, 6)) >> 6)
425#define OV8865_ISP_GAIN_RED_L_REG 0x5019
426#define OV8865_ISP_GAIN_RED_L(v) ((v) & GENMASK(5, 0))
427#define OV8865_ISP_GAIN_GREEN_H_REG 0x501a
428#define OV8865_ISP_GAIN_GREEN_H(v) (((v) & GENMASK(13, 6)) >> 6)
429#define OV8865_ISP_GAIN_GREEN_L_REG 0x501b
430#define OV8865_ISP_GAIN_GREEN_L(v) ((v) & GENMASK(5, 0))
431#define OV8865_ISP_GAIN_BLUE_H_REG 0x501c
432#define OV8865_ISP_GAIN_BLUE_H(v) (((v) & GENMASK(13, 6)) >> 6)
433#define OV8865_ISP_GAIN_BLUE_L_REG 0x501d
434#define OV8865_ISP_GAIN_BLUE_L(v) ((v) & GENMASK(5, 0))
435
436/* VarioPixel */
437
438#define OV8865_VAP_CTRL0_REG 0x5900
439#define OV8865_VAP_CTRL1_REG 0x5901
440#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 0x5e00
447#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 0
452#define OV8865_PRE_CTRL0_PATTERN_RANDOM_DATA 1
453#define OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES 2
454#define OV8865_PRE_CTRL0_PATTERN_BLACK 3
455
456/* Macros */
457
458#define ov8865_subdev_sensor(s) \
459 container_of(s, struct ov8865_sensor, subdev)
460
461#define ov8865_ctrl_subdev(c) \
36e4f2b2
PK
462 (&container_of((c)->handler, struct ov8865_sensor, \
463 ctrls.handler)->subdev)
11c0d8fd
PK
464
465/* Data structures */
466
467struct ov8865_register_value {
468 u16 address;
469 u8 value;
470 unsigned int delay_ms;
471};
472
473/*
474 * PLL1 Clock Tree:
475 *
476 * +-< EXTCLK
477 * |
478 * +-+ pll_pre_div_half (0x30a [0])
479 * |
480 * +-+ pll_pre_div (0x300 [2:0], special values:
481 * | 0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 4, 7: 8)
482 * +-+ pll_mul (0x301 [1:0], 0x302 [7:0])
483 * |
484 * +-+ m_div (0x303 [3:0])
485 * | |
486 * | +-> PHY_SCLK
487 * | |
488 * | +-+ mipi_div (0x304 [1:0], special values: 0: 4, 1: 5, 2: 6, 3: 8)
489 * | |
490 * | +-+ pclk_div (0x3020 [3])
491 * | |
492 * | +-> PCLK
493 * |
494 * +-+ sys_pre_div (0x305 [1:0], special values: 0: 3, 1: 4, 2: 5, 3: 6)
495 * |
496 * +-+ sys_div (0x306 [0])
497 * |
498 * +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)
499 * |
500 * +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)
501 * |
502 * +-+ sclk_pre_div (0x3106 [3:2], special values:
503 * | 0: 1, 1: 2, 2: 4, 3: 1)
504 * |
505 * +-+ sclk_div (0x3106 [7:4], special values: 0: 1)
506 * |
507 * +-> SCLK
508 */
509
510struct ov8865_pll1_config {
511 unsigned int pll_pre_div_half;
512 unsigned int pll_pre_div;
513 unsigned int pll_mul;
514 unsigned int m_div;
515 unsigned int mipi_div;
516 unsigned int pclk_div;
517 unsigned int sys_pre_div;
518 unsigned int sys_div;
519};
520
521/*
522 * PLL2 Clock Tree:
523 *
524 * +-< EXTCLK
525 * |
526 * +-+ pll_pre_div_half (0x312 [4])
527 * |
528 * +-+ pll_pre_div (0x30b [2:0], special values:
529 * | 0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 4, 7: 8)
530 * +-+ pll_mul (0x30c [1:0], 0x30d [7:0])
531 * |
532 * +-+ dac_div (0x312 [3:0])
533 * | |
534 * | +-> DAC_CLK
535 * |
536 * +-+ sys_pre_div (0x30f [3:0])
537 * |
538 * +-+ sys_div (0x30e [2:0], special values:
539 * | 0: 1, 1: 1.5, 3: 2.5, 4: 3, 5: 3.5, 6: 4, 7:5)
540 * |
541 * +-+ sys_sel (0x3032 [7], 0: PLL1, 1: PLL2)
542 * |
543 * +-+ sclk_sel (0x3033 [1], 0: sys_sel, 1: PLL2 DAC_CLK)
544 * |
545 * +-+ sclk_pre_div (0x3106 [3:2], special values:
546 * | 0: 1, 1: 2, 2: 4, 3: 1)
547 * |
548 * +-+ sclk_div (0x3106 [7:4], special values: 0: 1)
549 * |
550 * +-> SCLK
551 */
552
553struct ov8865_pll2_config {
554 unsigned int pll_pre_div_half;
555 unsigned int pll_pre_div;
556 unsigned int pll_mul;
557 unsigned int dac_div;
558 unsigned int sys_pre_div;
559 unsigned int sys_div;
560};
561
562struct ov8865_sclk_config {
563 unsigned int sys_sel;
564 unsigned int sclk_sel;
565 unsigned int sclk_pre_div;
566 unsigned int sclk_div;
567};
568
569/*
570 * General formulas for (array-centered) mode calculation:
571 * - photo_array_width = 3296
572 * - crop_start_x = (photo_array_width - output_size_x) / 2
573 * - crop_end_x = crop_start_x + offset_x + output_size_x - 1
574 *
575 * - photo_array_height = 2480
576 * - crop_start_y = (photo_array_height - output_size_y) / 2
577 * - crop_end_y = crop_start_y + offset_y + output_size_y - 1
578 */
579
580struct ov8865_mode {
581 unsigned int crop_start_x;
582 unsigned int offset_x;
583 unsigned int output_size_x;
584 unsigned int crop_end_x;
585 unsigned int hts;
586
587 unsigned int crop_start_y;
588 unsigned int offset_y;
589 unsigned int output_size_y;
590 unsigned int crop_end_y;
591 unsigned int vts;
592
593 /* With auto size, only output and total sizes need to be set. */
594 bool size_auto;
595 unsigned int size_auto_boundary_x;
596 unsigned int size_auto_boundary_y;
597
598 bool binning_x;
599 bool binning_y;
600 bool variopixel;
601 unsigned int variopixel_hsub_coef;
602 unsigned int variopixel_vsub_coef;
603
604 /* Bits for the format register, used for binning. */
605 bool sync_hbin;
606 bool horz_var2;
607
608 unsigned int inc_x_odd;
609 unsigned int inc_x_even;
610 unsigned int inc_y_odd;
611 unsigned int inc_y_even;
612
613 unsigned int vfifo_read_start;
614
615 unsigned int ablc_num;
616 unsigned int zline_num;
617
618 unsigned int blc_top_zero_line_start;
619 unsigned int blc_top_zero_line_num;
620 unsigned int blc_top_black_line_start;
621 unsigned int blc_top_black_line_num;
622
623 unsigned int blc_bottom_zero_line_start;
624 unsigned int blc_bottom_zero_line_num;
625 unsigned int blc_bottom_black_line_start;
626 unsigned int blc_bottom_black_line_num;
627
628 u8 blc_col_shift_mask;
629
630 unsigned int blc_anchor_left_start;
631 unsigned int blc_anchor_left_end;
632 unsigned int blc_anchor_right_start;
633 unsigned int blc_anchor_right_end;
634
635 struct v4l2_fract frame_interval;
636
637 const struct ov8865_pll1_config *pll1_config;
638 const struct ov8865_pll2_config *pll2_config;
639 const struct ov8865_sclk_config *sclk_config;
640
641 const struct ov8865_register_value *register_values;
642 unsigned int register_values_count;
643};
644
645struct ov8865_state {
646 const struct ov8865_mode *mode;
647 u32 mbus_code;
648
649 bool streaming;
650};
651
652struct ov8865_ctrls {
653 struct v4l2_ctrl *link_freq;
654 struct v4l2_ctrl *pixel_rate;
655
656 struct v4l2_ctrl_handler handler;
657};
658
659struct ov8865_sensor {
660 struct device *dev;
661 struct i2c_client *i2c_client;
662 struct gpio_desc *reset;
663 struct gpio_desc *powerdown;
664 struct regulator *avdd;
665 struct regulator *dvdd;
666 struct regulator *dovdd;
667 struct clk *extclk;
668
669 struct v4l2_fwnode_endpoint endpoint;
670 struct v4l2_subdev subdev;
671 struct media_pad pad;
672
673 struct mutex mutex;
674
675 struct ov8865_state state;
676 struct ov8865_ctrls ctrls;
677};
678
679/* Static definitions */
680
681/*
682 * EXTCLK = 24 MHz
683 * PHY_SCLK = 720 MHz
684 * MIPI_PCLK = 90 MHz
685 */
686static const struct ov8865_pll1_config ov8865_pll1_config_native = {
687 .pll_pre_div_half = 1,
688 .pll_pre_div = 0,
689 .pll_mul = 30,
690 .m_div = 1,
691 .mipi_div = 3,
692 .pclk_div = 1,
693 .sys_pre_div = 1,
694 .sys_div = 2,
695};
696
697/*
698 * EXTCLK = 24 MHz
699 * DAC_CLK = 360 MHz
700 * SCLK = 144 MHz
701 */
702
703static const struct ov8865_pll2_config ov8865_pll2_config_native = {
704 .pll_pre_div_half = 1,
705 .pll_pre_div = 0,
706 .pll_mul = 30,
707 .dac_div = 2,
708 .sys_pre_div = 5,
709 .sys_div = 0,
710};
711
712/*
713 * EXTCLK = 24 MHz
714 * DAC_CLK = 360 MHz
715 * SCLK = 80 MHz
716 */
717
718static const struct ov8865_pll2_config ov8865_pll2_config_binning = {
719 .pll_pre_div_half = 1,
720 .pll_pre_div = 0,
721 .pll_mul = 30,
722 .dac_div = 2,
723 .sys_pre_div = 10,
724 .sys_div = 0,
725};
726
727static const struct ov8865_sclk_config ov8865_sclk_config_native = {
728 .sys_sel = 1,
729 .sclk_sel = 0,
730 .sclk_pre_div = 0,
731 .sclk_div = 0,
732};
733
734static const struct ov8865_register_value ov8865_register_values_native[] = {
735 /* Sensor */
736
737 { 0x3700, 0x48 },
738 { 0x3701, 0x18 },
739 { 0x3702, 0x50 },
740 { 0x3703, 0x32 },
741 { 0x3704, 0x28 },
742 { 0x3706, 0x70 },
743 { 0x3707, 0x08 },
744 { 0x3708, 0x48 },
745 { 0x3709, 0x80 },
746 { 0x370a, 0x01 },
747 { 0x370b, 0x70 },
748 { 0x370c, 0x07 },
749 { 0x3718, 0x14 },
750 { 0x3712, 0x44 },
751 { 0x371e, 0x31 },
752 { 0x371f, 0x7f },
753 { 0x3720, 0x0a },
754 { 0x3721, 0x0a },
755 { 0x3724, 0x04 },
756 { 0x3725, 0x04 },
757 { 0x3726, 0x0c },
758 { 0x3728, 0x0a },
759 { 0x3729, 0x03 },
760 { 0x372a, 0x06 },
761 { 0x372b, 0xa6 },
762 { 0x372c, 0xa6 },
763 { 0x372d, 0xa6 },
764 { 0x372e, 0x0c },
765 { 0x372f, 0x20 },
766 { 0x3730, 0x02 },
767 { 0x3731, 0x0c },
768 { 0x3732, 0x28 },
769 { 0x3736, 0x30 },
770 { 0x373a, 0x04 },
771 { 0x373b, 0x18 },
772 { 0x373c, 0x14 },
773 { 0x373e, 0x06 },
774 { 0x375a, 0x0c },
775 { 0x375b, 0x26 },
776 { 0x375d, 0x04 },
777 { 0x375f, 0x28 },
778 { 0x3767, 0x1e },
779 { 0x3772, 0x46 },
780 { 0x3773, 0x04 },
781 { 0x3774, 0x2c },
782 { 0x3775, 0x13 },
783 { 0x3776, 0x10 },
784 { 0x37a0, 0x88 },
785 { 0x37a1, 0x7a },
786 { 0x37a2, 0x7a },
787 { 0x37a3, 0x02 },
788 { 0x37a5, 0x09 },
789 { 0x37a7, 0x88 },
790 { 0x37a8, 0xb0 },
791 { 0x37a9, 0xb0 },
792 { 0x37aa, 0x88 },
793 { 0x37ab, 0x5c },
794 { 0x37ac, 0x5c },
795 { 0x37ad, 0x55 },
796 { 0x37ae, 0x19 },
797 { 0x37af, 0x19 },
798 { 0x37b3, 0x84 },
799 { 0x37b4, 0x84 },
800 { 0x37b5, 0x66 },
801
802 /* PSRAM */
803
804 { OV8865_PSRAM_CTRL8_REG, 0x16 },
805
806 /* ADC Sync */
807
808 { 0x4500, 0x68 },
809};
810
811static const struct ov8865_register_value ov8865_register_values_binning[] = {
812 /* Sensor */
813
814 { 0x3700, 0x24 },
815 { 0x3701, 0x0c },
816 { 0x3702, 0x28 },
817 { 0x3703, 0x19 },
818 { 0x3704, 0x14 },
819 { 0x3706, 0x38 },
820 { 0x3707, 0x04 },
821 { 0x3708, 0x24 },
822 { 0x3709, 0x40 },
823 { 0x370a, 0x00 },
824 { 0x370b, 0xb8 },
825 { 0x370c, 0x04 },
826 { 0x3718, 0x12 },
827 { 0x3712, 0x42 },
828 { 0x371e, 0x19 },
829 { 0x371f, 0x40 },
830 { 0x3720, 0x05 },
831 { 0x3721, 0x05 },
832 { 0x3724, 0x02 },
833 { 0x3725, 0x02 },
834 { 0x3726, 0x06 },
835 { 0x3728, 0x05 },
836 { 0x3729, 0x02 },
837 { 0x372a, 0x03 },
838 { 0x372b, 0x53 },
839 { 0x372c, 0xa3 },
840 { 0x372d, 0x53 },
841 { 0x372e, 0x06 },
842 { 0x372f, 0x10 },
843 { 0x3730, 0x01 },
844 { 0x3731, 0x06 },
845 { 0x3732, 0x14 },
846 { 0x3736, 0x20 },
847 { 0x373a, 0x02 },
848 { 0x373b, 0x0c },
849 { 0x373c, 0x0a },
850 { 0x373e, 0x03 },
851 { 0x375a, 0x06 },
852 { 0x375b, 0x13 },
853 { 0x375d, 0x02 },
854 { 0x375f, 0x14 },
855 { 0x3767, 0x1c },
856 { 0x3772, 0x23 },
857 { 0x3773, 0x02 },
858 { 0x3774, 0x16 },
859 { 0x3775, 0x12 },
860 { 0x3776, 0x08 },
861 { 0x37a0, 0x44 },
862 { 0x37a1, 0x3d },
863 { 0x37a2, 0x3d },
864 { 0x37a3, 0x01 },
865 { 0x37a5, 0x08 },
866 { 0x37a7, 0x44 },
867 { 0x37a8, 0x58 },
868 { 0x37a9, 0x58 },
869 { 0x37aa, 0x44 },
870 { 0x37ab, 0x2e },
871 { 0x37ac, 0x2e },
872 { 0x37ad, 0x33 },
873 { 0x37ae, 0x0d },
874 { 0x37af, 0x0d },
875 { 0x37b3, 0x42 },
876 { 0x37b4, 0x42 },
877 { 0x37b5, 0x33 },
878
879 /* PSRAM */
880
881 { OV8865_PSRAM_CTRL8_REG, 0x0b },
882
883 /* ADC Sync */
884
885 { 0x4500, 0x40 },
886};
887
888static const struct ov8865_mode ov8865_modes[] = {
889 /* 3264x2448 */
890 {
891 /* Horizontal */
892 .output_size_x = 3264,
893 .hts = 1944,
894
895 /* Vertical */
896 .output_size_y = 2448,
897 .vts = 2470,
898
899 .size_auto = true,
900 .size_auto_boundary_x = 8,
901 .size_auto_boundary_y = 4,
902
903 /* Subsample increase */
904 .inc_x_odd = 1,
905 .inc_x_even = 1,
906 .inc_y_odd = 1,
907 .inc_y_even = 1,
908
909 /* VFIFO */
910 .vfifo_read_start = 16,
911
912 .ablc_num = 4,
913 .zline_num = 1,
914
915 /* Black Level */
916
917 .blc_top_zero_line_start = 0,
918 .blc_top_zero_line_num = 2,
919 .blc_top_black_line_start = 4,
920 .blc_top_black_line_num = 4,
921
922 .blc_bottom_zero_line_start = 2,
923 .blc_bottom_zero_line_num = 2,
924 .blc_bottom_black_line_start = 8,
925 .blc_bottom_black_line_num = 2,
926
927 .blc_anchor_left_start = 576,
928 .blc_anchor_left_end = 831,
929 .blc_anchor_right_start = 1984,
930 .blc_anchor_right_end = 2239,
931
932 /* Frame Interval */
933 .frame_interval = { 1, 30 },
934
935 /* PLL */
936 .pll1_config = &ov8865_pll1_config_native,
937 .pll2_config = &ov8865_pll2_config_native,
938 .sclk_config = &ov8865_sclk_config_native,
939
940 /* Registers */
941 .register_values = ov8865_register_values_native,
942 .register_values_count =
943 ARRAY_SIZE(ov8865_register_values_native),
944 },
945 /* 3264x1836 */
946 {
947 /* Horizontal */
948 .output_size_x = 3264,
949 .hts = 2582,
950
951 /* Vertical */
952 .output_size_y = 1836,
953 .vts = 2002,
954
955 .size_auto = true,
956 .size_auto_boundary_x = 8,
957 .size_auto_boundary_y = 4,
958
959 /* Subsample increase */
960 .inc_x_odd = 1,
961 .inc_x_even = 1,
962 .inc_y_odd = 1,
963 .inc_y_even = 1,
964
965 /* VFIFO */
966 .vfifo_read_start = 16,
967
968 .ablc_num = 4,
969 .zline_num = 1,
970
971 /* Black Level */
972
973 .blc_top_zero_line_start = 0,
974 .blc_top_zero_line_num = 2,
975 .blc_top_black_line_start = 4,
976 .blc_top_black_line_num = 4,
977
978 .blc_bottom_zero_line_start = 2,
979 .blc_bottom_zero_line_num = 2,
980 .blc_bottom_black_line_start = 8,
981 .blc_bottom_black_line_num = 2,
982
983 .blc_anchor_left_start = 576,
984 .blc_anchor_left_end = 831,
985 .blc_anchor_right_start = 1984,
986 .blc_anchor_right_end = 2239,
987
988 /* Frame Interval */
989 .frame_interval = { 1, 30 },
990
991 /* PLL */
992 .pll1_config = &ov8865_pll1_config_native,
993 .pll2_config = &ov8865_pll2_config_native,
994 .sclk_config = &ov8865_sclk_config_native,
995
996 /* Registers */
997 .register_values = ov8865_register_values_native,
998 .register_values_count =
999 ARRAY_SIZE(ov8865_register_values_native),
1000 },
1001 /* 1632x1224 */
1002 {
1003 /* Horizontal */
1004 .output_size_x = 1632,
1005 .hts = 1923,
1006
1007 /* Vertical */
1008 .output_size_y = 1224,
1009 .vts = 1248,
1010
1011 .size_auto = true,
1012 .size_auto_boundary_x = 8,
1013 .size_auto_boundary_y = 8,
1014
1015 /* Subsample increase */
1016 .inc_x_odd = 3,
1017 .inc_x_even = 1,
1018 .inc_y_odd = 3,
1019 .inc_y_even = 1,
1020
1021 /* Binning */
1022 .binning_y = true,
1023 .sync_hbin = true,
1024
1025 /* VFIFO */
1026 .vfifo_read_start = 116,
1027
1028 .ablc_num = 8,
1029 .zline_num = 2,
1030
1031 /* Black Level */
1032
1033 .blc_top_zero_line_start = 0,
1034 .blc_top_zero_line_num = 2,
1035 .blc_top_black_line_start = 4,
1036 .blc_top_black_line_num = 4,
1037
1038 .blc_bottom_zero_line_start = 2,
1039 .blc_bottom_zero_line_num = 2,
1040 .blc_bottom_black_line_start = 8,
1041 .blc_bottom_black_line_num = 2,
1042
1043 .blc_anchor_left_start = 288,
1044 .blc_anchor_left_end = 415,
1045 .blc_anchor_right_start = 992,
1046 .blc_anchor_right_end = 1119,
1047
1048 /* Frame Interval */
1049 .frame_interval = { 1, 30 },
1050
1051 /* PLL */
1052 .pll1_config = &ov8865_pll1_config_native,
1053 .pll2_config = &ov8865_pll2_config_binning,
1054 .sclk_config = &ov8865_sclk_config_native,
1055
1056 /* Registers */
1057 .register_values = ov8865_register_values_binning,
1058 .register_values_count =
1059 ARRAY_SIZE(ov8865_register_values_binning),
1060 },
1061 /* 800x600 (SVGA) */
1062 {
1063 /* Horizontal */
1064 .output_size_x = 800,
1065 .hts = 1250,
1066
1067 /* Vertical */
1068 .output_size_y = 600,
1069 .vts = 640,
1070
1071 .size_auto = true,
1072 .size_auto_boundary_x = 8,
1073 .size_auto_boundary_y = 8,
1074
1075 /* Subsample increase */
1076 .inc_x_odd = 3,
1077 .inc_x_even = 1,
1078 .inc_y_odd = 5,
1079 .inc_y_even = 3,
1080
1081 /* Binning */
1082 .binning_y = true,
1083 .variopixel = true,
1084 .variopixel_hsub_coef = 2,
1085 .variopixel_vsub_coef = 1,
1086 .sync_hbin = true,
1087 .horz_var2 = true,
1088
1089 /* VFIFO */
1090 .vfifo_read_start = 80,
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 = 2,
1100 .blc_top_black_line_num = 2,
1101
1102 .blc_bottom_zero_line_start = 0,
1103 .blc_bottom_zero_line_num = 0,
1104 .blc_bottom_black_line_start = 4,
1105 .blc_bottom_black_line_num = 2,
1106
1107 .blc_col_shift_mask = OV8865_BLC_CTRL1_COL_SHIFT_128,
1108
1109 .blc_anchor_left_start = 288,
1110 .blc_anchor_left_end = 415,
1111 .blc_anchor_right_start = 992,
1112 .blc_anchor_right_end = 1119,
1113
1114 /* Frame Interval */
1115 .frame_interval = { 1, 90 },
1116
1117 /* PLL */
1118 .pll1_config = &ov8865_pll1_config_native,
1119 .pll2_config = &ov8865_pll2_config_binning,
1120 .sclk_config = &ov8865_sclk_config_native,
1121
1122 /* Registers */
1123 .register_values = ov8865_register_values_binning,
1124 .register_values_count =
1125 ARRAY_SIZE(ov8865_register_values_binning),
1126 },
1127};
1128
1129static const u32 ov8865_mbus_codes[] = {
1130 MEDIA_BUS_FMT_SBGGR10_1X10,
1131};
1132
1133static const struct ov8865_register_value ov8865_init_sequence[] = {
1134 /* Analog */
1135
1136 { 0x3604, 0x04 },
1137 { 0x3602, 0x30 },
1138 { 0x3605, 0x00 },
1139 { 0x3607, 0x20 },
1140 { 0x3608, 0x11 },
1141 { 0x3609, 0x68 },
1142 { 0x360a, 0x40 },
1143 { 0x360c, 0xdd },
1144 { 0x360e, 0x0c },
1145 { 0x3610, 0x07 },
1146 { 0x3612, 0x86 },
1147 { 0x3613, 0x58 },
1148 { 0x3614, 0x28 },
1149 { 0x3617, 0x40 },
1150 { 0x3618, 0x5a },
1151 { 0x3619, 0x9b },
1152 { 0x361c, 0x00 },
1153 { 0x361d, 0x60 },
1154 { 0x3631, 0x60 },
1155 { 0x3633, 0x10 },
1156 { 0x3634, 0x10 },
1157 { 0x3635, 0x10 },
1158 { 0x3636, 0x10 },
1159 { 0x3638, 0xff },
1160 { 0x3641, 0x55 },
1161 { 0x3646, 0x86 },
1162 { 0x3647, 0x27 },
1163 { 0x364a, 0x1b },
1164
1165 /* Sensor */
1166
1167 { 0x3700, 0x24 },
1168 { 0x3701, 0x0c },
1169 { 0x3702, 0x28 },
1170 { 0x3703, 0x19 },
1171 { 0x3704, 0x14 },
1172 { 0x3705, 0x00 },
1173 { 0x3706, 0x38 },
1174 { 0x3707, 0x04 },
1175 { 0x3708, 0x24 },
1176 { 0x3709, 0x40 },
1177 { 0x370a, 0x00 },
1178 { 0x370b, 0xb8 },
1179 { 0x370c, 0x04 },
1180 { 0x3718, 0x12 },
1181 { 0x3719, 0x31 },
1182 { 0x3712, 0x42 },
1183 { 0x3714, 0x12 },
1184 { 0x371e, 0x19 },
1185 { 0x371f, 0x40 },
1186 { 0x3720, 0x05 },
1187 { 0x3721, 0x05 },
1188 { 0x3724, 0x02 },
1189 { 0x3725, 0x02 },
1190 { 0x3726, 0x06 },
1191 { 0x3728, 0x05 },
1192 { 0x3729, 0x02 },
1193 { 0x372a, 0x03 },
1194 { 0x372b, 0x53 },
1195 { 0x372c, 0xa3 },
1196 { 0x372d, 0x53 },
1197 { 0x372e, 0x06 },
1198 { 0x372f, 0x10 },
1199 { 0x3730, 0x01 },
1200 { 0x3731, 0x06 },
1201 { 0x3732, 0x14 },
1202 { 0x3733, 0x10 },
1203 { 0x3734, 0x40 },
1204 { 0x3736, 0x20 },
1205 { 0x373a, 0x02 },
1206 { 0x373b, 0x0c },
1207 { 0x373c, 0x0a },
1208 { 0x373e, 0x03 },
1209 { 0x3755, 0x40 },
1210 { 0x3758, 0x00 },
1211 { 0x3759, 0x4c },
1212 { 0x375a, 0x06 },
1213 { 0x375b, 0x13 },
1214 { 0x375c, 0x40 },
1215 { 0x375d, 0x02 },
1216 { 0x375e, 0x00 },
1217 { 0x375f, 0x14 },
1218 { 0x3767, 0x1c },
1219 { 0x3768, 0x04 },
1220 { 0x3769, 0x20 },
1221 { 0x376c, 0xc0 },
1222 { 0x376d, 0xc0 },
1223 { 0x376a, 0x08 },
1224 { 0x3761, 0x00 },
1225 { 0x3762, 0x00 },
1226 { 0x3763, 0x00 },
1227 { 0x3766, 0xff },
1228 { 0x376b, 0x42 },
1229 { 0x3772, 0x23 },
1230 { 0x3773, 0x02 },
1231 { 0x3774, 0x16 },
1232 { 0x3775, 0x12 },
1233 { 0x3776, 0x08 },
1234 { 0x37a0, 0x44 },
1235 { 0x37a1, 0x3d },
1236 { 0x37a2, 0x3d },
1237 { 0x37a3, 0x01 },
1238 { 0x37a4, 0x00 },
1239 { 0x37a5, 0x08 },
1240 { 0x37a6, 0x00 },
1241 { 0x37a7, 0x44 },
1242 { 0x37a8, 0x58 },
1243 { 0x37a9, 0x58 },
1244 { 0x3760, 0x00 },
1245 { 0x376f, 0x01 },
1246 { 0x37aa, 0x44 },
1247 { 0x37ab, 0x2e },
1248 { 0x37ac, 0x2e },
1249 { 0x37ad, 0x33 },
1250 { 0x37ae, 0x0d },
1251 { 0x37af, 0x0d },
1252 { 0x37b0, 0x00 },
1253 { 0x37b1, 0x00 },
1254 { 0x37b2, 0x00 },
1255 { 0x37b3, 0x42 },
1256 { 0x37b4, 0x42 },
1257 { 0x37b5, 0x33 },
1258 { 0x37b6, 0x00 },
1259 { 0x37b7, 0x00 },
1260 { 0x37b8, 0x00 },
1261 { 0x37b9, 0xff },
1262
1263 /* ADC Sync */
1264
1265 { 0x4503, 0x10 },
1266};
1267
1268static const s64 ov8865_link_freq_menu[] = {
1269 360000000,
1270};
1271
1272static const char *const ov8865_test_pattern_menu[] = {
1273 "Disabled",
1274 "Random data",
1275 "Color bars",
1276 "Color bars with rolling bar",
1277 "Color squares",
1278 "Color squares with rolling bar"
1279};
1280
1281static const u8 ov8865_test_pattern_bits[] = {
1282 0,
1283 OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_RANDOM_DATA,
1284 OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_COLOR_BARS,
1285 OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_ROLLING_BAR_EN |
1286 OV8865_PRE_CTRL0_PATTERN_COLOR_BARS,
1287 OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES,
1288 OV8865_PRE_CTRL0_PATTERN_EN | OV8865_PRE_CTRL0_ROLLING_BAR_EN |
1289 OV8865_PRE_CTRL0_PATTERN_COLOR_SQUARES,
1290};
1291
1292/* Input/Output */
1293
1294static int ov8865_read(struct ov8865_sensor *sensor, u16 address, u8 *value)
1295{
1296 unsigned char data[2] = { address >> 8, address & 0xff };
1297 struct i2c_client *client = sensor->i2c_client;
1298 int ret;
1299
1300 ret = i2c_master_send(client, data, sizeof(data));
1301 if (ret < 0) {
1302 dev_dbg(&client->dev, "i2c send error at address %#04x\n",
1303 address);
1304 return ret;
1305 }
1306
1307 ret = i2c_master_recv(client, value, 1);
1308 if (ret < 0) {
1309 dev_dbg(&client->dev, "i2c recv error at address %#04x\n",
1310 address);
1311 return ret;
1312 }
1313
1314 return 0;
1315}
1316
1317static int ov8865_write(struct ov8865_sensor *sensor, u16 address, u8 value)
1318{
1319 unsigned char data[3] = { address >> 8, address & 0xff, value };
1320 struct i2c_client *client = sensor->i2c_client;
1321 int ret;
1322
1323 ret = i2c_master_send(client, data, sizeof(data));
1324 if (ret < 0) {
1325 dev_dbg(&client->dev, "i2c send error at address %#04x\n",
1326 address);
1327 return ret;
1328 }
1329
1330 return 0;
1331}
1332
1333static int ov8865_write_sequence(struct ov8865_sensor *sensor,
1334 const struct ov8865_register_value *sequence,
1335 unsigned int sequence_count)
1336{
1337 unsigned int i;
1338 int ret = 0;
1339
1340 for (i = 0; i < sequence_count; i++) {
1341 ret = ov8865_write(sensor, sequence[i].address,
1342 sequence[i].value);
1343 if (ret)
1344 break;
1345
1346 if (sequence[i].delay_ms)
1347 msleep(sequence[i].delay_ms);
1348 }
1349
1350 return ret;
1351}
1352
1353static int ov8865_update_bits(struct ov8865_sensor *sensor, u16 address,
1354 u8 mask, u8 bits)
1355{
1356 u8 value = 0;
1357 int ret;
1358
1359 ret = ov8865_read(sensor, address, &value);
1360 if (ret)
1361 return ret;
1362
1363 value &= ~mask;
1364 value |= bits;
1365
1366 return ov8865_write(sensor, address, value);
1367}
1368
1369/* Sensor */
1370
1371static int ov8865_sw_reset(struct ov8865_sensor *sensor)
1372{
1373 return ov8865_write(sensor, OV8865_SW_RESET_REG, OV8865_SW_RESET_RESET);
1374}
1375
1376static int ov8865_sw_standby(struct ov8865_sensor *sensor, int standby)
1377{
1378 u8 value = 0;
1379
1380 if (!standby)
1381 value = OV8865_SW_STANDBY_STREAM_ON;
1382
1383 return ov8865_write(sensor, OV8865_SW_STANDBY_REG, value);
1384}
1385
1386static int ov8865_chip_id_check(struct ov8865_sensor *sensor)
1387{
1388 u16 regs[] = { OV8865_CHIP_ID_HH_REG, OV8865_CHIP_ID_H_REG,
1389 OV8865_CHIP_ID_L_REG };
1390 u8 values[] = { OV8865_CHIP_ID_HH_VALUE, OV8865_CHIP_ID_H_VALUE,
1391 OV8865_CHIP_ID_L_VALUE };
1392 unsigned int i;
1393 u8 value;
1394 int ret;
1395
1396 for (i = 0; i < ARRAY_SIZE(regs); i++) {
1397 ret = ov8865_read(sensor, regs[i], &value);
1398 if (ret < 0)
1399 return ret;
1400
1401 if (value != values[i]) {
1402 dev_err(sensor->dev,
1403 "chip id value mismatch: %#x instead of %#x\n",
1404 value, values[i]);
1405 return -EINVAL;
1406 }
1407 }
1408
1409 return 0;
1410}
1411
1412static int ov8865_charge_pump_configure(struct ov8865_sensor *sensor)
1413{
1414 return ov8865_write(sensor, OV8865_PUMP_CLK_DIV_REG,
1415 OV8865_PUMP_CLK_DIV_PUMP_P(1));
1416}
1417
1418static int ov8865_mipi_configure(struct ov8865_sensor *sensor)
1419{
1420 struct v4l2_fwnode_bus_mipi_csi2 *bus_mipi_csi2 =
1421 &sensor->endpoint.bus.mipi_csi2;
1422 unsigned int lanes_count = bus_mipi_csi2->num_data_lanes;
1423 int ret;
1424
1425 ret = ov8865_write(sensor, OV8865_MIPI_SC_CTRL0_REG,
1426 OV8865_MIPI_SC_CTRL0_LANES(lanes_count) |
1427 OV8865_MIPI_SC_CTRL0_MIPI_EN |
1428 OV8865_MIPI_SC_CTRL0_UNKNOWN);
1429 if (ret)
1430 return ret;
1431
1432 ret = ov8865_write(sensor, OV8865_MIPI_SC_CTRL2_REG,
1433 OV8865_MIPI_SC_CTRL2_PD_MIPI_RST_SYNC);
1434 if (ret)
1435 return ret;
1436
1437 if (lanes_count >= 2) {
1438 ret = ov8865_write(sensor, OV8865_MIPI_LANE_SEL01_REG,
1439 OV8865_MIPI_LANE_SEL01_LANE0(0) |
1440 OV8865_MIPI_LANE_SEL01_LANE1(1));
1441 if (ret)
1442 return ret;
1443 }
1444
1445 if (lanes_count >= 4) {
1446 ret = ov8865_write(sensor, OV8865_MIPI_LANE_SEL23_REG,
1447 OV8865_MIPI_LANE_SEL23_LANE2(2) |
1448 OV8865_MIPI_LANE_SEL23_LANE3(3));
1449 if (ret)
1450 return ret;
1451 }
1452
1453 ret = ov8865_update_bits(sensor, OV8865_CLK_SEL1_REG,
1454 OV8865_CLK_SEL1_MIPI_EOF,
1455 OV8865_CLK_SEL1_MIPI_EOF);
1456 if (ret)
1457 return ret;
1458
1459 /*
1460 * This value might need to change depending on PCLK rate,
1461 * but it's unclear how. This value seems to generally work
1462 * while the default value was found to cause transmission errors.
1463 */
1464 return ov8865_write(sensor, OV8865_MIPI_PCLK_PERIOD_REG, 0x16);
1465}
1466
1467static int ov8865_black_level_configure(struct ov8865_sensor *sensor)
1468{
1469 int ret;
1470
1471 /* Trigger BLC on relevant events and enable filter. */
1472 ret = ov8865_write(sensor, OV8865_BLC_CTRL0_REG,
1473 OV8865_BLC_CTRL0_TRIG_RANGE_EN |
1474 OV8865_BLC_CTRL0_TRIG_FORMAT_EN |
1475 OV8865_BLC_CTRL0_TRIG_GAIN_EN |
1476 OV8865_BLC_CTRL0_TRIG_EXPOSURE_EN |
1477 OV8865_BLC_CTRL0_FILTER_EN);
1478 if (ret)
1479 return ret;
1480
1481 /* Lower BLC offset trigger threshold. */
1482 ret = ov8865_write(sensor, OV8865_BLC_CTRLD_REG,
1483 OV8865_BLC_CTRLD_OFFSET_TRIGGER(16));
1484 if (ret)
1485 return ret;
1486
1487 ret = ov8865_write(sensor, OV8865_BLC_CTRL1F_REG, 0);
1488 if (ret)
1489 return ret;
1490
1491 /* Increase BLC offset maximum limit. */
1492 return ov8865_write(sensor, OV8865_BLC_OFFSET_LIMIT_REG,
1493 OV8865_BLC_OFFSET_LIMIT(63));
1494}
1495
1496static int ov8865_isp_configure(struct ov8865_sensor *sensor)
1497{
1498 int ret;
1499
1500 /* Disable lens correction. */
1501 ret = ov8865_write(sensor, OV8865_ISP_CTRL0_REG,
1502 OV8865_ISP_CTRL0_WHITE_BALANCE_EN |
1503 OV8865_ISP_CTRL0_DPC_BLACK_EN |
1504 OV8865_ISP_CTRL0_DPC_WHITE_EN);
1505 if (ret)
1506 return ret;
1507
1508 return ov8865_write(sensor, OV8865_ISP_CTRL1_REG,
1509 OV8865_ISP_CTRL1_BLC_EN);
1510}
1511
1512static unsigned long ov8865_mode_pll1_rate(struct ov8865_sensor *sensor,
1513 const struct ov8865_mode *mode)
1514{
1515 const struct ov8865_pll1_config *config = mode->pll1_config;
1516 unsigned long extclk_rate;
1517 unsigned long pll1_rate;
1518
1519 extclk_rate = clk_get_rate(sensor->extclk);
1520 pll1_rate = extclk_rate * config->pll_mul / config->pll_pre_div_half;
1521
1522 switch (config->pll_pre_div) {
1523 case 0:
1524 break;
1525 case 1:
1526 pll1_rate *= 3;
1527 pll1_rate /= 2;
1528 break;
1529 case 3:
1530 pll1_rate *= 5;
1531 pll1_rate /= 2;
1532 break;
1533 case 4:
1534 pll1_rate /= 3;
1535 break;
1536 case 5:
1537 pll1_rate /= 4;
1538 break;
1539 case 7:
1540 pll1_rate /= 8;
1541 break;
1542 default:
1543 pll1_rate /= config->pll_pre_div;
1544 break;
1545 }
1546
1547 return pll1_rate;
1548}
1549
1550static int ov8865_mode_pll1_configure(struct ov8865_sensor *sensor,
1551 const struct ov8865_mode *mode,
1552 u32 mbus_code)
1553{
1554 const struct ov8865_pll1_config *config = mode->pll1_config;
1555 u8 value;
1556 int ret;
1557
1558 switch (mbus_code) {
1559 case MEDIA_BUS_FMT_SBGGR10_1X10:
1560 value = OV8865_MIPI_BIT_SEL(10);
1561 break;
1562 default:
1563 return -EINVAL;
1564 }
1565
1566 ret = ov8865_write(sensor, OV8865_MIPI_BIT_SEL_REG, value);
1567 if (ret)
1568 return ret;
1569
1570 ret = ov8865_write(sensor, OV8865_PLL_CTRLA_REG,
1571 OV8865_PLL_CTRLA_PRE_DIV_HALF(config->pll_pre_div_half));
1572 if (ret)
1573 return ret;
1574
1575 ret = ov8865_write(sensor, OV8865_PLL_CTRL0_REG,
1576 OV8865_PLL_CTRL0_PRE_DIV(config->pll_pre_div));
1577 if (ret)
1578 return ret;
1579
1580 ret = ov8865_write(sensor, OV8865_PLL_CTRL1_REG,
1581 OV8865_PLL_CTRL1_MUL_H(config->pll_mul));
1582 if (ret)
1583 return ret;
1584
1585 ret = ov8865_write(sensor, OV8865_PLL_CTRL2_REG,
1586 OV8865_PLL_CTRL2_MUL_L(config->pll_mul));
1587 if (ret)
1588 return ret;
1589
1590 ret = ov8865_write(sensor, OV8865_PLL_CTRL3_REG,
1591 OV8865_PLL_CTRL3_M_DIV(config->m_div));
1592 if (ret)
1593 return ret;
1594
1595 ret = ov8865_write(sensor, OV8865_PLL_CTRL4_REG,
1596 OV8865_PLL_CTRL4_MIPI_DIV(config->mipi_div));
1597 if (ret)
1598 return ret;
1599
1600 ret = ov8865_update_bits(sensor, OV8865_PCLK_SEL_REG,
36e4f2b2
PK
1601 OV8865_PCLK_SEL_PCLK_DIV_MASK,
1602 OV8865_PCLK_SEL_PCLK_DIV(config->pclk_div));
11c0d8fd
PK
1603 if (ret)
1604 return ret;
1605
1606 ret = ov8865_write(sensor, OV8865_PLL_CTRL5_REG,
1607 OV8865_PLL_CTRL5_SYS_PRE_DIV(config->sys_pre_div));
1608 if (ret)
1609 return ret;
1610
1611 ret = ov8865_write(sensor, OV8865_PLL_CTRL6_REG,
1612 OV8865_PLL_CTRL6_SYS_DIV(config->sys_div));
1613 if (ret)
1614 return ret;
1615
1616 return ov8865_update_bits(sensor, OV8865_PLL_CTRL1E_REG,
1617 OV8865_PLL_CTRL1E_PLL1_NO_LAT,
1618 OV8865_PLL_CTRL1E_PLL1_NO_LAT);
1619}
1620
1621static int ov8865_mode_pll2_configure(struct ov8865_sensor *sensor,
1622 const struct ov8865_mode *mode)
1623{
1624 const struct ov8865_pll2_config *config = mode->pll2_config;
1625 int ret;
1626
1627 ret = ov8865_write(sensor, OV8865_PLL_CTRL12_REG,
1628 OV8865_PLL_CTRL12_PRE_DIV_HALF(config->pll_pre_div_half) |
1629 OV8865_PLL_CTRL12_DAC_DIV(config->dac_div));
1630 if (ret)
1631 return ret;
1632
1633 ret = ov8865_write(sensor, OV8865_PLL_CTRLB_REG,
1634 OV8865_PLL_CTRLB_PRE_DIV(config->pll_pre_div));
1635 if (ret)
1636 return ret;
1637
1638 ret = ov8865_write(sensor, OV8865_PLL_CTRLC_REG,
1639 OV8865_PLL_CTRLC_MUL_H(config->pll_mul));
1640 if (ret)
1641 return ret;
1642
1643 ret = ov8865_write(sensor, OV8865_PLL_CTRLD_REG,
1644 OV8865_PLL_CTRLD_MUL_L(config->pll_mul));
1645 if (ret)
1646 return ret;
1647
1648 ret = ov8865_write(sensor, OV8865_PLL_CTRLF_REG,
1649 OV8865_PLL_CTRLF_SYS_PRE_DIV(config->sys_pre_div));
1650 if (ret)
1651 return ret;
1652
1653 return ov8865_write(sensor, OV8865_PLL_CTRLE_REG,
1654 OV8865_PLL_CTRLE_SYS_DIV(config->sys_div));
1655}
1656
1657static int ov8865_mode_sclk_configure(struct ov8865_sensor *sensor,
1658 const struct ov8865_mode *mode)
1659{
1660 const struct ov8865_sclk_config *config = mode->sclk_config;
1661 int ret;
1662
1663 ret = ov8865_write(sensor, OV8865_CLK_SEL0_REG,
1664 OV8865_CLK_SEL0_PLL1_SYS_SEL(config->sys_sel));
1665 if (ret)
1666 return ret;
1667
1668 ret = ov8865_update_bits(sensor, OV8865_CLK_SEL1_REG,
1669 OV8865_CLK_SEL1_PLL_SCLK_SEL_MASK,
1670 OV8865_CLK_SEL1_PLL_SCLK_SEL(config->sclk_sel));
1671 if (ret)
1672 return ret;
1673
1674 return ov8865_write(sensor, OV8865_SCLK_CTRL_REG,
1675 OV8865_SCLK_CTRL_UNKNOWN |
1676 OV8865_SCLK_CTRL_SCLK_DIV(config->sclk_div) |
1677 OV8865_SCLK_CTRL_SCLK_PRE_DIV(config->sclk_pre_div));
1678}
1679
1680static int ov8865_mode_binning_configure(struct ov8865_sensor *sensor,
1681 const struct ov8865_mode *mode)
1682{
1683 unsigned int variopixel_hsub_coef, variopixel_vsub_coef;
1684 u8 value;
1685 int ret;
1686
1687 ret = ov8865_write(sensor, OV8865_FORMAT1_REG, 0);
1688 if (ret)
1689 return ret;
1690
1691 value = OV8865_FORMAT2_HSYNC_EN;
1692
1693 if (mode->binning_x)
1694 value |= OV8865_FORMAT2_FST_HBIN_EN;
1695
1696 if (mode->binning_y)
1697 value |= OV8865_FORMAT2_FST_VBIN_EN;
1698
1699 if (mode->sync_hbin)
1700 value |= OV8865_FORMAT2_SYNC_HBIN_EN;
1701
1702 if (mode->horz_var2)
1703 value |= OV8865_FORMAT2_ISP_HORZ_VAR2_EN;
1704
1705 ret = ov8865_write(sensor, OV8865_FORMAT2_REG, value);
1706 if (ret)
1707 return ret;
1708
1709 ret = ov8865_update_bits(sensor, OV8865_ISP_CTRL2_REG,
1710 OV8865_ISP_CTRL2_VARIOPIXEL_EN,
1711 mode->variopixel ?
1712 OV8865_ISP_CTRL2_VARIOPIXEL_EN : 0);
1713 if (ret)
1714 return ret;
1715
1716 if (mode->variopixel) {
1717 /* VarioPixel coefs needs to be > 1. */
1718 variopixel_hsub_coef = mode->variopixel_hsub_coef;
1719 variopixel_vsub_coef = mode->variopixel_vsub_coef;
1720 } else {
1721 variopixel_hsub_coef = 1;
1722 variopixel_vsub_coef = 1;
1723 }
1724
1725 ret = ov8865_write(sensor, OV8865_VAP_CTRL1_REG,
1726 OV8865_VAP_CTRL1_HSUB_COEF(variopixel_hsub_coef) |
1727 OV8865_VAP_CTRL1_VSUB_COEF(variopixel_vsub_coef));
1728 if (ret)
1729 return ret;
1730
1731 ret = ov8865_write(sensor, OV8865_INC_X_ODD_REG,
1732 OV8865_INC_X_ODD(mode->inc_x_odd));
1733 if (ret)
1734 return ret;
1735
1736 ret = ov8865_write(sensor, OV8865_INC_X_EVEN_REG,
1737 OV8865_INC_X_EVEN(mode->inc_x_even));
1738 if (ret)
1739 return ret;
1740
1741 ret = ov8865_write(sensor, OV8865_INC_Y_ODD_REG,
1742 OV8865_INC_Y_ODD(mode->inc_y_odd));
1743 if (ret)
1744 return ret;
1745
1746 return ov8865_write(sensor, OV8865_INC_Y_EVEN_REG,
1747 OV8865_INC_Y_EVEN(mode->inc_y_even));
1748}
1749
1750static int ov8865_mode_black_level_configure(struct ov8865_sensor *sensor,
1751 const struct ov8865_mode *mode)
1752{
1753 int ret;
1754
1755 /* Note that a zero value for blc_col_shift_mask is the default 256. */
1756 ret = ov8865_write(sensor, OV8865_BLC_CTRL1_REG,
1757 mode->blc_col_shift_mask |
1758 OV8865_BLC_CTRL1_OFFSET_LIMIT_EN);
1759 if (ret)
1760 return ret;
1761
1762 /* BLC top zero line */
1763
1764 ret = ov8865_write(sensor, OV8865_BLC_TOP_ZLINE_START_REG,
1765 OV8865_BLC_TOP_ZLINE_START(mode->blc_top_zero_line_start));
1766 if (ret)
1767 return ret;
1768
1769 ret = ov8865_write(sensor, OV8865_BLC_TOP_ZLINE_NUM_REG,
1770 OV8865_BLC_TOP_ZLINE_NUM(mode->blc_top_zero_line_num));
1771 if (ret)
1772 return ret;
1773
1774 /* BLC top black line */
1775
1776 ret = ov8865_write(sensor, OV8865_BLC_TOP_BLKLINE_START_REG,
1777 OV8865_BLC_TOP_BLKLINE_START(mode->blc_top_black_line_start));
1778 if (ret)
1779 return ret;
1780
1781 ret = ov8865_write(sensor, OV8865_BLC_TOP_BLKLINE_NUM_REG,
1782 OV8865_BLC_TOP_BLKLINE_NUM(mode->blc_top_black_line_num));
1783 if (ret)
1784 return ret;
1785
1786 /* BLC bottom zero line */
1787
1788 ret = ov8865_write(sensor, OV8865_BLC_BOT_ZLINE_START_REG,
1789 OV8865_BLC_BOT_ZLINE_START(mode->blc_bottom_zero_line_start));
1790 if (ret)
1791 return ret;
1792
1793 ret = ov8865_write(sensor, OV8865_BLC_BOT_ZLINE_NUM_REG,
1794 OV8865_BLC_BOT_ZLINE_NUM(mode->blc_bottom_zero_line_num));
1795 if (ret)
1796 return ret;
1797
1798 /* BLC bottom black line */
1799
1800 ret = ov8865_write(sensor, OV8865_BLC_BOT_BLKLINE_START_REG,
1801 OV8865_BLC_BOT_BLKLINE_START(mode->blc_bottom_black_line_start));
1802 if (ret)
1803 return ret;
1804
1805 ret = ov8865_write(sensor, OV8865_BLC_BOT_BLKLINE_NUM_REG,
1806 OV8865_BLC_BOT_BLKLINE_NUM(mode->blc_bottom_black_line_num));
1807 if (ret)
1808 return ret;
1809
1810 /* BLC anchor */
1811
1812 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_START_H_REG,
1813 OV8865_BLC_ANCHOR_LEFT_START_H(mode->blc_anchor_left_start));
1814 if (ret)
1815 return ret;
1816
1817 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_START_L_REG,
1818 OV8865_BLC_ANCHOR_LEFT_START_L(mode->blc_anchor_left_start));
1819 if (ret)
1820 return ret;
1821
1822 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_END_H_REG,
1823 OV8865_BLC_ANCHOR_LEFT_END_H(mode->blc_anchor_left_end));
1824 if (ret)
1825 return ret;
1826
1827 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_LEFT_END_L_REG,
1828 OV8865_BLC_ANCHOR_LEFT_END_L(mode->blc_anchor_left_end));
1829 if (ret)
1830 return ret;
1831
1832 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_START_H_REG,
1833 OV8865_BLC_ANCHOR_RIGHT_START_H(mode->blc_anchor_right_start));
1834 if (ret)
1835 return ret;
1836
1837 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_START_L_REG,
1838 OV8865_BLC_ANCHOR_RIGHT_START_L(mode->blc_anchor_right_start));
1839 if (ret)
1840 return ret;
1841
1842 ret = ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_END_H_REG,
1843 OV8865_BLC_ANCHOR_RIGHT_END_H(mode->blc_anchor_right_end));
1844 if (ret)
1845 return ret;
1846
1847 return ov8865_write(sensor, OV8865_BLC_ANCHOR_RIGHT_END_L_REG,
1848 OV8865_BLC_ANCHOR_RIGHT_END_L(mode->blc_anchor_right_end));
1849}
1850
1851static int ov8865_mode_configure(struct ov8865_sensor *sensor,
1852 const struct ov8865_mode *mode, u32 mbus_code)
1853{
1854 int ret;
1855
1856 /* Output Size X */
1857
1858 ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_X_H_REG,
1859 OV8865_OUTPUT_SIZE_X_H(mode->output_size_x));
1860 if (ret)
1861 return ret;
1862
1863 ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_X_L_REG,
1864 OV8865_OUTPUT_SIZE_X_L(mode->output_size_x));
1865 if (ret)
1866 return ret;
1867
1868 /* Horizontal Total Size */
1869
1870 ret = ov8865_write(sensor, OV8865_HTS_H_REG, OV8865_HTS_H(mode->hts));
1871 if (ret)
1872 return ret;
1873
1874 ret = ov8865_write(sensor, OV8865_HTS_L_REG, OV8865_HTS_L(mode->hts));
1875 if (ret)
1876 return ret;
1877
1878 /* Output Size Y */
1879
1880 ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_Y_H_REG,
1881 OV8865_OUTPUT_SIZE_Y_H(mode->output_size_y));
1882 if (ret)
1883 return ret;
1884
1885 ret = ov8865_write(sensor, OV8865_OUTPUT_SIZE_Y_L_REG,
1886 OV8865_OUTPUT_SIZE_Y_L(mode->output_size_y));
1887 if (ret)
1888 return ret;
1889
1890 /* Vertical Total Size */
1891
1892 ret = ov8865_write(sensor, OV8865_VTS_H_REG, OV8865_VTS_H(mode->vts));
1893 if (ret)
1894 return ret;
1895
1896 ret = ov8865_write(sensor, OV8865_VTS_L_REG, OV8865_VTS_L(mode->vts));
1897 if (ret)
1898 return ret;
1899
1900 if (mode->size_auto) {
1901 /* Auto Size */
1902
1903 ret = ov8865_write(sensor, OV8865_AUTO_SIZE_CTRL_REG,
1904 OV8865_AUTO_SIZE_CTRL_OFFSET_Y_REG |
1905 OV8865_AUTO_SIZE_CTRL_OFFSET_X_REG |
1906 OV8865_AUTO_SIZE_CTRL_CROP_END_Y_REG |
1907 OV8865_AUTO_SIZE_CTRL_CROP_END_X_REG |
1908 OV8865_AUTO_SIZE_CTRL_CROP_START_Y_REG |
1909 OV8865_AUTO_SIZE_CTRL_CROP_START_X_REG);
1910 if (ret)
1911 return ret;
1912
1913 ret = ov8865_write(sensor, OV8865_AUTO_SIZE_BOUNDARIES_REG,
1914 OV8865_AUTO_SIZE_BOUNDARIES_Y(mode->size_auto_boundary_y) |
1915 OV8865_AUTO_SIZE_BOUNDARIES_X(mode->size_auto_boundary_x));
1916 if (ret)
1917 return ret;
1918 } else {
1919 /* Crop Start X */
1920
1921 ret = ov8865_write(sensor, OV8865_CROP_START_X_H_REG,
1922 OV8865_CROP_START_X_H(mode->crop_start_x));
1923 if (ret)
1924 return ret;
1925
1926 ret = ov8865_write(sensor, OV8865_CROP_START_X_L_REG,
1927 OV8865_CROP_START_X_L(mode->crop_start_x));
1928 if (ret)
1929 return ret;
1930
1931 /* Offset X */
1932
1933 ret = ov8865_write(sensor, OV8865_OFFSET_X_H_REG,
1934 OV8865_OFFSET_X_H(mode->offset_x));
1935 if (ret)
1936 return ret;
1937
1938 ret = ov8865_write(sensor, OV8865_OFFSET_X_L_REG,
1939 OV8865_OFFSET_X_L(mode->offset_x));
1940 if (ret)
1941 return ret;
1942
1943 /* Crop End X */
1944
1945 ret = ov8865_write(sensor, OV8865_CROP_END_X_H_REG,
1946 OV8865_CROP_END_X_H(mode->crop_end_x));
1947 if (ret)
1948 return ret;
1949
1950 ret = ov8865_write(sensor, OV8865_CROP_END_X_L_REG,
1951 OV8865_CROP_END_X_L(mode->crop_end_x));
1952 if (ret)
1953 return ret;
1954
1955 /* Crop Start Y */
1956
1957 ret = ov8865_write(sensor, OV8865_CROP_START_Y_H_REG,
1958 OV8865_CROP_START_Y_H(mode->crop_start_y));
1959 if (ret)
1960 return ret;
1961
1962 ret = ov8865_write(sensor, OV8865_CROP_START_Y_L_REG,
1963 OV8865_CROP_START_Y_L(mode->crop_start_y));
1964 if (ret)
1965 return ret;
1966
1967 /* Offset Y */
1968
1969 ret = ov8865_write(sensor, OV8865_OFFSET_Y_H_REG,
1970 OV8865_OFFSET_Y_H(mode->offset_y));
1971 if (ret)
1972 return ret;
1973
1974 ret = ov8865_write(sensor, OV8865_OFFSET_Y_L_REG,
1975 OV8865_OFFSET_Y_L(mode->offset_y));
1976 if (ret)
1977 return ret;
1978
1979 /* Crop End Y */
1980
1981 ret = ov8865_write(sensor, OV8865_CROP_END_Y_H_REG,
1982 OV8865_CROP_END_Y_H(mode->crop_end_y));
1983 if (ret)
1984 return ret;
1985
1986 ret = ov8865_write(sensor, OV8865_CROP_END_Y_L_REG,
1987 OV8865_CROP_END_Y_L(mode->crop_end_y));
1988 if (ret)
1989 return ret;
1990 }
1991
1992 /* VFIFO */
1993
1994 ret = ov8865_write(sensor, OV8865_VFIFO_READ_START_H_REG,
1995 OV8865_VFIFO_READ_START_H(mode->vfifo_read_start));
1996 if (ret)
1997 return ret;
1998
1999 ret = ov8865_write(sensor, OV8865_VFIFO_READ_START_L_REG,
2000 OV8865_VFIFO_READ_START_L(mode->vfifo_read_start));
2001 if (ret)
2002 return ret;
2003
2004 ret = ov8865_write(sensor, OV8865_ABLC_NUM_REG,
2005 OV8865_ABLC_NUM(mode->ablc_num));
2006 if (ret)
2007 return ret;
2008
2009 ret = ov8865_write(sensor, OV8865_ZLINE_NUM_REG,
2010 OV8865_ZLINE_NUM(mode->zline_num));
2011 if (ret)
2012 return ret;
2013
2014 /* Binning */
2015
2016 ret = ov8865_mode_binning_configure(sensor, mode);
2017 if (ret)
2018 return ret;
2019
2020 /* Black Level */
2021
2022 ret = ov8865_mode_black_level_configure(sensor, mode);
2023 if (ret)
2024 return ret;
2025
2026 /* PLLs */
2027
2028 ret = ov8865_mode_pll1_configure(sensor, mode, mbus_code);
2029 if (ret)
2030 return ret;
2031
2032 ret = ov8865_mode_pll2_configure(sensor, mode);
2033 if (ret)
2034 return ret;
2035
2036 ret = ov8865_mode_sclk_configure(sensor, mode);
2037 if (ret)
2038 return ret;
2039
2040 /* Extra registers */
2041
2042 if (mode->register_values) {
2043 ret = ov8865_write_sequence(sensor, mode->register_values,
2044 mode->register_values_count);
2045 if (ret)
2046 return ret;
2047 }
2048
2049 return 0;
2050}
2051
2052static unsigned long ov8865_mode_mipi_clk_rate(struct ov8865_sensor *sensor,
2053 const struct ov8865_mode *mode)
2054{
2055 const struct ov8865_pll1_config *config = mode->pll1_config;
2056 unsigned long pll1_rate;
2057
2058 pll1_rate = ov8865_mode_pll1_rate(sensor, mode);
2059
2060 return pll1_rate / config->m_div / 2;
2061}
2062
2063/* Exposure */
2064
2065static int ov8865_exposure_configure(struct ov8865_sensor *sensor, u32 exposure)
2066{
2067 int ret;
2068
2069 ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_HH_REG,
2070 OV8865_EXPOSURE_CTRL_HH(exposure));
2071 if (ret)
2072 return ret;
2073
2074 ret = ov8865_write(sensor, OV8865_EXPOSURE_CTRL_H_REG,
2075 OV8865_EXPOSURE_CTRL_H(exposure));
2076 if (ret)
2077 return ret;
2078
2079 return ov8865_write(sensor, OV8865_EXPOSURE_CTRL_L_REG,
2080 OV8865_EXPOSURE_CTRL_L(exposure));
2081}
2082
2083/* Gain */
2084
2085static int ov8865_gain_configure(struct ov8865_sensor *sensor, u32 gain)
2086{
2087 int ret;
2088
2089 ret = ov8865_write(sensor, OV8865_GAIN_CTRL_H_REG,
2090 OV8865_GAIN_CTRL_H(gain));
2091 if (ret)
2092 return ret;
2093
2094 return ov8865_write(sensor, OV8865_GAIN_CTRL_L_REG,
2095 OV8865_GAIN_CTRL_L(gain));
2096}
2097
2098/* White Balance */
2099
2100static int ov8865_red_balance_configure(struct ov8865_sensor *sensor,
2101 u32 red_balance)
2102{
2103 int ret;
2104
2105 ret = ov8865_write(sensor, OV8865_ISP_GAIN_RED_H_REG,
2106 OV8865_ISP_GAIN_RED_H(red_balance));
2107 if (ret)
2108 return ret;
2109
2110 return ov8865_write(sensor, OV8865_ISP_GAIN_RED_L_REG,
2111 OV8865_ISP_GAIN_RED_L(red_balance));
2112}
2113
2114static int ov8865_blue_balance_configure(struct ov8865_sensor *sensor,
2115 u32 blue_balance)
2116{
2117 int ret;
2118
2119 ret = ov8865_write(sensor, OV8865_ISP_GAIN_BLUE_H_REG,
2120 OV8865_ISP_GAIN_BLUE_H(blue_balance));
2121 if (ret)
2122 return ret;
2123
2124 return ov8865_write(sensor, OV8865_ISP_GAIN_BLUE_L_REG,
2125 OV8865_ISP_GAIN_BLUE_L(blue_balance));
2126}
2127
2128/* Flip */
2129
2130static int ov8865_flip_vert_configure(struct ov8865_sensor *sensor, bool enable)
2131{
2132 u8 bits = OV8865_FORMAT1_FLIP_VERT_ISP_EN |
2133 OV8865_FORMAT1_FLIP_VERT_SENSOR_EN;
2134
2135 return ov8865_update_bits(sensor, OV8865_FORMAT1_REG, bits,
2136 enable ? bits : 0);
2137}
2138
2139static int ov8865_flip_horz_configure(struct ov8865_sensor *sensor, bool enable)
2140{
2141 u8 bits = OV8865_FORMAT2_FLIP_HORZ_ISP_EN |
2142 OV8865_FORMAT2_FLIP_HORZ_SENSOR_EN;
2143
2144 return ov8865_update_bits(sensor, OV8865_FORMAT2_REG, bits,
2145 enable ? bits : 0);
2146}
2147
2148/* Test Pattern */
2149
2150static int ov8865_test_pattern_configure(struct ov8865_sensor *sensor,
2151 unsigned int index)
2152{
2153 if (index >= ARRAY_SIZE(ov8865_test_pattern_bits))
2154 return -EINVAL;
2155
2156 return ov8865_write(sensor, OV8865_PRE_CTRL0_REG,
2157 ov8865_test_pattern_bits[index]);
2158}
2159
2160/* State */
2161
2162static int ov8865_state_mipi_configure(struct ov8865_sensor *sensor,
2163 const struct ov8865_mode *mode,
2164 u32 mbus_code)
2165{
2166 struct ov8865_ctrls *ctrls = &sensor->ctrls;
2167 struct v4l2_fwnode_bus_mipi_csi2 *bus_mipi_csi2 =
2168 &sensor->endpoint.bus.mipi_csi2;
2169 unsigned long mipi_clk_rate;
2170 unsigned int bits_per_sample;
2171 unsigned int lanes_count;
2172 unsigned int i, j;
2173 s64 mipi_pixel_rate;
2174
2175 mipi_clk_rate = ov8865_mode_mipi_clk_rate(sensor, mode);
2176 if (!mipi_clk_rate)
2177 return -EINVAL;
2178
2179 for (i = 0; i < ARRAY_SIZE(ov8865_link_freq_menu); i++) {
2180 s64 freq = ov8865_link_freq_menu[i];
2181
2182 if (freq == mipi_clk_rate)
2183 break;
2184 }
2185
2186 for (j = 0; j < sensor->endpoint.nr_of_link_frequencies; j++) {
2187 u64 freq = sensor->endpoint.link_frequencies[j];
2188
2189 if (freq == mipi_clk_rate)
2190 break;
2191 }
2192
2193 if (i == ARRAY_SIZE(ov8865_link_freq_menu)) {
2194 dev_err(sensor->dev,
2195 "failed to find %lu clk rate in link freq\n",
2196 mipi_clk_rate);
2197 } else if (j == sensor->endpoint.nr_of_link_frequencies) {
2198 dev_err(sensor->dev,
2199 "failed to find %lu clk rate in endpoint link-frequencies\n",
2200 mipi_clk_rate);
2201 } else {
2202 __v4l2_ctrl_s_ctrl(ctrls->link_freq, i);
2203 }
2204
2205 switch (mbus_code) {
2206 case MEDIA_BUS_FMT_SBGGR10_1X10:
2207 bits_per_sample = 10;
2208 break;
2209 default:
2210 return -EINVAL;
2211 }
2212
2213 lanes_count = bus_mipi_csi2->num_data_lanes;
2214 mipi_pixel_rate = mipi_clk_rate * 2 * lanes_count / bits_per_sample;
2215
2216 __v4l2_ctrl_s_ctrl_int64(ctrls->pixel_rate, mipi_pixel_rate);
2217
2218 return 0;
2219}
2220
2221static int ov8865_state_configure(struct ov8865_sensor *sensor,
2222 const struct ov8865_mode *mode,
2223 u32 mbus_code)
2224{
2225 int ret;
2226
2227 if (sensor->state.streaming)
2228 return -EBUSY;
2229
2230 /* State will be configured at first power on otherwise. */
2231 if (pm_runtime_enabled(sensor->dev) &&
2232 !pm_runtime_suspended(sensor->dev)) {
2233 ret = ov8865_mode_configure(sensor, mode, mbus_code);
2234 if (ret)
2235 return ret;
2236 }
2237
2238 ret = ov8865_state_mipi_configure(sensor, mode, mbus_code);
2239 if (ret)
2240 return ret;
2241
2242 sensor->state.mode = mode;
2243 sensor->state.mbus_code = mbus_code;
2244
2245 return 0;
2246}
2247
2248static int ov8865_state_init(struct ov8865_sensor *sensor)
2249{
2250 return ov8865_state_configure(sensor, &ov8865_modes[0],
2251 ov8865_mbus_codes[0]);
2252}
2253
2254/* Sensor Base */
2255
2256static int ov8865_sensor_init(struct ov8865_sensor *sensor)
2257{
2258 int ret;
2259
2260 ret = ov8865_sw_reset(sensor);
2261 if (ret) {
2262 dev_err(sensor->dev, "failed to perform sw reset\n");
2263 return ret;
2264 }
2265
2266 ret = ov8865_sw_standby(sensor, 1);
2267 if (ret) {
2268 dev_err(sensor->dev, "failed to set sensor standby\n");
2269 return ret;
2270 }
2271
2272 ret = ov8865_chip_id_check(sensor);
2273 if (ret) {
2274 dev_err(sensor->dev, "failed to check sensor chip id\n");
2275 return ret;
2276 }
2277
2278 ret = ov8865_write_sequence(sensor, ov8865_init_sequence,
2279 ARRAY_SIZE(ov8865_init_sequence));
2280 if (ret) {
2281 dev_err(sensor->dev, "failed to write init sequence\n");
2282 return ret;
2283 }
2284
2285 ret = ov8865_charge_pump_configure(sensor);
2286 if (ret) {
2287 dev_err(sensor->dev, "failed to configure pad\n");
2288 return ret;
2289 }
2290
2291 ret = ov8865_mipi_configure(sensor);
2292 if (ret) {
2293 dev_err(sensor->dev, "failed to configure MIPI\n");
2294 return ret;
2295 }
2296
2297 ret = ov8865_isp_configure(sensor);
2298 if (ret) {
2299 dev_err(sensor->dev, "failed to configure ISP\n");
2300 return ret;
2301 }
2302
2303 ret = ov8865_black_level_configure(sensor);
2304 if (ret) {
2305 dev_err(sensor->dev, "failed to configure black level\n");
2306 return ret;
2307 }
2308
2309 /* Configure current mode. */
2310 ret = ov8865_state_configure(sensor, sensor->state.mode,
2311 sensor->state.mbus_code);
2312 if (ret) {
2313 dev_err(sensor->dev, "failed to configure state\n");
2314 return ret;
2315 }
2316
2317 return 0;
2318}
2319
2320static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on)
2321{
2322 /* Keep initialized to zero for disable label. */
2323 int ret = 0;
2324
2325 if (on) {
2326 gpiod_set_value_cansleep(sensor->reset, 1);
2327 gpiod_set_value_cansleep(sensor->powerdown, 1);
2328
2329 ret = regulator_enable(sensor->dovdd);
2330 if (ret) {
2331 dev_err(sensor->dev,
2332 "failed to enable DOVDD regulator\n");
2333 goto disable;
2334 }
2335
2336 ret = regulator_enable(sensor->avdd);
2337 if (ret) {
2338 dev_err(sensor->dev,
2339 "failed to enable AVDD regulator\n");
2340 goto disable;
2341 }
2342
2343 ret = regulator_enable(sensor->dvdd);
2344 if (ret) {
2345 dev_err(sensor->dev,
2346 "failed to enable DVDD regulator\n");
2347 goto disable;
2348 }
2349
2350 ret = clk_prepare_enable(sensor->extclk);
2351 if (ret) {
2352 dev_err(sensor->dev, "failed to enable EXTCLK clock\n");
2353 goto disable;
2354 }
2355
2356 gpiod_set_value_cansleep(sensor->reset, 0);
2357 gpiod_set_value_cansleep(sensor->powerdown, 0);
2358
2359 /* Time to enter streaming mode according to power timings. */
2360 usleep_range(10000, 12000);
2361 } else {
2362disable:
2363 gpiod_set_value_cansleep(sensor->powerdown, 1);
2364 gpiod_set_value_cansleep(sensor->reset, 1);
2365
2366 clk_disable_unprepare(sensor->extclk);
2367
2368 regulator_disable(sensor->dvdd);
2369 regulator_disable(sensor->avdd);
2370 regulator_disable(sensor->dovdd);
2371 }
2372
2373 return ret;
2374}
2375
2376/* Controls */
2377
2378static int ov8865_s_ctrl(struct v4l2_ctrl *ctrl)
2379{
2380 struct v4l2_subdev *subdev = ov8865_ctrl_subdev(ctrl);
2381 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2382 unsigned int index;
2383 int ret;
2384
2385 /* Wait for the sensor to be on before setting controls. */
2386 if (pm_runtime_suspended(sensor->dev))
2387 return 0;
2388
2389 switch (ctrl->id) {
2390 case V4L2_CID_EXPOSURE:
2391 ret = ov8865_exposure_configure(sensor, ctrl->val);
2392 if (ret)
2393 return ret;
2394 break;
2395 case V4L2_CID_GAIN:
2396 ret = ov8865_gain_configure(sensor, ctrl->val);
2397 if (ret)
2398 return ret;
2399 break;
2400 case V4L2_CID_RED_BALANCE:
2401 return ov8865_red_balance_configure(sensor, ctrl->val);
2402 case V4L2_CID_BLUE_BALANCE:
2403 return ov8865_blue_balance_configure(sensor, ctrl->val);
2404 case V4L2_CID_HFLIP:
2405 return ov8865_flip_horz_configure(sensor, !!ctrl->val);
2406 case V4L2_CID_VFLIP:
2407 return ov8865_flip_vert_configure(sensor, !!ctrl->val);
2408 case V4L2_CID_TEST_PATTERN:
2409 index = (unsigned int)ctrl->val;
2410 return ov8865_test_pattern_configure(sensor, index);
2411 default:
2412 return -EINVAL;
2413 }
2414
2415 return 0;
2416}
2417
2418static const struct v4l2_ctrl_ops ov8865_ctrl_ops = {
2419 .s_ctrl = ov8865_s_ctrl,
2420};
2421
2422static int ov8865_ctrls_init(struct ov8865_sensor *sensor)
2423{
2424 struct ov8865_ctrls *ctrls = &sensor->ctrls;
2425 struct v4l2_ctrl_handler *handler = &ctrls->handler;
2426 const struct v4l2_ctrl_ops *ops = &ov8865_ctrl_ops;
2427 int ret;
2428
2429 v4l2_ctrl_handler_init(handler, 32);
2430
2431 /* Use our mutex for ctrl locking. */
2432 handler->lock = &sensor->mutex;
2433
2434 /* Exposure */
2435
2436 v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 16, 1048575, 16,
2437 512);
2438
2439 /* Gain */
2440
2441 v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 128, 8191, 128, 128);
2442
2443 /* White Balance */
2444
2445 v4l2_ctrl_new_std(handler, ops, V4L2_CID_RED_BALANCE, 1, 32767, 1,
2446 1024);
2447
2448 v4l2_ctrl_new_std(handler, ops, V4L2_CID_BLUE_BALANCE, 1, 32767, 1,
2449 1024);
2450
2451 /* Flip */
2452
2453 v4l2_ctrl_new_std(handler, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
2454 v4l2_ctrl_new_std(handler, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
2455
2456 /* Test Pattern */
2457
2458 v4l2_ctrl_new_std_menu_items(handler, ops, V4L2_CID_TEST_PATTERN,
2459 ARRAY_SIZE(ov8865_test_pattern_menu) - 1,
2460 0, 0, ov8865_test_pattern_menu);
2461
2462 /* MIPI CSI-2 */
2463
2464 ctrls->link_freq =
2465 v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
2466 ARRAY_SIZE(ov8865_link_freq_menu) - 1,
2467 0, ov8865_link_freq_menu);
2468
2469 ctrls->pixel_rate =
2470 v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, 1,
2471 INT_MAX, 1, 1);
2472
2473 if (handler->error) {
2474 ret = handler->error;
2475 goto error_ctrls;
2476 }
2477
2478 ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2479 ctrls->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY;
2480
2481 sensor->subdev.ctrl_handler = handler;
2482
2483 return 0;
2484
2485error_ctrls:
2486 v4l2_ctrl_handler_free(handler);
2487
2488 return ret;
2489}
2490
2491/* Subdev Video Operations */
2492
2493static int ov8865_s_stream(struct v4l2_subdev *subdev, int enable)
2494{
2495 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2496 struct ov8865_state *state = &sensor->state;
2497 int ret;
2498
2499 if (enable) {
586ee057
MCC
2500 ret = pm_runtime_resume_and_get(sensor->dev);
2501 if (ret < 0)
11c0d8fd 2502 return ret;
11c0d8fd
PK
2503 }
2504
2505 mutex_lock(&sensor->mutex);
2506 ret = ov8865_sw_standby(sensor, !enable);
2507 mutex_unlock(&sensor->mutex);
2508
2509 if (ret)
2510 return ret;
2511
2512 state->streaming = !!enable;
2513
2514 if (!enable)
2515 pm_runtime_put(sensor->dev);
2516
2517 return 0;
2518}
2519
2520static int ov8865_g_frame_interval(struct v4l2_subdev *subdev,
2521 struct v4l2_subdev_frame_interval *interval)
2522{
2523 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2524 const struct ov8865_mode *mode;
11c0d8fd
PK
2525
2526 mutex_lock(&sensor->mutex);
2527
2528 mode = sensor->state.mode;
2529 interval->interval = mode->frame_interval;
2530
2531 mutex_unlock(&sensor->mutex);
2532
a1946caf 2533 return 0;
11c0d8fd
PK
2534}
2535
2536static const struct v4l2_subdev_video_ops ov8865_subdev_video_ops = {
2537 .s_stream = ov8865_s_stream,
2538 .g_frame_interval = ov8865_g_frame_interval,
2539 .s_frame_interval = ov8865_g_frame_interval,
2540};
2541
2542/* Subdev Pad Operations */
2543
2544static int ov8865_enum_mbus_code(struct v4l2_subdev *subdev,
0d346d2a 2545 struct v4l2_subdev_state *sd_state,
11c0d8fd
PK
2546 struct v4l2_subdev_mbus_code_enum *code_enum)
2547{
2548 if (code_enum->index >= ARRAY_SIZE(ov8865_mbus_codes))
2549 return -EINVAL;
2550
2551 code_enum->code = ov8865_mbus_codes[code_enum->index];
2552
2553 return 0;
2554}
2555
2556static void ov8865_mbus_format_fill(struct v4l2_mbus_framefmt *mbus_format,
2557 u32 mbus_code,
2558 const struct ov8865_mode *mode)
2559{
2560 mbus_format->width = mode->output_size_x;
2561 mbus_format->height = mode->output_size_y;
2562 mbus_format->code = mbus_code;
2563
2564 mbus_format->field = V4L2_FIELD_NONE;
2565 mbus_format->colorspace = V4L2_COLORSPACE_RAW;
2566 mbus_format->ycbcr_enc =
2567 V4L2_MAP_YCBCR_ENC_DEFAULT(mbus_format->colorspace);
2568 mbus_format->quantization = V4L2_QUANTIZATION_FULL_RANGE;
2569 mbus_format->xfer_func =
2570 V4L2_MAP_XFER_FUNC_DEFAULT(mbus_format->colorspace);
2571}
2572
2573static int ov8865_get_fmt(struct v4l2_subdev *subdev,
0d346d2a 2574 struct v4l2_subdev_state *sd_state,
11c0d8fd
PK
2575 struct v4l2_subdev_format *format)
2576{
2577 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2578 struct v4l2_mbus_framefmt *mbus_format = &format->format;
2579
2580 mutex_lock(&sensor->mutex);
2581
2582 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
0d346d2a 2583 *mbus_format = *v4l2_subdev_get_try_format(subdev, sd_state,
11c0d8fd
PK
2584 format->pad);
2585 else
2586 ov8865_mbus_format_fill(mbus_format, sensor->state.mbus_code,
2587 sensor->state.mode);
2588
2589 mutex_unlock(&sensor->mutex);
2590
2591 return 0;
2592}
2593
2594static int ov8865_set_fmt(struct v4l2_subdev *subdev,
0d346d2a 2595 struct v4l2_subdev_state *sd_state,
11c0d8fd
PK
2596 struct v4l2_subdev_format *format)
2597{
2598 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2599 struct v4l2_mbus_framefmt *mbus_format = &format->format;
2600 const struct ov8865_mode *mode;
2601 u32 mbus_code = 0;
2602 unsigned int index;
2603 int ret = 0;
2604
2605 mutex_lock(&sensor->mutex);
2606
2607 if (sensor->state.streaming) {
2608 ret = -EBUSY;
2609 goto complete;
2610 }
2611
2612 /* Try to find requested mbus code. */
2613 for (index = 0; index < ARRAY_SIZE(ov8865_mbus_codes); index++) {
2614 if (ov8865_mbus_codes[index] == mbus_format->code) {
2615 mbus_code = mbus_format->code;
2616 break;
2617 }
2618 }
2619
2620 /* Fallback to default. */
2621 if (!mbus_code)
2622 mbus_code = ov8865_mbus_codes[0];
2623
2624 /* Find the mode with nearest dimensions. */
2625 mode = v4l2_find_nearest_size(ov8865_modes, ARRAY_SIZE(ov8865_modes),
2626 output_size_x, output_size_y,
2627 mbus_format->width, mbus_format->height);
2628 if (!mode) {
2629 ret = -EINVAL;
2630 goto complete;
2631 }
2632
2633 ov8865_mbus_format_fill(mbus_format, mbus_code, mode);
2634
2635 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
0d346d2a 2636 *v4l2_subdev_get_try_format(subdev, sd_state, format->pad) =
11c0d8fd
PK
2637 *mbus_format;
2638 else if (sensor->state.mode != mode ||
2639 sensor->state.mbus_code != mbus_code)
2640 ret = ov8865_state_configure(sensor, mode, mbus_code);
2641
2642complete:
2643 mutex_unlock(&sensor->mutex);
2644
2645 return ret;
2646}
2647
2648static int ov8865_enum_frame_size(struct v4l2_subdev *subdev,
0d346d2a 2649 struct v4l2_subdev_state *sd_state,
11c0d8fd
PK
2650 struct v4l2_subdev_frame_size_enum *size_enum)
2651{
2652 const struct ov8865_mode *mode;
2653
2654 if (size_enum->index >= ARRAY_SIZE(ov8865_modes))
2655 return -EINVAL;
2656
2657 mode = &ov8865_modes[size_enum->index];
2658
2659 size_enum->min_width = size_enum->max_width = mode->output_size_x;
2660 size_enum->min_height = size_enum->max_height = mode->output_size_y;
2661
2662 return 0;
2663}
2664
2665static int ov8865_enum_frame_interval(struct v4l2_subdev *subdev,
0d346d2a 2666 struct v4l2_subdev_state *sd_state,
11c0d8fd
PK
2667 struct v4l2_subdev_frame_interval_enum *interval_enum)
2668{
2669 const struct ov8865_mode *mode = NULL;
2670 unsigned int mode_index;
2671 unsigned int interval_index;
2672
2673 if (interval_enum->index > 0)
2674 return -EINVAL;
2675 /*
2676 * Multiple modes with the same dimensions may have different frame
2677 * intervals, so look up each relevant mode.
2678 */
2679 for (mode_index = 0, interval_index = 0;
2680 mode_index < ARRAY_SIZE(ov8865_modes); mode_index++) {
2681 mode = &ov8865_modes[mode_index];
2682
2683 if (mode->output_size_x == interval_enum->width &&
2684 mode->output_size_y == interval_enum->height) {
2685 if (interval_index == interval_enum->index)
2686 break;
2687
2688 interval_index++;
2689 }
2690 }
2691
45dbd70c 2692 if (mode_index == ARRAY_SIZE(ov8865_modes))
11c0d8fd
PK
2693 return -EINVAL;
2694
2695 interval_enum->interval = mode->frame_interval;
2696
2697 return 0;
2698}
2699
2700static const struct v4l2_subdev_pad_ops ov8865_subdev_pad_ops = {
2701 .enum_mbus_code = ov8865_enum_mbus_code,
2702 .get_fmt = ov8865_get_fmt,
2703 .set_fmt = ov8865_set_fmt,
2704 .enum_frame_size = ov8865_enum_frame_size,
2705 .enum_frame_interval = ov8865_enum_frame_interval,
2706};
2707
2708static const struct v4l2_subdev_ops ov8865_subdev_ops = {
2709 .video = &ov8865_subdev_video_ops,
2710 .pad = &ov8865_subdev_pad_ops,
2711};
2712
2713static int ov8865_suspend(struct device *dev)
2714{
2715 struct i2c_client *client = to_i2c_client(dev);
2716 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2717 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2718 struct ov8865_state *state = &sensor->state;
2719 int ret = 0;
2720
2721 mutex_lock(&sensor->mutex);
2722
2723 if (state->streaming) {
2724 ret = ov8865_sw_standby(sensor, true);
2725 if (ret)
2726 goto complete;
2727 }
2728
2729 ret = ov8865_sensor_power(sensor, false);
2730 if (ret)
2731 ov8865_sw_standby(sensor, false);
2732
2733complete:
2734 mutex_unlock(&sensor->mutex);
2735
2736 return ret;
2737}
2738
2739static int ov8865_resume(struct device *dev)
2740{
2741 struct i2c_client *client = to_i2c_client(dev);
2742 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2743 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2744 struct ov8865_state *state = &sensor->state;
2745 int ret = 0;
2746
2747 mutex_lock(&sensor->mutex);
2748
2749 ret = ov8865_sensor_power(sensor, true);
2750 if (ret)
2751 goto complete;
2752
2753 ret = ov8865_sensor_init(sensor);
2754 if (ret)
2755 goto error_power;
2756
2757 ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
2758 if (ret)
2759 goto error_power;
2760
2761 if (state->streaming) {
2762 ret = ov8865_sw_standby(sensor, false);
2763 if (ret)
2764 goto error_power;
2765 }
2766
2767 goto complete;
2768
2769error_power:
2770 ov8865_sensor_power(sensor, false);
2771
2772complete:
2773 mutex_unlock(&sensor->mutex);
2774
2775 return ret;
2776}
2777
2778static int ov8865_probe(struct i2c_client *client)
2779{
2780 struct device *dev = &client->dev;
2781 struct fwnode_handle *handle;
2782 struct ov8865_sensor *sensor;
2783 struct v4l2_subdev *subdev;
2784 struct media_pad *pad;
2785 unsigned long rate;
2786 int ret;
2787
2788 sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL);
2789 if (!sensor)
2790 return -ENOMEM;
2791
2792 sensor->dev = dev;
2793 sensor->i2c_client = client;
2794
2795 /* Graph Endpoint */
2796
2797 handle = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
2798 if (!handle) {
ea12d248 2799 dev_err(dev, "unable to find endpoint node\n");
11c0d8fd
PK
2800 return -EINVAL;
2801 }
2802
2803 sensor->endpoint.bus_type = V4L2_MBUS_CSI2_DPHY;
2804
2805 ret = v4l2_fwnode_endpoint_alloc_parse(handle, &sensor->endpoint);
2806 fwnode_handle_put(handle);
2807 if (ret) {
2808 dev_err(dev, "failed to parse endpoint node\n");
2809 return ret;
2810 }
2811
2812 /* GPIOs */
2813
2814 sensor->powerdown = devm_gpiod_get_optional(dev, "powerdown",
2815 GPIOD_OUT_HIGH);
2816 if (IS_ERR(sensor->powerdown)) {
2817 ret = PTR_ERR(sensor->powerdown);
2818 goto error_endpoint;
2819 }
2820
2821 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
2822 if (IS_ERR(sensor->reset)) {
2823 ret = PTR_ERR(sensor->reset);
2824 goto error_endpoint;
2825 }
2826
2827 /* Regulators */
2828
2829 /* DVDD: digital core */
2830 sensor->dvdd = devm_regulator_get(dev, "dvdd");
2831 if (IS_ERR(sensor->dvdd)) {
2832 dev_err(dev, "cannot get DVDD (digital core) regulator\n");
2833 ret = PTR_ERR(sensor->dvdd);
2834 goto error_endpoint;
2835 }
2836
2837 /* DOVDD: digital I/O */
2838 sensor->dovdd = devm_regulator_get(dev, "dovdd");
6e7cca27 2839 if (IS_ERR(sensor->dovdd)) {
11c0d8fd 2840 dev_err(dev, "cannot get DOVDD (digital I/O) regulator\n");
6e7cca27 2841 ret = PTR_ERR(sensor->dovdd);
11c0d8fd
PK
2842 goto error_endpoint;
2843 }
2844
2845 /* AVDD: analog */
2846 sensor->avdd = devm_regulator_get(dev, "avdd");
2847 if (IS_ERR(sensor->avdd)) {
2848 dev_err(dev, "cannot get AVDD (analog) regulator\n");
6e7cca27 2849 ret = PTR_ERR(sensor->avdd);
11c0d8fd
PK
2850 goto error_endpoint;
2851 }
2852
2853 /* External Clock */
2854
2855 sensor->extclk = devm_clk_get(dev, NULL);
2856 if (IS_ERR(sensor->extclk)) {
2857 dev_err(dev, "failed to get external clock\n");
2858 ret = PTR_ERR(sensor->extclk);
2859 goto error_endpoint;
2860 }
2861
2862 rate = clk_get_rate(sensor->extclk);
2863 if (rate != OV8865_EXTCLK_RATE) {
2864 dev_err(dev, "clock rate %lu Hz is unsupported\n", rate);
2865 ret = -EINVAL;
2866 goto error_endpoint;
2867 }
2868
2869 /* Subdev, entity and pad */
2870
2871 subdev = &sensor->subdev;
2872 v4l2_i2c_subdev_init(subdev, client, &ov8865_subdev_ops);
2873
2874 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
2875 subdev->entity.function = MEDIA_ENT_F_CAM_SENSOR;
2876
2877 pad = &sensor->pad;
2878 pad->flags = MEDIA_PAD_FL_SOURCE;
2879
2880 ret = media_entity_pads_init(&subdev->entity, 1, pad);
2881 if (ret)
2882 goto error_entity;
2883
2884 /* Mutex */
2885
2886 mutex_init(&sensor->mutex);
2887
2888 /* Sensor */
2889
2890 ret = ov8865_ctrls_init(sensor);
2891 if (ret)
2892 goto error_mutex;
2893
2894 ret = ov8865_state_init(sensor);
2895 if (ret)
2896 goto error_ctrls;
2897
2898 /* Runtime PM */
2899
2900 pm_runtime_enable(sensor->dev);
2901 pm_runtime_set_suspended(sensor->dev);
2902
2903 /* V4L2 subdev register */
2904
15786f7b 2905 ret = v4l2_async_register_subdev_sensor(subdev);
11c0d8fd
PK
2906 if (ret)
2907 goto error_pm;
2908
2909 return 0;
2910
2911error_pm:
2912 pm_runtime_disable(sensor->dev);
2913
2914error_ctrls:
2915 v4l2_ctrl_handler_free(&sensor->ctrls.handler);
2916
2917error_mutex:
2918 mutex_destroy(&sensor->mutex);
2919
2920error_entity:
2921 media_entity_cleanup(&sensor->subdev.entity);
2922
2923error_endpoint:
2924 v4l2_fwnode_endpoint_free(&sensor->endpoint);
2925
2926 return ret;
2927}
2928
2929static int ov8865_remove(struct i2c_client *client)
2930{
2931 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
2932 struct ov8865_sensor *sensor = ov8865_subdev_sensor(subdev);
2933
2934 v4l2_async_unregister_subdev(subdev);
2935 pm_runtime_disable(sensor->dev);
2936 v4l2_ctrl_handler_free(&sensor->ctrls.handler);
2937 mutex_destroy(&sensor->mutex);
2938 media_entity_cleanup(&subdev->entity);
2939
2940 v4l2_fwnode_endpoint_free(&sensor->endpoint);
2941
2942 return 0;
2943}
2944
2945static const struct dev_pm_ops ov8865_pm_ops = {
2946 SET_RUNTIME_PM_OPS(ov8865_suspend, ov8865_resume, NULL)
2947};
2948
2949static const struct of_device_id ov8865_of_match[] = {
2950 { .compatible = "ovti,ov8865" },
2951 { }
2952};
2953MODULE_DEVICE_TABLE(of, ov8865_of_match);
2954
2955static struct i2c_driver ov8865_driver = {
2956 .driver = {
2957 .name = "ov8865",
2958 .of_match_table = ov8865_of_match,
2959 .pm = &ov8865_pm_ops,
2960 },
2961 .probe_new = ov8865_probe,
2962 .remove = ov8865_remove,
2963};
2964
2965module_i2c_driver(ov8865_driver);
2966
2967MODULE_AUTHOR("Paul Kocialkowski <paul.kocialkowski@bootlin.com>");
2968MODULE_DESCRIPTION("V4L2 driver for the OmniVision OV8865 image sensor");
2969MODULE_LICENSE("GPL v2");