1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Samsung LSI S5C73M3 8M pixel camera driver
4 *
5 * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
6 * Sylwester Nawrocki <s.nawrocki@samsung.com>
7 * Andrzej Hajda <a.hajda@samsung.com>
8 */
9
10#include <linux/sizes.h>
11#include <linux/delay.h>
12#include <linux/firmware.h>
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/media.h>
16#include <linux/module.h>
17#include <linux/regulator/consumer.h>
18#include <linux/slab.h>
19#include <linux/spi/spi.h>
20#include <linux/videodev2.h>
21#include <media/media-entity.h>
22#include <media/v4l2-ctrls.h>
23#include <media/v4l2-device.h>
24#include <media/v4l2-subdev.h>
25#include <media/v4l2-mediabus.h>
26
27#include "s5c73m3.h"
28
29static int s5c73m3_get_af_status(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
30{
31	u16 reg = REG_AF_STATUS_UNFOCUSED;
32
33	int ret = s5c73m3_read(state, REG_AF_STATUS, &reg);
34
35	switch (reg) {
36	case REG_CAF_STATUS_FIND_SEARCH_DIR:
37	case REG_AF_STATUS_FOCUSING:
38	case REG_CAF_STATUS_FOCUSING:
39		ctrl->val = V4L2_AUTO_FOCUS_STATUS_BUSY;
40		break;
41	case REG_CAF_STATUS_FOCUSED:
42	case REG_AF_STATUS_FOCUSED:
43		ctrl->val = V4L2_AUTO_FOCUS_STATUS_REACHED;
44		break;
45	default:
46		v4l2_info(&state->sensor_sd, "Unknown AF status %#x\n", reg);
47		fallthrough;
48	case REG_CAF_STATUS_UNFOCUSED:
49	case REG_AF_STATUS_UNFOCUSED:
50	case REG_AF_STATUS_INVALID:
51		ctrl->val = V4L2_AUTO_FOCUS_STATUS_FAILED;
52		break;
53	}
54
55	return ret;
56}
57
58static int s5c73m3_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
59{
60	struct v4l2_subdev *sd = ctrl_to_sensor_sd(ctrl);
61	struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd);
62	int ret;
63
64	if (state->power == 0)
65		return -EBUSY;
66
67	switch (ctrl->id) {
68	case V4L2_CID_FOCUS_AUTO:
69		ret = s5c73m3_get_af_status(state, state->ctrls.af_status);
70		if (ret)
71			return ret;
72		break;
73	}
74
75	return 0;
76}
77
78static int s5c73m3_set_colorfx(struct s5c73m3 *state, int val)
79{
80	static const unsigned short colorfx[][2] = {
81		{ V4L2_COLORFX_NONE,	 COMM_IMAGE_EFFECT_NONE },
82		{ V4L2_COLORFX_BW,	 COMM_IMAGE_EFFECT_MONO },
83		{ V4L2_COLORFX_SEPIA,	 COMM_IMAGE_EFFECT_SEPIA },
84		{ V4L2_COLORFX_NEGATIVE, COMM_IMAGE_EFFECT_NEGATIVE },
85		{ V4L2_COLORFX_AQUA,	 COMM_IMAGE_EFFECT_AQUA },
86	};
87	int i;
88
89	for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
90		if (colorfx[i][0] != val)
91			continue;
92
93		v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd,
94			 "Setting %s color effect\n",
95			 v4l2_ctrl_get_menu(state->ctrls.colorfx->id)[i]);
96
97		return s5c73m3_isp_command(state, COMM_IMAGE_EFFECT,
98					 colorfx[i][1]);
99	}
100	return -EINVAL;
101}
102
103/* Set exposure metering/exposure bias */
104static int s5c73m3_set_exposure(struct s5c73m3 *state, int auto_exp)
105{
106	struct v4l2_subdev *sd = &state->sensor_sd;
107	struct s5c73m3_ctrls *ctrls = &state->ctrls;
108	int ret = 0;
109
110	if (ctrls->exposure_metering->is_new) {
111		u16 metering;
112
113		switch (ctrls->exposure_metering->val) {
114		case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
115			metering = COMM_METERING_CENTER;
116			break;
117		case V4L2_EXPOSURE_METERING_SPOT:
118			metering = COMM_METERING_SPOT;
119			break;
120		default:
121			metering = COMM_METERING_AVERAGE;
122			break;
123		}
124
125		ret = s5c73m3_isp_command(state, COMM_METERING, metering);
126	}
127
128	if (!ret && ctrls->exposure_bias->is_new) {
129		u16 exp_bias = ctrls->exposure_bias->val;
130		ret = s5c73m3_isp_command(state, COMM_EV, exp_bias);
131	}
132
133	v4l2_dbg(1, s5c73m3_dbg, sd,
134		 "%s: exposure bias: %#x, metering: %#x (%d)\n",  __func__,
135		 ctrls->exposure_bias->val, ctrls->exposure_metering->val, ret);
136
137	return ret;
138}
139
140static int s5c73m3_set_white_balance(struct s5c73m3 *state, int val)
141{
142	static const unsigned short wb[][2] = {
143		{ V4L2_WHITE_BALANCE_INCANDESCENT,  COMM_AWB_MODE_INCANDESCENT},
144		{ V4L2_WHITE_BALANCE_FLUORESCENT,   COMM_AWB_MODE_FLUORESCENT1},
145		{ V4L2_WHITE_BALANCE_FLUORESCENT_H, COMM_AWB_MODE_FLUORESCENT2},
146		{ V4L2_WHITE_BALANCE_CLOUDY,        COMM_AWB_MODE_CLOUDY},
147		{ V4L2_WHITE_BALANCE_DAYLIGHT,      COMM_AWB_MODE_DAYLIGHT},
148		{ V4L2_WHITE_BALANCE_AUTO,          COMM_AWB_MODE_AUTO},
149	};
150	int i;
151
152	for (i = 0; i < ARRAY_SIZE(wb); i++) {
153		if (wb[i][0] != val)
154			continue;
155
156		v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd,
157			 "Setting white balance to: %s\n",
158			 v4l2_ctrl_get_menu(state->ctrls.auto_wb->id)[i]);
159
160		return s5c73m3_isp_command(state, COMM_AWB_MODE, wb[i][1]);
161	}
162
163	return -EINVAL;
164}
165
166static int s5c73m3_af_run(struct s5c73m3 *state, bool on)
167{
168	struct s5c73m3_ctrls *c = &state->ctrls;
169
170	if (!on)
171		return s5c73m3_isp_command(state, COMM_AF_CON,
172							COMM_AF_CON_STOP);
173
174	if (c->focus_auto->val)
175		return s5c73m3_isp_command(state, COMM_AF_MODE,
176					   COMM_AF_MODE_PREVIEW_CAF_START);
177
178	return s5c73m3_isp_command(state, COMM_AF_CON, COMM_AF_CON_START);
179}
180
181static int s5c73m3_3a_lock(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
182{
183	bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
184	bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
185	bool af_lock = ctrl->val & V4L2_LOCK_FOCUS;
186	int ret = 0;
187
188	if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_EXPOSURE) {
189		ret = s5c73m3_isp_command(state, COMM_AE_CON,
190				ae_lock ? COMM_AE_STOP : COMM_AE_START);
191		if (ret)
192			return ret;
193	}
194
195	if (((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_WHITE_BALANCE)
196	    && state->ctrls.auto_wb->val) {
197		ret = s5c73m3_isp_command(state, COMM_AWB_CON,
198			awb_lock ? COMM_AWB_STOP : COMM_AWB_START);
199		if (ret)
200			return ret;
201	}
202
203	if ((ctrl->val ^ ctrl->cur.val) & V4L2_LOCK_FOCUS)
204		ret = s5c73m3_af_run(state, !af_lock);
205
206	return ret;
207}
208
209static int s5c73m3_set_auto_focus(struct s5c73m3 *state, int caf)
210{
211	struct s5c73m3_ctrls *c = &state->ctrls;
212	int ret = 1;
213
214	if (c->af_distance->is_new) {
215		u16 mode = (c->af_distance->val == V4L2_AUTO_FOCUS_RANGE_MACRO)
216				? COMM_AF_MODE_MACRO : COMM_AF_MODE_NORMAL;
217		ret = s5c73m3_isp_command(state, COMM_AF_MODE, mode);
218		if (ret != 0)
219			return ret;
220	}
221
222	if (!ret || (c->focus_auto->is_new && c->focus_auto->val) ||
223							c->af_start->is_new)
224		ret = s5c73m3_af_run(state, 1);
225	else if ((c->focus_auto->is_new && !c->focus_auto->val) ||
226							c->af_stop->is_new)
227		ret = s5c73m3_af_run(state, 0);
228	else
229		ret = 0;
230
231	return ret;
232}
233
234static int s5c73m3_set_contrast(struct s5c73m3 *state, int val)
235{
236	u16 reg = (val < 0) ? -val + 2 : val;
237	return s5c73m3_isp_command(state, COMM_CONTRAST, reg);
238}
239
240static int s5c73m3_set_saturation(struct s5c73m3 *state, int val)
241{
242	u16 reg = (val < 0) ? -val + 2 : val;
243	return s5c73m3_isp_command(state, COMM_SATURATION, reg);
244}
245
246static int s5c73m3_set_sharpness(struct s5c73m3 *state, int val)
247{
248	u16 reg = (val < 0) ? -val + 2 : val;
249	return s5c73m3_isp_command(state, COMM_SHARPNESS, reg);
250}
251
252static int s5c73m3_set_iso(struct s5c73m3 *state, int val)
253{
254	u32 iso;
255
256	if (val == V4L2_ISO_SENSITIVITY_MANUAL)
257		iso = state->ctrls.iso->val + 1;
258	else
259		iso = 0;
260
261	return s5c73m3_isp_command(state, COMM_ISO, iso);
262}
263
264static int s5c73m3_set_stabilization(struct s5c73m3 *state, int val)
265{
266	struct v4l2_subdev *sd = &state->sensor_sd;
267
268	v4l2_dbg(1, s5c73m3_dbg, sd, "Image stabilization: %d\n", val);
269
270	return s5c73m3_isp_command(state, COMM_FRAME_RATE, val ?
271			COMM_FRAME_RATE_ANTI_SHAKE : COMM_FRAME_RATE_AUTO_SET);
272}
273
274static int s5c73m3_set_jpeg_quality(struct s5c73m3 *state, int quality)
275{
276	int reg;
277
278	if (quality <= 65)
279		reg = COMM_IMAGE_QUALITY_NORMAL;
280	else if (quality <= 75)
281		reg = COMM_IMAGE_QUALITY_FINE;
282	else
283		reg = COMM_IMAGE_QUALITY_SUPERFINE;
284
285	return s5c73m3_isp_command(state, COMM_IMAGE_QUALITY, reg);
286}
287
288static int s5c73m3_set_scene_program(struct s5c73m3 *state, int val)
289{
290	static const unsigned short scene_lookup[] = {
291		COMM_SCENE_MODE_NONE,	     /* V4L2_SCENE_MODE_NONE */
292		COMM_SCENE_MODE_AGAINST_LIGHT,/* V4L2_SCENE_MODE_BACKLIGHT */
293		COMM_SCENE_MODE_BEACH,	     /* V4L2_SCENE_MODE_BEACH_SNOW */
294		COMM_SCENE_MODE_CANDLE,	     /* V4L2_SCENE_MODE_CANDLE_LIGHT */
295		COMM_SCENE_MODE_DAWN,	     /* V4L2_SCENE_MODE_DAWN_DUSK */
296		COMM_SCENE_MODE_FALL,	     /* V4L2_SCENE_MODE_FALL_COLORS */
297		COMM_SCENE_MODE_FIRE,	     /* V4L2_SCENE_MODE_FIREWORKS */
298		COMM_SCENE_MODE_LANDSCAPE,    /* V4L2_SCENE_MODE_LANDSCAPE */
299		COMM_SCENE_MODE_NIGHT,	     /* V4L2_SCENE_MODE_NIGHT */
300		COMM_SCENE_MODE_INDOOR,	     /* V4L2_SCENE_MODE_PARTY_INDOOR */
301		COMM_SCENE_MODE_PORTRAIT,     /* V4L2_SCENE_MODE_PORTRAIT */
302		COMM_SCENE_MODE_SPORTS,	     /* V4L2_SCENE_MODE_SPORTS */
303		COMM_SCENE_MODE_SUNSET,	     /* V4L2_SCENE_MODE_SUNSET */
304		COMM_SCENE_MODE_TEXT,	     /* V4L2_SCENE_MODE_TEXT */
305	};
306
307	v4l2_dbg(1, s5c73m3_dbg, &state->sensor_sd, "Setting %s scene mode\n",
308		 v4l2_ctrl_get_menu(state->ctrls.scene_mode->id)[val]);
309
310	return s5c73m3_isp_command(state, COMM_SCENE_MODE, scene_lookup[val]);
311}
312
313static int s5c73m3_set_power_line_freq(struct s5c73m3 *state, int val)
314{
315	unsigned int pwr_line_freq = COMM_FLICKER_NONE;
316
317	switch (val) {
318	case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
319		pwr_line_freq = COMM_FLICKER_NONE;
320		break;
321	case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
322		pwr_line_freq = COMM_FLICKER_AUTO_50HZ;
323		break;
324	case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
325		pwr_line_freq = COMM_FLICKER_AUTO_60HZ;
326		break;
327	default:
328	case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
329		pwr_line_freq = COMM_FLICKER_NONE;
330	}
331
332	return s5c73m3_isp_command(state, COMM_FLICKER_MODE, pwr_line_freq);
333}
334
335static int s5c73m3_s_ctrl(struct v4l2_ctrl *ctrl)
336{
337	struct v4l2_subdev *sd = ctrl_to_sensor_sd(ctrl);
338	struct s5c73m3 *state = sensor_sd_to_s5c73m3(sd);
339	int ret = 0;
340
341	v4l2_dbg(1, s5c73m3_dbg, sd, "set_ctrl: %s, value: %d\n",
342		 ctrl->name, ctrl->val);
343
344	mutex_lock(&state->lock);
345	/*
346	 * If the device is not powered up by the host driver do
347	 * not apply any controls to H/W at this time. Instead
348	 * the controls will be restored right after power-up.
349	 */
350	if (state->power == 0)
351		goto unlock;
352
353	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) {
354		ret = -EINVAL;
355		goto unlock;
356	}
357
358	switch (ctrl->id) {
359	case V4L2_CID_3A_LOCK:
360		ret = s5c73m3_3a_lock(state, ctrl);
361		break;
362
363	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
364		ret = s5c73m3_set_white_balance(state, ctrl->val);
365		break;
366
367	case V4L2_CID_CONTRAST:
368		ret = s5c73m3_set_contrast(state, ctrl->val);
369		break;
370
371	case V4L2_CID_COLORFX:
372		ret = s5c73m3_set_colorfx(state, ctrl->val);
373		break;
374
375	case V4L2_CID_EXPOSURE_AUTO:
376		ret = s5c73m3_set_exposure(state, ctrl->val);
377		break;
378
379	case V4L2_CID_FOCUS_AUTO:
380		ret = s5c73m3_set_auto_focus(state, ctrl->val);
381		break;
382
383	case V4L2_CID_IMAGE_STABILIZATION:
384		ret = s5c73m3_set_stabilization(state, ctrl->val);
385		break;
386
387	case V4L2_CID_ISO_SENSITIVITY:
388		ret = s5c73m3_set_iso(state, ctrl->val);
389		break;
390
391	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
392		ret = s5c73m3_set_jpeg_quality(state, ctrl->val);
393		break;
394
395	case V4L2_CID_POWER_LINE_FREQUENCY:
396		ret = s5c73m3_set_power_line_freq(state, ctrl->val);
397		break;
398
399	case V4L2_CID_SATURATION:
400		ret = s5c73m3_set_saturation(state, ctrl->val);
401		break;
402
403	case V4L2_CID_SCENE_MODE:
404		ret = s5c73m3_set_scene_program(state, ctrl->val);
405		break;
406
407	case V4L2_CID_SHARPNESS:
408		ret = s5c73m3_set_sharpness(state, ctrl->val);
409		break;
410
411	case V4L2_CID_WIDE_DYNAMIC_RANGE:
412		ret = s5c73m3_isp_command(state, COMM_WDR, !!ctrl->val);
413		break;
414
415	case V4L2_CID_ZOOM_ABSOLUTE:
416		ret = s5c73m3_isp_command(state, COMM_ZOOM_STEP, ctrl->val);
417		break;
418	}
419unlock:
420	mutex_unlock(&state->lock);
421	return ret;
422}
423
424static const struct v4l2_ctrl_ops s5c73m3_ctrl_ops = {
425	.g_volatile_ctrl	= s5c73m3_g_volatile_ctrl,
426	.s_ctrl			= s5c73m3_s_ctrl,
427};
428
429/* Supported manual ISO values */
430static const s64 iso_qmenu[] = {
431	/* COMM_ISO: 0x0001...0x0004 */
432	100, 200, 400, 800,
433};
434
435/* Supported exposure bias values (-2.0EV...+2.0EV) */
436static const s64 ev_bias_qmenu[] = {
437	/* COMM_EV: 0x0000...0x0008 */
438	-2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
439};
440
441int s5c73m3_init_controls(struct s5c73m3 *state)
442{
443	const struct v4l2_ctrl_ops *ops = &s5c73m3_ctrl_ops;
444	struct s5c73m3_ctrls *ctrls = &state->ctrls;
445	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
446
447	int ret = v4l2_ctrl_handler_init(hdl, 22);
448	if (ret)
449		return ret;
450
451	/* White balance */
452	ctrls->auto_wb = v4l2_ctrl_new_std_menu(hdl, ops,
453			V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
454			9, ~0x15e, V4L2_WHITE_BALANCE_AUTO);
455
456	/* Exposure (only automatic exposure) */
457	ctrls->auto_exposure = v4l2_ctrl_new_std_menu(hdl, ops,
458			V4L2_CID_EXPOSURE_AUTO, 0, ~0x01, V4L2_EXPOSURE_AUTO);
459
460	ctrls->exposure_bias = v4l2_ctrl_new_int_menu(hdl, ops,
461			V4L2_CID_AUTO_EXPOSURE_BIAS,
462			ARRAY_SIZE(ev_bias_qmenu) - 1,
463			ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
464			ev_bias_qmenu);
465
466	ctrls->exposure_metering = v4l2_ctrl_new_std_menu(hdl, ops,
467			V4L2_CID_EXPOSURE_METERING,
468			2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
469
470	/* Auto focus */
471	ctrls->focus_auto = v4l2_ctrl_new_std(hdl, ops,
472			V4L2_CID_FOCUS_AUTO, 0, 1, 1, 0);
473
474	ctrls->af_start = v4l2_ctrl_new_std(hdl, ops,
475			V4L2_CID_AUTO_FOCUS_START, 0, 1, 1, 0);
476
477	ctrls->af_stop = v4l2_ctrl_new_std(hdl, ops,
478			V4L2_CID_AUTO_FOCUS_STOP, 0, 1, 1, 0);
479
480	ctrls->af_status = v4l2_ctrl_new_std(hdl, ops,
481			V4L2_CID_AUTO_FOCUS_STATUS, 0,
482			(V4L2_AUTO_FOCUS_STATUS_BUSY |
483			 V4L2_AUTO_FOCUS_STATUS_REACHED |
484			 V4L2_AUTO_FOCUS_STATUS_FAILED),
485			0, V4L2_AUTO_FOCUS_STATUS_IDLE);
486
487	ctrls->af_distance = v4l2_ctrl_new_std_menu(hdl, ops,
488			V4L2_CID_AUTO_FOCUS_RANGE,
489			V4L2_AUTO_FOCUS_RANGE_MACRO,
490			~(1 << V4L2_AUTO_FOCUS_RANGE_NORMAL |
491			  1 << V4L2_AUTO_FOCUS_RANGE_MACRO),
492			V4L2_AUTO_FOCUS_RANGE_NORMAL);
493	/* ISO sensitivity */
494	ctrls->auto_iso = v4l2_ctrl_new_std_menu(hdl, ops,
495			V4L2_CID_ISO_SENSITIVITY_AUTO, 1, 0,
496			V4L2_ISO_SENSITIVITY_AUTO);
497
498	ctrls->iso = v4l2_ctrl_new_int_menu(hdl, ops,
499			V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
500			ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
501
502	ctrls->contrast = v4l2_ctrl_new_std(hdl, ops,
503			V4L2_CID_CONTRAST, -2, 2, 1, 0);
504
505	ctrls->saturation = v4l2_ctrl_new_std(hdl, ops,
506			V4L2_CID_SATURATION, -2, 2, 1, 0);
507
508	ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops,
509			V4L2_CID_SHARPNESS, -2, 2, 1, 0);
510
511	ctrls->zoom = v4l2_ctrl_new_std(hdl, ops,
512			V4L2_CID_ZOOM_ABSOLUTE, 0, 30, 1, 0);
513
514	ctrls->colorfx = v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
515			V4L2_COLORFX_AQUA, ~0x40f, V4L2_COLORFX_NONE);
516
517	ctrls->wdr = v4l2_ctrl_new_std(hdl, ops,
518			V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
519
520	ctrls->stabilization = v4l2_ctrl_new_std(hdl, ops,
521			V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
522
523	v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
524			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
525			       V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
526
527	ctrls->jpeg_quality = v4l2_ctrl_new_std(hdl, ops,
528			V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
529
530	ctrls->scene_mode = v4l2_ctrl_new_std_menu(hdl, ops,
531			V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_TEXT, ~0x3fff,
532			V4L2_SCENE_MODE_NONE);
533
534	ctrls->aaa_lock = v4l2_ctrl_new_std(hdl, ops,
535			V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
536
537	if (hdl->error) {
538		ret = hdl->error;
539		v4l2_ctrl_handler_free(hdl);
540		return ret;
541	}
542
543	v4l2_ctrl_auto_cluster(3, &ctrls->auto_exposure, 0, false);
544	ctrls->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
545				V4L2_CTRL_FLAG_UPDATE;
546	v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, 0, false);
547	ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;
548	v4l2_ctrl_cluster(5, &ctrls->focus_auto);
549
550	state->sensor_sd.ctrl_handler = hdl;
551
552	return 0;
553}
554