1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (c) 2013 Intel Corporation. All Rights Reserved. |
4 | * |
5 | * Adapted from the atomisp-ov5693 driver, with contributions from: |
6 | * |
7 | * Daniel Scally |
8 | * Jean-Michel Hautbois |
9 | * Fabian Wuthrich |
10 | * Tsuchiya Yuto |
11 | * Jordan Hand |
12 | * Jake Day |
13 | */ |
14 | |
15 | #include <linux/acpi.h> |
16 | #include <linux/clk.h> |
17 | #include <linux/delay.h> |
18 | #include <linux/device.h> |
19 | #include <linux/i2c.h> |
20 | #include <linux/module.h> |
21 | #include <linux/pm_runtime.h> |
22 | #include <linux/regulator/consumer.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/types.h> |
25 | |
26 | #include <media/v4l2-cci.h> |
27 | #include <media/v4l2-ctrls.h> |
28 | #include <media/v4l2-device.h> |
29 | #include <media/v4l2-fwnode.h> |
30 | |
31 | /* System Control */ |
32 | #define OV5693_SW_RESET_REG CCI_REG8(0x0103) |
33 | #define OV5693_SW_STREAM_REG CCI_REG8(0x0100) |
34 | #define OV5693_START_STREAMING 0x01 |
35 | #define OV5693_STOP_STREAMING 0x00 |
36 | #define OV5693_SW_RESET 0x01 |
37 | |
38 | #define OV5693_REG_CHIP_ID CCI_REG16(0x300a) |
39 | /* Yes, this is right. The datasheet for the OV5693 gives its ID as 0x5690 */ |
40 | #define OV5693_CHIP_ID 0x5690 |
41 | |
42 | /* Exposure */ |
43 | #define OV5693_EXPOSURE_CTRL_REG CCI_REG24(0x3500) |
44 | #define OV5693_EXPOSURE_CTRL_MASK GENMASK(19, 4) |
45 | #define OV5693_INTEGRATION_TIME_MARGIN 8 |
46 | #define OV5693_EXPOSURE_MIN 1 |
47 | #define OV5693_EXPOSURE_STEP 1 |
48 | |
49 | /* Analogue Gain */ |
50 | #define OV5693_GAIN_CTRL_REG CCI_REG16(0x350a) |
51 | #define OV5693_GAIN_CTRL_MASK GENMASK(10, 4) |
52 | #define OV5693_GAIN_MIN 1 |
53 | #define OV5693_GAIN_MAX 127 |
54 | #define OV5693_GAIN_DEF 8 |
55 | #define OV5693_GAIN_STEP 1 |
56 | |
57 | /* Digital Gain */ |
58 | #define OV5693_MWB_RED_GAIN_REG CCI_REG16(0x3400) |
59 | #define OV5693_MWB_GREEN_GAIN_REG CCI_REG16(0x3402) |
60 | #define OV5693_MWB_BLUE_GAIN_REG CCI_REG16(0x3404) |
61 | #define OV5693_MWB_GAIN_MASK GENMASK(11, 0) |
62 | #define OV5693_MWB_GAIN_MAX 0x0fff |
63 | #define OV5693_DIGITAL_GAIN_MIN 1 |
64 | #define OV5693_DIGITAL_GAIN_MAX 4095 |
65 | #define OV5693_DIGITAL_GAIN_DEF 1024 |
66 | #define OV5693_DIGITAL_GAIN_STEP 1 |
67 | |
68 | /* Timing and Format */ |
69 | #define OV5693_CROP_START_X_REG CCI_REG16(0x3800) |
70 | #define OV5693_CROP_START_Y_REG CCI_REG16(0x3802) |
71 | #define OV5693_CROP_END_X_REG CCI_REG16(0x3804) |
72 | #define OV5693_CROP_END_Y_REG CCI_REG16(0x3806) |
73 | #define OV5693_OUTPUT_SIZE_X_REG CCI_REG16(0x3808) |
74 | #define OV5693_OUTPUT_SIZE_Y_REG CCI_REG16(0x380a) |
75 | |
76 | #define OV5693_TIMING_HTS_REG CCI_REG16(0x380c) |
77 | #define OV5693_FIXED_PPL 2688U |
78 | #define OV5693_TIMING_VTS_REG CCI_REG16(0x380e) |
79 | #define OV5693_TIMING_MAX_VTS 0xffff |
80 | #define OV5693_TIMING_MIN_VTS 0x04 |
81 | |
82 | #define OV5693_OFFSET_START_X_REG CCI_REG16(0x3810) |
83 | #define OV5693_OFFSET_START_Y_REG CCI_REG16(0x3812) |
84 | |
85 | #define OV5693_SUB_INC_X_REG CCI_REG8(0x3814) |
86 | #define OV5693_SUB_INC_Y_REG CCI_REG8(0x3815) |
87 | |
88 | #define OV5693_FORMAT1_REG CCI_REG8(0x3820) |
89 | #define OV5693_FORMAT1_FLIP_VERT_ISP_EN BIT(6) |
90 | #define OV5693_FORMAT1_FLIP_VERT_SENSOR_EN BIT(1) |
91 | #define OV5693_FORMAT1_VBIN_EN BIT(0) |
92 | #define OV5693_FORMAT2_REG CCI_REG8(0x3821) |
93 | #define OV5693_FORMAT2_HDR_EN BIT(7) |
94 | #define OV5693_FORMAT2_FLIP_HORZ_ISP_EN BIT(2) |
95 | #define OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN BIT(1) |
96 | #define OV5693_FORMAT2_HBIN_EN BIT(0) |
97 | |
98 | #define OV5693_ISP_CTRL2_REG CCI_REG8(0x5002) |
99 | #define OV5693_ISP_SCALE_ENABLE BIT(7) |
100 | |
101 | /* Pixel Array */ |
102 | #define OV5693_NATIVE_WIDTH 2624 |
103 | #define OV5693_NATIVE_HEIGHT 1956 |
104 | #define OV5693_NATIVE_START_LEFT 0 |
105 | #define OV5693_NATIVE_START_TOP 0 |
106 | #define OV5693_ACTIVE_WIDTH 2592 |
107 | #define OV5693_ACTIVE_HEIGHT 1944 |
108 | #define OV5693_ACTIVE_START_LEFT 16 |
109 | #define OV5693_ACTIVE_START_TOP 6 |
110 | #define OV5693_MIN_CROP_WIDTH 2 |
111 | #define OV5693_MIN_CROP_HEIGHT 2 |
112 | |
113 | /* Test Pattern */ |
114 | #define OV5693_TEST_PATTERN_REG CCI_REG8(0x5e00) |
115 | #define OV5693_TEST_PATTERN_ENABLE BIT(7) |
116 | #define OV5693_TEST_PATTERN_ROLLING BIT(6) |
117 | #define OV5693_TEST_PATTERN_RANDOM 0x01 |
118 | #define OV5693_TEST_PATTERN_BARS 0x00 |
119 | |
120 | /* System Frequencies */ |
121 | #define OV5693_XVCLK_FREQ 19200000 |
122 | #define OV5693_LINK_FREQ_419_2MHZ 419200000 |
123 | #define OV5693_PIXEL_RATE 167680000 |
124 | |
125 | #define to_ov5693_sensor(x) container_of(x, struct ov5693_device, sd) |
126 | |
127 | static const char * const ov5693_supply_names[] = { |
128 | "avdd" , /* Analog power */ |
129 | "dovdd" , /* Digital I/O power */ |
130 | "dvdd" , /* Digital circuit power */ |
131 | }; |
132 | |
133 | #define OV5693_NUM_SUPPLIES ARRAY_SIZE(ov5693_supply_names) |
134 | |
135 | struct ov5693_device { |
136 | struct device *dev; |
137 | struct regmap *regmap; |
138 | |
139 | /* Protect against concurrent changes to controls */ |
140 | struct mutex lock; |
141 | |
142 | struct gpio_desc *reset; |
143 | struct gpio_desc *powerdown; |
144 | struct gpio_desc *privacy_led; |
145 | struct regulator_bulk_data supplies[OV5693_NUM_SUPPLIES]; |
146 | struct clk *xvclk; |
147 | |
148 | struct ov5693_mode { |
149 | struct v4l2_rect crop; |
150 | struct v4l2_mbus_framefmt format; |
151 | bool binning_x; |
152 | bool binning_y; |
153 | unsigned int inc_x_odd; |
154 | unsigned int inc_y_odd; |
155 | unsigned int vts; |
156 | } mode; |
157 | |
158 | struct v4l2_subdev sd; |
159 | struct media_pad pad; |
160 | |
161 | struct ov5693_v4l2_ctrls { |
162 | struct v4l2_ctrl_handler handler; |
163 | struct v4l2_ctrl *link_freq; |
164 | struct v4l2_ctrl *pixel_rate; |
165 | struct v4l2_ctrl *exposure; |
166 | struct v4l2_ctrl *analogue_gain; |
167 | struct v4l2_ctrl *digital_gain; |
168 | struct v4l2_ctrl *hflip; |
169 | struct v4l2_ctrl *vflip; |
170 | struct v4l2_ctrl *hblank; |
171 | struct v4l2_ctrl *vblank; |
172 | struct v4l2_ctrl *test_pattern; |
173 | } ctrls; |
174 | }; |
175 | |
176 | static const struct cci_reg_sequence ov5693_global_regs[] = { |
177 | {CCI_REG8(0x3016), 0xf0}, |
178 | {CCI_REG8(0x3017), 0xf0}, |
179 | {CCI_REG8(0x3018), 0xf0}, |
180 | {CCI_REG8(0x3022), 0x01}, |
181 | {CCI_REG8(0x3028), 0x44}, |
182 | {CCI_REG8(0x3098), 0x02}, |
183 | {CCI_REG8(0x3099), 0x19}, |
184 | {CCI_REG8(0x309a), 0x02}, |
185 | {CCI_REG8(0x309b), 0x01}, |
186 | {CCI_REG8(0x309c), 0x00}, |
187 | {CCI_REG8(0x30a0), 0xd2}, |
188 | {CCI_REG8(0x30a2), 0x01}, |
189 | {CCI_REG8(0x30b2), 0x00}, |
190 | {CCI_REG8(0x30b3), 0x83}, |
191 | {CCI_REG8(0x30b4), 0x03}, |
192 | {CCI_REG8(0x30b5), 0x04}, |
193 | {CCI_REG8(0x30b6), 0x01}, |
194 | {CCI_REG8(0x3080), 0x01}, |
195 | {CCI_REG8(0x3104), 0x21}, |
196 | {CCI_REG8(0x3106), 0x00}, |
197 | {CCI_REG8(0x3406), 0x01}, |
198 | {CCI_REG8(0x3503), 0x07}, |
199 | {CCI_REG8(0x350b), 0x40}, |
200 | {CCI_REG8(0x3601), 0x0a}, |
201 | {CCI_REG8(0x3602), 0x38}, |
202 | {CCI_REG8(0x3612), 0x80}, |
203 | {CCI_REG8(0x3620), 0x54}, |
204 | {CCI_REG8(0x3621), 0xc7}, |
205 | {CCI_REG8(0x3622), 0x0f}, |
206 | {CCI_REG8(0x3625), 0x10}, |
207 | {CCI_REG8(0x3630), 0x55}, |
208 | {CCI_REG8(0x3631), 0xf4}, |
209 | {CCI_REG8(0x3632), 0x00}, |
210 | {CCI_REG8(0x3633), 0x34}, |
211 | {CCI_REG8(0x3634), 0x02}, |
212 | {CCI_REG8(0x364d), 0x0d}, |
213 | {CCI_REG8(0x364f), 0xdd}, |
214 | {CCI_REG8(0x3660), 0x04}, |
215 | {CCI_REG8(0x3662), 0x10}, |
216 | {CCI_REG8(0x3663), 0xf1}, |
217 | {CCI_REG8(0x3665), 0x00}, |
218 | {CCI_REG8(0x3666), 0x20}, |
219 | {CCI_REG8(0x3667), 0x00}, |
220 | {CCI_REG8(0x366a), 0x80}, |
221 | {CCI_REG8(0x3680), 0xe0}, |
222 | {CCI_REG8(0x3681), 0x00}, |
223 | {CCI_REG8(0x3700), 0x42}, |
224 | {CCI_REG8(0x3701), 0x14}, |
225 | {CCI_REG8(0x3702), 0xa0}, |
226 | {CCI_REG8(0x3703), 0xd8}, |
227 | {CCI_REG8(0x3704), 0x78}, |
228 | {CCI_REG8(0x3705), 0x02}, |
229 | {CCI_REG8(0x370a), 0x00}, |
230 | {CCI_REG8(0x370b), 0x20}, |
231 | {CCI_REG8(0x370c), 0x0c}, |
232 | {CCI_REG8(0x370d), 0x11}, |
233 | {CCI_REG8(0x370e), 0x00}, |
234 | {CCI_REG8(0x370f), 0x40}, |
235 | {CCI_REG8(0x3710), 0x00}, |
236 | {CCI_REG8(0x371a), 0x1c}, |
237 | {CCI_REG8(0x371b), 0x05}, |
238 | {CCI_REG8(0x371c), 0x01}, |
239 | {CCI_REG8(0x371e), 0xa1}, |
240 | {CCI_REG8(0x371f), 0x0c}, |
241 | {CCI_REG8(0x3721), 0x00}, |
242 | {CCI_REG8(0x3724), 0x10}, |
243 | {CCI_REG8(0x3726), 0x00}, |
244 | {CCI_REG8(0x372a), 0x01}, |
245 | {CCI_REG8(0x3730), 0x10}, |
246 | {CCI_REG8(0x3738), 0x22}, |
247 | {CCI_REG8(0x3739), 0xe5}, |
248 | {CCI_REG8(0x373a), 0x50}, |
249 | {CCI_REG8(0x373b), 0x02}, |
250 | {CCI_REG8(0x373c), 0x41}, |
251 | {CCI_REG8(0x373f), 0x02}, |
252 | {CCI_REG8(0x3740), 0x42}, |
253 | {CCI_REG8(0x3741), 0x02}, |
254 | {CCI_REG8(0x3742), 0x18}, |
255 | {CCI_REG8(0x3743), 0x01}, |
256 | {CCI_REG8(0x3744), 0x02}, |
257 | {CCI_REG8(0x3747), 0x10}, |
258 | {CCI_REG8(0x374c), 0x04}, |
259 | {CCI_REG8(0x3751), 0xf0}, |
260 | {CCI_REG8(0x3752), 0x00}, |
261 | {CCI_REG8(0x3753), 0x00}, |
262 | {CCI_REG8(0x3754), 0xc0}, |
263 | {CCI_REG8(0x3755), 0x00}, |
264 | {CCI_REG8(0x3756), 0x1a}, |
265 | {CCI_REG8(0x3758), 0x00}, |
266 | {CCI_REG8(0x3759), 0x0f}, |
267 | {CCI_REG8(0x376b), 0x44}, |
268 | {CCI_REG8(0x375c), 0x04}, |
269 | {CCI_REG8(0x3774), 0x10}, |
270 | {CCI_REG8(0x3776), 0x00}, |
271 | {CCI_REG8(0x377f), 0x08}, |
272 | {CCI_REG8(0x3780), 0x22}, |
273 | {CCI_REG8(0x3781), 0x0c}, |
274 | {CCI_REG8(0x3784), 0x2c}, |
275 | {CCI_REG8(0x3785), 0x1e}, |
276 | {CCI_REG8(0x378f), 0xf5}, |
277 | {CCI_REG8(0x3791), 0xb0}, |
278 | {CCI_REG8(0x3795), 0x00}, |
279 | {CCI_REG8(0x3796), 0x64}, |
280 | {CCI_REG8(0x3797), 0x11}, |
281 | {CCI_REG8(0x3798), 0x30}, |
282 | {CCI_REG8(0x3799), 0x41}, |
283 | {CCI_REG8(0x379a), 0x07}, |
284 | {CCI_REG8(0x379b), 0xb0}, |
285 | {CCI_REG8(0x379c), 0x0c}, |
286 | {CCI_REG8(0x3a04), 0x06}, |
287 | {CCI_REG8(0x3a05), 0x14}, |
288 | {CCI_REG8(0x3e07), 0x20}, |
289 | {CCI_REG8(0x4000), 0x08}, |
290 | {CCI_REG8(0x4001), 0x04}, |
291 | {CCI_REG8(0x4004), 0x08}, |
292 | {CCI_REG8(0x4006), 0x20}, |
293 | {CCI_REG8(0x4008), 0x24}, |
294 | {CCI_REG8(0x4009), 0x10}, |
295 | {CCI_REG8(0x4058), 0x00}, |
296 | {CCI_REG8(0x4101), 0xb2}, |
297 | {CCI_REG8(0x4307), 0x31}, |
298 | {CCI_REG8(0x4511), 0x05}, |
299 | {CCI_REG8(0x4512), 0x01}, |
300 | {CCI_REG8(0x481f), 0x30}, |
301 | {CCI_REG8(0x4826), 0x2c}, |
302 | {CCI_REG8(0x4d02), 0xfd}, |
303 | {CCI_REG8(0x4d03), 0xf5}, |
304 | {CCI_REG8(0x4d04), 0x0c}, |
305 | {CCI_REG8(0x4d05), 0xcc}, |
306 | {CCI_REG8(0x4837), 0x0a}, |
307 | {CCI_REG8(0x5003), 0x20}, |
308 | {CCI_REG8(0x5013), 0x00}, |
309 | {CCI_REG8(0x5842), 0x01}, |
310 | {CCI_REG8(0x5843), 0x2b}, |
311 | {CCI_REG8(0x5844), 0x01}, |
312 | {CCI_REG8(0x5845), 0x92}, |
313 | {CCI_REG8(0x5846), 0x01}, |
314 | {CCI_REG8(0x5847), 0x8f}, |
315 | {CCI_REG8(0x5848), 0x01}, |
316 | {CCI_REG8(0x5849), 0x0c}, |
317 | {CCI_REG8(0x5e10), 0x0c}, |
318 | {CCI_REG8(0x3820), 0x00}, |
319 | {CCI_REG8(0x3821), 0x1e}, |
320 | {CCI_REG8(0x5041), 0x14} |
321 | }; |
322 | |
323 | static const struct v4l2_rect ov5693_default_crop = { |
324 | .left = OV5693_ACTIVE_START_LEFT, |
325 | .top = OV5693_ACTIVE_START_TOP, |
326 | .width = OV5693_ACTIVE_WIDTH, |
327 | .height = OV5693_ACTIVE_HEIGHT, |
328 | }; |
329 | |
330 | static const struct v4l2_mbus_framefmt ov5693_default_fmt = { |
331 | .width = OV5693_ACTIVE_WIDTH, |
332 | .height = OV5693_ACTIVE_HEIGHT, |
333 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
334 | }; |
335 | |
336 | static const s64 [] = { |
337 | OV5693_LINK_FREQ_419_2MHZ |
338 | }; |
339 | |
340 | static const char * const [] = { |
341 | "Disabled" , |
342 | "Random Data" , |
343 | "Colour Bars" , |
344 | "Colour Bars with Rolling Bar" |
345 | }; |
346 | |
347 | static const u8 ov5693_test_pattern_bits[] = { |
348 | 0, |
349 | OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_RANDOM, |
350 | OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS, |
351 | OV5693_TEST_PATTERN_ENABLE | OV5693_TEST_PATTERN_BARS | |
352 | OV5693_TEST_PATTERN_ROLLING, |
353 | }; |
354 | |
355 | /* V4L2 Controls Functions */ |
356 | |
357 | static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, |
358 | bool enable) |
359 | { |
360 | u8 bits = OV5693_FORMAT1_FLIP_VERT_ISP_EN | |
361 | OV5693_FORMAT1_FLIP_VERT_SENSOR_EN; |
362 | int ret; |
363 | |
364 | ret = cci_update_bits(map: ov5693->regmap, OV5693_FORMAT1_REG, mask: bits, |
365 | val: enable ? bits : 0, NULL); |
366 | if (ret) |
367 | return ret; |
368 | |
369 | return 0; |
370 | } |
371 | |
372 | static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, |
373 | bool enable) |
374 | { |
375 | u8 bits = OV5693_FORMAT2_FLIP_HORZ_ISP_EN | |
376 | OV5693_FORMAT2_FLIP_HORZ_SENSOR_EN; |
377 | int ret; |
378 | |
379 | ret = cci_update_bits(map: ov5693->regmap, OV5693_FORMAT2_REG, mask: bits, |
380 | val: enable ? bits : 0, NULL); |
381 | if (ret) |
382 | return ret; |
383 | |
384 | return 0; |
385 | } |
386 | |
387 | static int ov5693_get_exposure(struct ov5693_device *ov5693, s32 *value) |
388 | { |
389 | u64 exposure; |
390 | int ret; |
391 | |
392 | ret = cci_read(map: ov5693->regmap, OV5693_EXPOSURE_CTRL_REG, val: &exposure, |
393 | NULL); |
394 | if (ret) |
395 | return ret; |
396 | |
397 | /* The lowest 4 bits are unsupported fractional bits */ |
398 | *value = exposure >> 4; |
399 | |
400 | return 0; |
401 | } |
402 | |
403 | static int ov5693_exposure_configure(struct ov5693_device *ov5693, |
404 | u32 exposure) |
405 | { |
406 | int ret = 0; |
407 | |
408 | exposure = (exposure << 4) & OV5693_EXPOSURE_CTRL_MASK; |
409 | |
410 | cci_write(map: ov5693->regmap, OV5693_EXPOSURE_CTRL_REG, val: exposure, err: &ret); |
411 | |
412 | return ret; |
413 | } |
414 | |
415 | static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain) |
416 | { |
417 | u64 value; |
418 | int ret; |
419 | |
420 | ret = cci_read(map: ov5693->regmap, OV5693_GAIN_CTRL_REG, val: &value, NULL); |
421 | if (ret) |
422 | return ret; |
423 | |
424 | /* As with exposure, the lowest 4 bits are fractional bits. */ |
425 | *gain = value >> 4; |
426 | |
427 | return ret; |
428 | } |
429 | |
430 | static int ov5693_digital_gain_configure(struct ov5693_device *ov5693, |
431 | u32 gain) |
432 | { |
433 | int ret = 0; |
434 | |
435 | gain &= OV5693_MWB_GAIN_MASK; |
436 | |
437 | cci_write(map: ov5693->regmap, OV5693_MWB_RED_GAIN_REG, val: gain, err: &ret); |
438 | cci_write(map: ov5693->regmap, OV5693_MWB_GREEN_GAIN_REG, val: gain, err: &ret); |
439 | cci_write(map: ov5693->regmap, OV5693_MWB_BLUE_GAIN_REG, val: gain, err: &ret); |
440 | |
441 | return ret; |
442 | } |
443 | |
444 | static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain) |
445 | { |
446 | int ret = 0; |
447 | |
448 | gain = (gain << 4) & OV5693_GAIN_CTRL_MASK; |
449 | |
450 | cci_write(map: ov5693->regmap, OV5693_GAIN_CTRL_REG, val: gain, err: &ret); |
451 | |
452 | return ret; |
453 | } |
454 | |
455 | static int ov5693_vts_configure(struct ov5693_device *ov5693, u32 vblank) |
456 | { |
457 | u16 vts = ov5693->mode.format.height + vblank; |
458 | int ret = 0; |
459 | |
460 | cci_write(map: ov5693->regmap, OV5693_TIMING_VTS_REG, val: vts, err: &ret); |
461 | |
462 | return ret; |
463 | } |
464 | |
465 | static int ov5693_test_pattern_configure(struct ov5693_device *ov5693, u32 idx) |
466 | { |
467 | int ret = 0; |
468 | |
469 | cci_write(map: ov5693->regmap, OV5693_TEST_PATTERN_REG, |
470 | val: ov5693_test_pattern_bits[idx], err: &ret); |
471 | |
472 | return ret; |
473 | } |
474 | |
475 | static int ov5693_s_ctrl(struct v4l2_ctrl *ctrl) |
476 | { |
477 | struct ov5693_device *ov5693 = |
478 | container_of(ctrl->handler, struct ov5693_device, ctrls.handler); |
479 | int ret = 0; |
480 | |
481 | /* If VBLANK is altered we need to update exposure to compensate */ |
482 | if (ctrl->id == V4L2_CID_VBLANK) { |
483 | int exposure_max; |
484 | |
485 | exposure_max = ov5693->mode.format.height + ctrl->val - |
486 | OV5693_INTEGRATION_TIME_MARGIN; |
487 | __v4l2_ctrl_modify_range(ctrl: ov5693->ctrls.exposure, |
488 | min: ov5693->ctrls.exposure->minimum, |
489 | max: exposure_max, |
490 | step: ov5693->ctrls.exposure->step, |
491 | min(ov5693->ctrls.exposure->val, |
492 | exposure_max)); |
493 | } |
494 | |
495 | /* Only apply changes to the controls if the device is powered up */ |
496 | if (!pm_runtime_get_if_in_use(dev: ov5693->dev)) |
497 | return 0; |
498 | |
499 | switch (ctrl->id) { |
500 | case V4L2_CID_EXPOSURE: |
501 | ret = ov5693_exposure_configure(ov5693, exposure: ctrl->val); |
502 | break; |
503 | case V4L2_CID_ANALOGUE_GAIN: |
504 | ret = ov5693_analog_gain_configure(ov5693, gain: ctrl->val); |
505 | break; |
506 | case V4L2_CID_DIGITAL_GAIN: |
507 | ret = ov5693_digital_gain_configure(ov5693, gain: ctrl->val); |
508 | break; |
509 | case V4L2_CID_HFLIP: |
510 | ret = ov5693_flip_horz_configure(ov5693, enable: !!ctrl->val); |
511 | break; |
512 | case V4L2_CID_VFLIP: |
513 | ret = ov5693_flip_vert_configure(ov5693, enable: !!ctrl->val); |
514 | break; |
515 | case V4L2_CID_VBLANK: |
516 | ret = ov5693_vts_configure(ov5693, vblank: ctrl->val); |
517 | break; |
518 | case V4L2_CID_TEST_PATTERN: |
519 | ret = ov5693_test_pattern_configure(ov5693, idx: ctrl->val); |
520 | break; |
521 | default: |
522 | ret = -EINVAL; |
523 | } |
524 | |
525 | pm_runtime_put(dev: ov5693->dev); |
526 | |
527 | return ret; |
528 | } |
529 | |
530 | static int ov5693_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
531 | { |
532 | struct ov5693_device *ov5693 = container_of(ctrl->handler, |
533 | struct ov5693_device, |
534 | ctrls.handler); |
535 | |
536 | switch (ctrl->id) { |
537 | case V4L2_CID_EXPOSURE_ABSOLUTE: |
538 | return ov5693_get_exposure(ov5693, value: &ctrl->val); |
539 | case V4L2_CID_AUTOGAIN: |
540 | return ov5693_get_gain(ov5693, gain: &ctrl->val); |
541 | default: |
542 | return -EINVAL; |
543 | } |
544 | } |
545 | |
546 | static const struct v4l2_ctrl_ops ov5693_ctrl_ops = { |
547 | .s_ctrl = ov5693_s_ctrl, |
548 | .g_volatile_ctrl = ov5693_g_volatile_ctrl |
549 | }; |
550 | |
551 | /* System Control Functions */ |
552 | |
553 | static int ov5693_mode_configure(struct ov5693_device *ov5693) |
554 | { |
555 | const struct ov5693_mode *mode = &ov5693->mode; |
556 | int ret = 0; |
557 | |
558 | /* Crop Start X */ |
559 | cci_write(map: ov5693->regmap, OV5693_CROP_START_X_REG, val: mode->crop.left, |
560 | err: &ret); |
561 | |
562 | /* Offset X */ |
563 | cci_write(map: ov5693->regmap, OV5693_OFFSET_START_X_REG, val: 0, err: &ret); |
564 | |
565 | /* Output Size X */ |
566 | cci_write(map: ov5693->regmap, OV5693_OUTPUT_SIZE_X_REG, val: mode->format.width, |
567 | err: &ret); |
568 | |
569 | /* Crop End X */ |
570 | cci_write(map: ov5693->regmap, OV5693_CROP_END_X_REG, |
571 | val: mode->crop.left + mode->crop.width, err: &ret); |
572 | |
573 | /* Horizontal Total Size */ |
574 | cci_write(map: ov5693->regmap, OV5693_TIMING_HTS_REG, OV5693_FIXED_PPL, |
575 | err: &ret); |
576 | |
577 | /* Crop Start Y */ |
578 | cci_write(map: ov5693->regmap, OV5693_CROP_START_Y_REG, val: mode->crop.top, |
579 | err: &ret); |
580 | |
581 | /* Offset Y */ |
582 | cci_write(map: ov5693->regmap, OV5693_OFFSET_START_Y_REG, val: 0, err: &ret); |
583 | |
584 | /* Output Size Y */ |
585 | cci_write(map: ov5693->regmap, OV5693_OUTPUT_SIZE_Y_REG, val: mode->format.height, |
586 | err: &ret); |
587 | |
588 | /* Crop End Y */ |
589 | cci_write(map: ov5693->regmap, OV5693_CROP_END_Y_REG, |
590 | val: mode->crop.top + mode->crop.height, err: &ret); |
591 | |
592 | /* Subsample X increase */ |
593 | cci_write(map: ov5693->regmap, OV5693_SUB_INC_X_REG, |
594 | val: ((mode->inc_x_odd << 4) & 0xf0) | 0x01, err: &ret); |
595 | /* Subsample Y increase */ |
596 | cci_write(map: ov5693->regmap, OV5693_SUB_INC_Y_REG, |
597 | val: ((mode->inc_y_odd << 4) & 0xf0) | 0x01, err: &ret); |
598 | |
599 | /* Binning */ |
600 | cci_update_bits(map: ov5693->regmap, OV5693_FORMAT1_REG, |
601 | OV5693_FORMAT1_VBIN_EN, |
602 | val: mode->binning_y ? OV5693_FORMAT1_VBIN_EN : 0, err: &ret); |
603 | |
604 | cci_update_bits(map: ov5693->regmap, OV5693_FORMAT2_REG, |
605 | OV5693_FORMAT2_HBIN_EN, |
606 | val: mode->binning_x ? OV5693_FORMAT2_HBIN_EN : 0, err: &ret); |
607 | |
608 | return ret; |
609 | } |
610 | |
611 | static int ov5693_enable_streaming(struct ov5693_device *ov5693, bool enable) |
612 | { |
613 | int ret = 0; |
614 | |
615 | cci_write(map: ov5693->regmap, OV5693_SW_STREAM_REG, |
616 | val: enable ? OV5693_START_STREAMING : OV5693_STOP_STREAMING, |
617 | err: &ret); |
618 | |
619 | return ret; |
620 | } |
621 | |
622 | static int ov5693_sw_reset(struct ov5693_device *ov5693) |
623 | { |
624 | int ret = 0; |
625 | |
626 | cci_write(map: ov5693->regmap, OV5693_SW_RESET_REG, OV5693_SW_RESET, err: &ret); |
627 | |
628 | return ret; |
629 | } |
630 | |
631 | static int ov5693_sensor_init(struct ov5693_device *ov5693) |
632 | { |
633 | int ret; |
634 | |
635 | ret = ov5693_sw_reset(ov5693); |
636 | if (ret) |
637 | return dev_err_probe(dev: ov5693->dev, err: ret, |
638 | fmt: "software reset error\n" ); |
639 | |
640 | ret = cci_multi_reg_write(map: ov5693->regmap, regs: ov5693_global_regs, |
641 | ARRAY_SIZE(ov5693_global_regs), NULL); |
642 | if (ret) |
643 | return dev_err_probe(dev: ov5693->dev, err: ret, |
644 | fmt: "global settings error\n" ); |
645 | |
646 | ret = ov5693_mode_configure(ov5693); |
647 | if (ret) |
648 | return dev_err_probe(dev: ov5693->dev, err: ret, |
649 | fmt: "mode configure error\n" ); |
650 | |
651 | ret = ov5693_enable_streaming(ov5693, enable: false); |
652 | if (ret) |
653 | dev_err(ov5693->dev, "stop streaming error\n" ); |
654 | |
655 | return ret; |
656 | } |
657 | |
658 | static void ov5693_sensor_powerdown(struct ov5693_device *ov5693) |
659 | { |
660 | gpiod_set_value_cansleep(desc: ov5693->privacy_led, value: 0); |
661 | gpiod_set_value_cansleep(desc: ov5693->reset, value: 1); |
662 | gpiod_set_value_cansleep(desc: ov5693->powerdown, value: 1); |
663 | |
664 | regulator_bulk_disable(OV5693_NUM_SUPPLIES, consumers: ov5693->supplies); |
665 | |
666 | clk_disable_unprepare(clk: ov5693->xvclk); |
667 | } |
668 | |
669 | static int ov5693_sensor_powerup(struct ov5693_device *ov5693) |
670 | { |
671 | int ret; |
672 | |
673 | gpiod_set_value_cansleep(desc: ov5693->reset, value: 1); |
674 | gpiod_set_value_cansleep(desc: ov5693->powerdown, value: 1); |
675 | |
676 | ret = clk_prepare_enable(clk: ov5693->xvclk); |
677 | if (ret) { |
678 | dev_err(ov5693->dev, "Failed to enable clk\n" ); |
679 | goto fail_power; |
680 | } |
681 | |
682 | ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, consumers: ov5693->supplies); |
683 | if (ret) { |
684 | dev_err(ov5693->dev, "Failed to enable regulators\n" ); |
685 | goto fail_power; |
686 | } |
687 | |
688 | gpiod_set_value_cansleep(desc: ov5693->powerdown, value: 0); |
689 | gpiod_set_value_cansleep(desc: ov5693->reset, value: 0); |
690 | gpiod_set_value_cansleep(desc: ov5693->privacy_led, value: 1); |
691 | |
692 | usleep_range(min: 5000, max: 7500); |
693 | |
694 | return 0; |
695 | |
696 | fail_power: |
697 | ov5693_sensor_powerdown(ov5693); |
698 | return ret; |
699 | } |
700 | |
701 | static int __maybe_unused ov5693_sensor_suspend(struct device *dev) |
702 | { |
703 | struct v4l2_subdev *sd = dev_get_drvdata(dev); |
704 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
705 | |
706 | ov5693_sensor_powerdown(ov5693); |
707 | |
708 | return 0; |
709 | } |
710 | |
711 | static int __maybe_unused ov5693_sensor_resume(struct device *dev) |
712 | { |
713 | struct v4l2_subdev *sd = dev_get_drvdata(dev); |
714 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
715 | int ret; |
716 | |
717 | mutex_lock(&ov5693->lock); |
718 | |
719 | ret = ov5693_sensor_powerup(ov5693); |
720 | if (ret) |
721 | goto out_unlock; |
722 | |
723 | ret = ov5693_sensor_init(ov5693); |
724 | if (ret) { |
725 | dev_err(dev, "ov5693 sensor init failure\n" ); |
726 | goto err_power; |
727 | } |
728 | |
729 | goto out_unlock; |
730 | |
731 | err_power: |
732 | ov5693_sensor_powerdown(ov5693); |
733 | out_unlock: |
734 | mutex_unlock(lock: &ov5693->lock); |
735 | return ret; |
736 | } |
737 | |
738 | static int ov5693_detect(struct ov5693_device *ov5693) |
739 | { |
740 | int ret; |
741 | u64 id; |
742 | |
743 | ret = cci_read(map: ov5693->regmap, OV5693_REG_CHIP_ID, val: &id, NULL); |
744 | if (ret) |
745 | return ret; |
746 | |
747 | if (id != OV5693_CHIP_ID) |
748 | return dev_err_probe(dev: ov5693->dev, err: -ENODEV, |
749 | fmt: "sensor ID mismatch. Got 0x%04llx\n" , id); |
750 | |
751 | return 0; |
752 | } |
753 | |
754 | /* V4L2 Framework callbacks */ |
755 | |
756 | static unsigned int __ov5693_calc_vts(u32 height) |
757 | { |
758 | /* |
759 | * We need to set a sensible default VTS for whatever format height we |
760 | * happen to be given from set_fmt(). This function just targets |
761 | * an even multiple of 30fps. |
762 | */ |
763 | |
764 | unsigned int tgt_fps; |
765 | |
766 | tgt_fps = rounddown(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / height, 30); |
767 | |
768 | return ALIGN_DOWN(OV5693_PIXEL_RATE / OV5693_FIXED_PPL / tgt_fps, 2); |
769 | } |
770 | |
771 | static struct v4l2_mbus_framefmt * |
772 | __ov5693_get_pad_format(struct ov5693_device *ov5693, |
773 | struct v4l2_subdev_state *state, |
774 | unsigned int pad, enum v4l2_subdev_format_whence which) |
775 | { |
776 | switch (which) { |
777 | case V4L2_SUBDEV_FORMAT_TRY: |
778 | return v4l2_subdev_state_get_format(state, pad); |
779 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
780 | return &ov5693->mode.format; |
781 | default: |
782 | return NULL; |
783 | } |
784 | } |
785 | |
786 | static struct v4l2_rect * |
787 | __ov5693_get_pad_crop(struct ov5693_device *ov5693, |
788 | struct v4l2_subdev_state *state, |
789 | unsigned int pad, enum v4l2_subdev_format_whence which) |
790 | { |
791 | switch (which) { |
792 | case V4L2_SUBDEV_FORMAT_TRY: |
793 | return v4l2_subdev_state_get_crop(state, pad); |
794 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
795 | return &ov5693->mode.crop; |
796 | } |
797 | |
798 | return NULL; |
799 | } |
800 | |
801 | static int ov5693_get_fmt(struct v4l2_subdev *sd, |
802 | struct v4l2_subdev_state *state, |
803 | struct v4l2_subdev_format *format) |
804 | { |
805 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
806 | |
807 | format->format = ov5693->mode.format; |
808 | |
809 | return 0; |
810 | } |
811 | |
812 | static int ov5693_set_fmt(struct v4l2_subdev *sd, |
813 | struct v4l2_subdev_state *state, |
814 | struct v4l2_subdev_format *format) |
815 | { |
816 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
817 | const struct v4l2_rect *crop; |
818 | struct v4l2_mbus_framefmt *fmt; |
819 | unsigned int hratio, vratio; |
820 | unsigned int width, height; |
821 | unsigned int hblank; |
822 | int exposure_max; |
823 | |
824 | crop = __ov5693_get_pad_crop(ov5693, state, pad: format->pad, which: format->which); |
825 | |
826 | /* |
827 | * Align to two to simplify the binning calculations below, and clamp |
828 | * the requested format at the crop rectangle |
829 | */ |
830 | width = clamp_t(unsigned int, ALIGN(format->format.width, 2), |
831 | OV5693_MIN_CROP_WIDTH, crop->width); |
832 | height = clamp_t(unsigned int, ALIGN(format->format.height, 2), |
833 | OV5693_MIN_CROP_HEIGHT, crop->height); |
834 | |
835 | /* |
836 | * We can only support setting either the dimensions of the crop rect |
837 | * or those dimensions binned (separately) by a factor of two. |
838 | */ |
839 | hratio = clamp_t(unsigned int, |
840 | DIV_ROUND_CLOSEST(crop->width, width), 1, 2); |
841 | vratio = clamp_t(unsigned int, |
842 | DIV_ROUND_CLOSEST(crop->height, height), 1, 2); |
843 | |
844 | fmt = __ov5693_get_pad_format(ov5693, state, pad: format->pad, |
845 | which: format->which); |
846 | |
847 | fmt->width = crop->width / hratio; |
848 | fmt->height = crop->height / vratio; |
849 | fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; |
850 | |
851 | format->format = *fmt; |
852 | |
853 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) |
854 | return 0; |
855 | |
856 | mutex_lock(&ov5693->lock); |
857 | |
858 | ov5693->mode.binning_x = hratio > 1; |
859 | ov5693->mode.inc_x_odd = hratio > 1 ? 3 : 1; |
860 | ov5693->mode.binning_y = vratio > 1; |
861 | ov5693->mode.inc_y_odd = vratio > 1 ? 3 : 1; |
862 | |
863 | ov5693->mode.vts = __ov5693_calc_vts(height: fmt->height); |
864 | |
865 | __v4l2_ctrl_modify_range(ctrl: ov5693->ctrls.vblank, |
866 | OV5693_TIMING_MIN_VTS, |
867 | OV5693_TIMING_MAX_VTS - fmt->height, |
868 | step: 1, def: ov5693->mode.vts - fmt->height); |
869 | __v4l2_ctrl_s_ctrl(ctrl: ov5693->ctrls.vblank, |
870 | val: ov5693->mode.vts - fmt->height); |
871 | |
872 | hblank = OV5693_FIXED_PPL - fmt->width; |
873 | __v4l2_ctrl_modify_range(ctrl: ov5693->ctrls.hblank, min: hblank, max: hblank, step: 1, |
874 | def: hblank); |
875 | |
876 | exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN; |
877 | __v4l2_ctrl_modify_range(ctrl: ov5693->ctrls.exposure, |
878 | min: ov5693->ctrls.exposure->minimum, max: exposure_max, |
879 | step: ov5693->ctrls.exposure->step, |
880 | min(ov5693->ctrls.exposure->val, |
881 | exposure_max)); |
882 | |
883 | mutex_unlock(lock: &ov5693->lock); |
884 | return 0; |
885 | } |
886 | |
887 | static int ov5693_get_selection(struct v4l2_subdev *sd, |
888 | struct v4l2_subdev_state *state, |
889 | struct v4l2_subdev_selection *sel) |
890 | { |
891 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
892 | |
893 | switch (sel->target) { |
894 | case V4L2_SEL_TGT_CROP: |
895 | mutex_lock(&ov5693->lock); |
896 | sel->r = *__ov5693_get_pad_crop(ov5693, state, pad: sel->pad, |
897 | which: sel->which); |
898 | mutex_unlock(lock: &ov5693->lock); |
899 | break; |
900 | case V4L2_SEL_TGT_NATIVE_SIZE: |
901 | sel->r.top = 0; |
902 | sel->r.left = 0; |
903 | sel->r.width = OV5693_NATIVE_WIDTH; |
904 | sel->r.height = OV5693_NATIVE_HEIGHT; |
905 | break; |
906 | case V4L2_SEL_TGT_CROP_BOUNDS: |
907 | case V4L2_SEL_TGT_CROP_DEFAULT: |
908 | sel->r.top = OV5693_ACTIVE_START_TOP; |
909 | sel->r.left = OV5693_ACTIVE_START_LEFT; |
910 | sel->r.width = OV5693_ACTIVE_WIDTH; |
911 | sel->r.height = OV5693_ACTIVE_HEIGHT; |
912 | break; |
913 | default: |
914 | return -EINVAL; |
915 | } |
916 | |
917 | return 0; |
918 | } |
919 | |
920 | static int ov5693_set_selection(struct v4l2_subdev *sd, |
921 | struct v4l2_subdev_state *state, |
922 | struct v4l2_subdev_selection *sel) |
923 | { |
924 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
925 | struct v4l2_mbus_framefmt *format; |
926 | struct v4l2_rect *__crop; |
927 | struct v4l2_rect rect; |
928 | |
929 | if (sel->target != V4L2_SEL_TGT_CROP) |
930 | return -EINVAL; |
931 | |
932 | /* |
933 | * Clamp the boundaries of the crop rectangle to the size of the sensor |
934 | * pixel array. Align to multiples of 2 to ensure Bayer pattern isn't |
935 | * disrupted. |
936 | */ |
937 | rect.left = clamp(ALIGN(sel->r.left, 2), OV5693_NATIVE_START_LEFT, |
938 | OV5693_NATIVE_WIDTH); |
939 | rect.top = clamp(ALIGN(sel->r.top, 2), OV5693_NATIVE_START_TOP, |
940 | OV5693_NATIVE_HEIGHT); |
941 | rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), |
942 | OV5693_MIN_CROP_WIDTH, OV5693_NATIVE_WIDTH); |
943 | rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), |
944 | OV5693_MIN_CROP_HEIGHT, OV5693_NATIVE_HEIGHT); |
945 | |
946 | /* Make sure the crop rectangle isn't outside the bounds of the array */ |
947 | rect.width = min_t(unsigned int, rect.width, |
948 | OV5693_NATIVE_WIDTH - rect.left); |
949 | rect.height = min_t(unsigned int, rect.height, |
950 | OV5693_NATIVE_HEIGHT - rect.top); |
951 | |
952 | __crop = __ov5693_get_pad_crop(ov5693, state, pad: sel->pad, which: sel->which); |
953 | |
954 | if (rect.width != __crop->width || rect.height != __crop->height) { |
955 | /* |
956 | * Reset the output image size if the crop rectangle size has |
957 | * been modified. |
958 | */ |
959 | format = __ov5693_get_pad_format(ov5693, state, pad: sel->pad, |
960 | which: sel->which); |
961 | format->width = rect.width; |
962 | format->height = rect.height; |
963 | } |
964 | |
965 | *__crop = rect; |
966 | sel->r = rect; |
967 | |
968 | return 0; |
969 | } |
970 | |
971 | static int ov5693_s_stream(struct v4l2_subdev *sd, int enable) |
972 | { |
973 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
974 | int ret; |
975 | |
976 | if (enable) { |
977 | ret = pm_runtime_resume_and_get(dev: ov5693->dev); |
978 | if (ret) |
979 | return ret; |
980 | |
981 | mutex_lock(&ov5693->lock); |
982 | ret = __v4l2_ctrl_handler_setup(hdl: &ov5693->ctrls.handler); |
983 | if (ret) { |
984 | mutex_unlock(lock: &ov5693->lock); |
985 | goto err_power_down; |
986 | } |
987 | |
988 | ret = ov5693_enable_streaming(ov5693, enable: true); |
989 | mutex_unlock(lock: &ov5693->lock); |
990 | } else { |
991 | mutex_lock(&ov5693->lock); |
992 | ret = ov5693_enable_streaming(ov5693, enable: false); |
993 | mutex_unlock(lock: &ov5693->lock); |
994 | } |
995 | if (ret) |
996 | goto err_power_down; |
997 | |
998 | if (!enable) |
999 | pm_runtime_put(dev: ov5693->dev); |
1000 | |
1001 | return 0; |
1002 | err_power_down: |
1003 | pm_runtime_put_noidle(dev: ov5693->dev); |
1004 | return ret; |
1005 | } |
1006 | |
1007 | static int ov5693_get_frame_interval(struct v4l2_subdev *sd, |
1008 | struct v4l2_subdev_state *sd_state, |
1009 | struct v4l2_subdev_frame_interval *interval) |
1010 | { |
1011 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
1012 | unsigned int framesize = OV5693_FIXED_PPL * (ov5693->mode.format.height + |
1013 | ov5693->ctrls.vblank->val); |
1014 | unsigned int fps = DIV_ROUND_CLOSEST(OV5693_PIXEL_RATE, framesize); |
1015 | |
1016 | /* |
1017 | * FIXME: Implement support for V4L2_SUBDEV_FORMAT_TRY, using the V4L2 |
1018 | * subdev active state API. |
1019 | */ |
1020 | if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) |
1021 | return -EINVAL; |
1022 | |
1023 | interval->interval.numerator = 1; |
1024 | interval->interval.denominator = fps; |
1025 | |
1026 | return 0; |
1027 | } |
1028 | |
1029 | static int ov5693_enum_mbus_code(struct v4l2_subdev *sd, |
1030 | struct v4l2_subdev_state *state, |
1031 | struct v4l2_subdev_mbus_code_enum *code) |
1032 | { |
1033 | /* Only a single mbus format is supported */ |
1034 | if (code->index > 0) |
1035 | return -EINVAL; |
1036 | |
1037 | code->code = MEDIA_BUS_FMT_SBGGR10_1X10; |
1038 | return 0; |
1039 | } |
1040 | |
1041 | static int ov5693_enum_frame_size(struct v4l2_subdev *sd, |
1042 | struct v4l2_subdev_state *state, |
1043 | struct v4l2_subdev_frame_size_enum *fse) |
1044 | { |
1045 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
1046 | struct v4l2_rect *__crop; |
1047 | |
1048 | if (fse->index > 1 || fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) |
1049 | return -EINVAL; |
1050 | |
1051 | __crop = __ov5693_get_pad_crop(ov5693, state, pad: fse->pad, which: fse->which); |
1052 | if (!__crop) |
1053 | return -EINVAL; |
1054 | |
1055 | fse->min_width = __crop->width / (fse->index + 1); |
1056 | fse->min_height = __crop->height / (fse->index + 1); |
1057 | fse->max_width = fse->min_width; |
1058 | fse->max_height = fse->min_height; |
1059 | |
1060 | return 0; |
1061 | } |
1062 | |
1063 | static const struct v4l2_subdev_video_ops ov5693_video_ops = { |
1064 | .s_stream = ov5693_s_stream, |
1065 | }; |
1066 | |
1067 | static const struct v4l2_subdev_pad_ops ov5693_pad_ops = { |
1068 | .enum_mbus_code = ov5693_enum_mbus_code, |
1069 | .enum_frame_size = ov5693_enum_frame_size, |
1070 | .get_fmt = ov5693_get_fmt, |
1071 | .set_fmt = ov5693_set_fmt, |
1072 | .get_selection = ov5693_get_selection, |
1073 | .set_selection = ov5693_set_selection, |
1074 | .get_frame_interval = ov5693_get_frame_interval, |
1075 | }; |
1076 | |
1077 | static const struct v4l2_subdev_ops ov5693_ops = { |
1078 | .video = &ov5693_video_ops, |
1079 | .pad = &ov5693_pad_ops, |
1080 | }; |
1081 | |
1082 | /* Sensor and Driver Configuration Functions */ |
1083 | |
1084 | static int ov5693_init_controls(struct ov5693_device *ov5693) |
1085 | { |
1086 | const struct v4l2_ctrl_ops *ops = &ov5693_ctrl_ops; |
1087 | struct ov5693_v4l2_ctrls *ctrls = &ov5693->ctrls; |
1088 | struct v4l2_fwnode_device_properties props; |
1089 | int vblank_max, vblank_def; |
1090 | int exposure_max; |
1091 | int hblank; |
1092 | int ret; |
1093 | |
1094 | ret = v4l2_ctrl_handler_init(&ctrls->handler, 12); |
1095 | if (ret) |
1096 | return ret; |
1097 | |
1098 | /* link freq */ |
1099 | ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl: &ctrls->handler, |
1100 | NULL, V4L2_CID_LINK_FREQ, |
1101 | max: 0, def: 0, qmenu_int: link_freq_menu_items); |
1102 | if (ctrls->link_freq) |
1103 | ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1104 | |
1105 | /* pixel rate */ |
1106 | ctrls->pixel_rate = v4l2_ctrl_new_std(hdl: &ctrls->handler, NULL, |
1107 | V4L2_CID_PIXEL_RATE, min: 0, |
1108 | OV5693_PIXEL_RATE, step: 1, |
1109 | OV5693_PIXEL_RATE); |
1110 | |
1111 | /* Exposure */ |
1112 | exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN; |
1113 | ctrls->exposure = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1114 | V4L2_CID_EXPOSURE, |
1115 | OV5693_EXPOSURE_MIN, max: exposure_max, |
1116 | OV5693_EXPOSURE_STEP, def: exposure_max); |
1117 | |
1118 | /* Gain */ |
1119 | ctrls->analogue_gain = v4l2_ctrl_new_std(hdl: &ctrls->handler, |
1120 | ops, V4L2_CID_ANALOGUE_GAIN, |
1121 | OV5693_GAIN_MIN, |
1122 | OV5693_GAIN_MAX, |
1123 | OV5693_GAIN_STEP, |
1124 | OV5693_GAIN_DEF); |
1125 | |
1126 | ctrls->digital_gain = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1127 | V4L2_CID_DIGITAL_GAIN, |
1128 | OV5693_DIGITAL_GAIN_MIN, |
1129 | OV5693_DIGITAL_GAIN_MAX, |
1130 | OV5693_DIGITAL_GAIN_STEP, |
1131 | OV5693_DIGITAL_GAIN_DEF); |
1132 | |
1133 | /* Flip */ |
1134 | ctrls->hflip = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1135 | V4L2_CID_HFLIP, min: 0, max: 1, step: 1, def: 0); |
1136 | |
1137 | ctrls->vflip = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1138 | V4L2_CID_VFLIP, min: 0, max: 1, step: 1, def: 0); |
1139 | |
1140 | hblank = OV5693_FIXED_PPL - ov5693->mode.format.width; |
1141 | ctrls->hblank = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1142 | V4L2_CID_HBLANK, min: hblank, |
1143 | max: hblank, step: 1, def: hblank); |
1144 | |
1145 | if (ctrls->hblank) |
1146 | ctrls->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1147 | |
1148 | vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode.format.height; |
1149 | vblank_def = ov5693->mode.vts - ov5693->mode.format.height; |
1150 | ctrls->vblank = v4l2_ctrl_new_std(hdl: &ctrls->handler, ops, |
1151 | V4L2_CID_VBLANK, |
1152 | OV5693_TIMING_MIN_VTS, |
1153 | max: vblank_max, step: 1, def: vblank_def); |
1154 | |
1155 | ctrls->test_pattern = v4l2_ctrl_new_std_menu_items( |
1156 | hdl: &ctrls->handler, ops, |
1157 | V4L2_CID_TEST_PATTERN, |
1158 | ARRAY_SIZE(ov5693_test_pattern_menu) - 1, |
1159 | mask: 0, def: 0, qmenu: ov5693_test_pattern_menu); |
1160 | |
1161 | if (ctrls->handler.error) { |
1162 | dev_err(ov5693->dev, "Error initialising v4l2 ctrls\n" ); |
1163 | ret = ctrls->handler.error; |
1164 | goto err_free_handler; |
1165 | } |
1166 | |
1167 | /* set properties from fwnode (e.g. rotation, orientation) */ |
1168 | ret = v4l2_fwnode_device_parse(dev: ov5693->dev, props: &props); |
1169 | if (ret) |
1170 | goto err_free_handler; |
1171 | |
1172 | ret = v4l2_ctrl_new_fwnode_properties(hdl: &ctrls->handler, ctrl_ops: ops, |
1173 | p: &props); |
1174 | if (ret) |
1175 | goto err_free_handler; |
1176 | |
1177 | /* Use same lock for controls as for everything else. */ |
1178 | ctrls->handler.lock = &ov5693->lock; |
1179 | ov5693->sd.ctrl_handler = &ctrls->handler; |
1180 | |
1181 | return 0; |
1182 | |
1183 | err_free_handler: |
1184 | v4l2_ctrl_handler_free(hdl: &ctrls->handler); |
1185 | return ret; |
1186 | } |
1187 | |
1188 | static int ov5693_configure_gpios(struct ov5693_device *ov5693) |
1189 | { |
1190 | ov5693->reset = devm_gpiod_get_optional(dev: ov5693->dev, con_id: "reset" , |
1191 | flags: GPIOD_OUT_HIGH); |
1192 | if (IS_ERR(ptr: ov5693->reset)) { |
1193 | dev_err(ov5693->dev, "Error fetching reset GPIO\n" ); |
1194 | return PTR_ERR(ptr: ov5693->reset); |
1195 | } |
1196 | |
1197 | ov5693->powerdown = devm_gpiod_get_optional(dev: ov5693->dev, con_id: "powerdown" , |
1198 | flags: GPIOD_OUT_HIGH); |
1199 | if (IS_ERR(ptr: ov5693->powerdown)) { |
1200 | dev_err(ov5693->dev, "Error fetching powerdown GPIO\n" ); |
1201 | return PTR_ERR(ptr: ov5693->powerdown); |
1202 | } |
1203 | |
1204 | ov5693->privacy_led = devm_gpiod_get_optional(dev: ov5693->dev, con_id: "privacy-led" , |
1205 | flags: GPIOD_OUT_LOW); |
1206 | if (IS_ERR(ptr: ov5693->privacy_led)) { |
1207 | dev_err(ov5693->dev, "Error fetching privacy-led GPIO\n" ); |
1208 | return PTR_ERR(ptr: ov5693->privacy_led); |
1209 | } |
1210 | |
1211 | return 0; |
1212 | } |
1213 | |
1214 | static int ov5693_get_regulators(struct ov5693_device *ov5693) |
1215 | { |
1216 | unsigned int i; |
1217 | |
1218 | for (i = 0; i < OV5693_NUM_SUPPLIES; i++) |
1219 | ov5693->supplies[i].supply = ov5693_supply_names[i]; |
1220 | |
1221 | return devm_regulator_bulk_get(dev: ov5693->dev, OV5693_NUM_SUPPLIES, |
1222 | consumers: ov5693->supplies); |
1223 | } |
1224 | |
1225 | static int ov5693_check_hwcfg(struct ov5693_device *ov5693) |
1226 | { |
1227 | struct fwnode_handle *fwnode = dev_fwnode(ov5693->dev); |
1228 | struct v4l2_fwnode_endpoint bus_cfg = { |
1229 | .bus_type = V4L2_MBUS_CSI2_DPHY, |
1230 | }; |
1231 | struct fwnode_handle *endpoint; |
1232 | unsigned int i; |
1233 | int ret; |
1234 | |
1235 | endpoint = fwnode_graph_get_next_endpoint(fwnode, NULL); |
1236 | if (!endpoint) |
1237 | return -EPROBE_DEFER; /* Could be provided by cio2-bridge */ |
1238 | |
1239 | ret = v4l2_fwnode_endpoint_alloc_parse(fwnode: endpoint, vep: &bus_cfg); |
1240 | fwnode_handle_put(fwnode: endpoint); |
1241 | if (ret) |
1242 | return ret; |
1243 | |
1244 | if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) { |
1245 | dev_err(ov5693->dev, "only a 2-lane CSI2 config is supported" ); |
1246 | ret = -EINVAL; |
1247 | goto out_free_bus_cfg; |
1248 | } |
1249 | |
1250 | if (!bus_cfg.nr_of_link_frequencies) { |
1251 | dev_err(ov5693->dev, "no link frequencies defined\n" ); |
1252 | ret = -EINVAL; |
1253 | goto out_free_bus_cfg; |
1254 | } |
1255 | |
1256 | for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) |
1257 | if (bus_cfg.link_frequencies[i] == OV5693_LINK_FREQ_419_2MHZ) |
1258 | break; |
1259 | |
1260 | if (i == bus_cfg.nr_of_link_frequencies) { |
1261 | dev_err(ov5693->dev, "supported link freq %ull not found\n" , |
1262 | OV5693_LINK_FREQ_419_2MHZ); |
1263 | ret = -EINVAL; |
1264 | goto out_free_bus_cfg; |
1265 | } |
1266 | |
1267 | out_free_bus_cfg: |
1268 | v4l2_fwnode_endpoint_free(vep: &bus_cfg); |
1269 | |
1270 | return ret; |
1271 | } |
1272 | |
1273 | static int ov5693_probe(struct i2c_client *client) |
1274 | { |
1275 | struct ov5693_device *ov5693; |
1276 | u32 xvclk_rate; |
1277 | int ret = 0; |
1278 | |
1279 | ov5693 = devm_kzalloc(dev: &client->dev, size: sizeof(*ov5693), GFP_KERNEL); |
1280 | if (!ov5693) |
1281 | return -ENOMEM; |
1282 | |
1283 | ov5693->dev = &client->dev; |
1284 | |
1285 | ov5693->regmap = devm_cci_regmap_init_i2c(client, reg_addr_bits: 16); |
1286 | if (IS_ERR(ptr: ov5693->regmap)) |
1287 | return PTR_ERR(ptr: ov5693->regmap); |
1288 | |
1289 | ret = ov5693_check_hwcfg(ov5693); |
1290 | if (ret) |
1291 | return ret; |
1292 | |
1293 | mutex_init(&ov5693->lock); |
1294 | |
1295 | v4l2_i2c_subdev_init(sd: &ov5693->sd, client, ops: &ov5693_ops); |
1296 | |
1297 | ov5693->xvclk = devm_clk_get_optional(dev: &client->dev, id: "xvclk" ); |
1298 | if (IS_ERR(ptr: ov5693->xvclk)) |
1299 | return dev_err_probe(dev: &client->dev, err: PTR_ERR(ptr: ov5693->xvclk), |
1300 | fmt: "failed to get xvclk: %ld\n" , |
1301 | PTR_ERR(ptr: ov5693->xvclk)); |
1302 | |
1303 | if (ov5693->xvclk) { |
1304 | xvclk_rate = clk_get_rate(clk: ov5693->xvclk); |
1305 | } else { |
1306 | ret = fwnode_property_read_u32(dev_fwnode(&client->dev), |
1307 | propname: "clock-frequency" , |
1308 | val: &xvclk_rate); |
1309 | |
1310 | if (ret) { |
1311 | dev_err(&client->dev, "can't get clock frequency" ); |
1312 | return ret; |
1313 | } |
1314 | } |
1315 | |
1316 | if (xvclk_rate != OV5693_XVCLK_FREQ) |
1317 | dev_warn(&client->dev, "Found clk freq %u, expected %u\n" , |
1318 | xvclk_rate, OV5693_XVCLK_FREQ); |
1319 | |
1320 | ret = ov5693_configure_gpios(ov5693); |
1321 | if (ret) |
1322 | return ret; |
1323 | |
1324 | ret = ov5693_get_regulators(ov5693); |
1325 | if (ret) |
1326 | return dev_err_probe(dev: &client->dev, err: ret, |
1327 | fmt: "Error fetching regulators\n" ); |
1328 | |
1329 | ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
1330 | ov5693->pad.flags = MEDIA_PAD_FL_SOURCE; |
1331 | ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; |
1332 | |
1333 | ov5693->mode.crop = ov5693_default_crop; |
1334 | ov5693->mode.format = ov5693_default_fmt; |
1335 | ov5693->mode.vts = __ov5693_calc_vts(height: ov5693->mode.format.height); |
1336 | |
1337 | ret = ov5693_init_controls(ov5693); |
1338 | if (ret) |
1339 | return ret; |
1340 | |
1341 | ret = media_entity_pads_init(entity: &ov5693->sd.entity, num_pads: 1, pads: &ov5693->pad); |
1342 | if (ret) |
1343 | goto err_ctrl_handler_free; |
1344 | |
1345 | /* |
1346 | * We need the driver to work in the event that pm runtime is disable in |
1347 | * the kernel, so power up and verify the chip now. In the event that |
1348 | * runtime pm is disabled this will leave the chip on, so that streaming |
1349 | * will work. |
1350 | */ |
1351 | |
1352 | ret = ov5693_sensor_powerup(ov5693); |
1353 | if (ret) |
1354 | goto err_media_entity_cleanup; |
1355 | |
1356 | ret = ov5693_detect(ov5693); |
1357 | if (ret) |
1358 | goto err_powerdown; |
1359 | |
1360 | pm_runtime_set_active(dev: &client->dev); |
1361 | pm_runtime_get_noresume(dev: &client->dev); |
1362 | pm_runtime_enable(dev: &client->dev); |
1363 | |
1364 | ret = v4l2_async_register_subdev_sensor(sd: &ov5693->sd); |
1365 | if (ret) { |
1366 | dev_err(&client->dev, "failed to register V4L2 subdev: %d" , |
1367 | ret); |
1368 | goto err_pm_runtime; |
1369 | } |
1370 | |
1371 | pm_runtime_set_autosuspend_delay(dev: &client->dev, delay: 1000); |
1372 | pm_runtime_use_autosuspend(dev: &client->dev); |
1373 | pm_runtime_put_autosuspend(dev: &client->dev); |
1374 | |
1375 | return ret; |
1376 | |
1377 | err_pm_runtime: |
1378 | pm_runtime_disable(dev: &client->dev); |
1379 | pm_runtime_put_noidle(dev: &client->dev); |
1380 | err_powerdown: |
1381 | ov5693_sensor_powerdown(ov5693); |
1382 | err_media_entity_cleanup: |
1383 | media_entity_cleanup(entity: &ov5693->sd.entity); |
1384 | err_ctrl_handler_free: |
1385 | v4l2_ctrl_handler_free(hdl: &ov5693->ctrls.handler); |
1386 | |
1387 | return ret; |
1388 | } |
1389 | |
1390 | static void ov5693_remove(struct i2c_client *client) |
1391 | { |
1392 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
1393 | struct ov5693_device *ov5693 = to_ov5693_sensor(sd); |
1394 | |
1395 | v4l2_async_unregister_subdev(sd); |
1396 | media_entity_cleanup(entity: &ov5693->sd.entity); |
1397 | v4l2_ctrl_handler_free(hdl: &ov5693->ctrls.handler); |
1398 | mutex_destroy(lock: &ov5693->lock); |
1399 | |
1400 | /* |
1401 | * Disable runtime PM. In case runtime PM is disabled in the kernel, |
1402 | * make sure to turn power off manually. |
1403 | */ |
1404 | pm_runtime_disable(dev: &client->dev); |
1405 | if (!pm_runtime_status_suspended(dev: &client->dev)) |
1406 | ov5693_sensor_powerdown(ov5693); |
1407 | pm_runtime_set_suspended(dev: &client->dev); |
1408 | } |
1409 | |
1410 | static const struct dev_pm_ops ov5693_pm_ops = { |
1411 | SET_RUNTIME_PM_OPS(ov5693_sensor_suspend, ov5693_sensor_resume, NULL) |
1412 | }; |
1413 | |
1414 | static const struct acpi_device_id ov5693_acpi_match[] = { |
1415 | {"INT33BE" }, |
1416 | {}, |
1417 | }; |
1418 | MODULE_DEVICE_TABLE(acpi, ov5693_acpi_match); |
1419 | |
1420 | static const struct of_device_id ov5693_of_match[] = { |
1421 | { .compatible = "ovti,ov5693" , }, |
1422 | { /* sentinel */ }, |
1423 | }; |
1424 | MODULE_DEVICE_TABLE(of, ov5693_of_match); |
1425 | |
1426 | static struct i2c_driver ov5693_driver = { |
1427 | .driver = { |
1428 | .name = "ov5693" , |
1429 | .acpi_match_table = ov5693_acpi_match, |
1430 | .of_match_table = ov5693_of_match, |
1431 | .pm = &ov5693_pm_ops, |
1432 | }, |
1433 | .probe = ov5693_probe, |
1434 | .remove = ov5693_remove, |
1435 | }; |
1436 | module_i2c_driver(ov5693_driver); |
1437 | |
1438 | MODULE_DESCRIPTION("A low-level driver for OmniVision 5693 sensors" ); |
1439 | MODULE_LICENSE("GPL" ); |
1440 | |