blob: 2aa15b9c23cc1baf6a7089e6712f90caf2847532 [file] [log] [blame]
Luca Ceresolie6002df2018-08-24 12:35:25 -04001// SPDX-License-Identifier: GPL-2.0
Leon Luo0985dd32017-10-05 02:06:21 +02002/*
3 * imx274.c - IMX274 CMOS Image Sensor driver
4 *
5 * Copyright (C) 2017, Leopard Imaging, Inc.
6 *
7 * Leon Luo <leonl@leopardimaging.com>
8 * Edwin Zou <edwinz@leopardimaging.com>
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04009 * Luca Ceresoli <luca@lucaceresoli.net>
Leon Luo0985dd32017-10-05 02:06:21 +020010 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/gpio.h>
15#include <linux/gpio/consumer.h>
16#include <linux/i2c.h>
17#include <linux/init.h>
Luca Ceresoli39dd23d2018-07-25 12:24:55 -040018#include <linux/kernel.h>
Leon Luo0985dd32017-10-05 02:06:21 +020019#include <linux/module.h>
20#include <linux/of_gpio.h>
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +020021#include <linux/pm_runtime.h>
Leon Luo0985dd32017-10-05 02:06:21 +020022#include <linux/regmap.h>
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +020023#include <linux/regulator/consumer.h>
Leon Luo0985dd32017-10-05 02:06:21 +020024#include <linux/slab.h>
25#include <linux/v4l2-mediabus.h>
26#include <linux/videodev2.h>
27
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-device.h>
Eugen Hristev0abb8f92021-11-23 13:04:21 +010030#include <media/v4l2-fwnode.h>
Leon Luo0985dd32017-10-05 02:06:21 +020031#include <media/v4l2-subdev.h>
32
33/*
34 * See "SHR, SVR Setting" in datasheet
35 */
36#define IMX274_DEFAULT_FRAME_LENGTH (4550)
37#define IMX274_MAX_FRAME_LENGTH (0x000fffff)
38
39/*
40 * See "Frame Rate Adjustment" in datasheet
41 */
42#define IMX274_PIXCLK_CONST1 (72000000)
43#define IMX274_PIXCLK_CONST2 (1000000)
44
45/*
46 * The input gain is shifted by IMX274_GAIN_SHIFT to get
47 * decimal number. The real gain is
48 * (float)input_gain_value / (1 << IMX274_GAIN_SHIFT)
49 */
50#define IMX274_GAIN_SHIFT (8)
51#define IMX274_GAIN_SHIFT_MASK ((1 << IMX274_GAIN_SHIFT) - 1)
52
53/*
54 * See "Analog Gain" and "Digital Gain" in datasheet
55 * min gain is 1X
56 * max gain is calculated based on IMX274_GAIN_REG_MAX
57 */
58#define IMX274_GAIN_REG_MAX (1957)
59#define IMX274_MIN_GAIN (0x01 << IMX274_GAIN_SHIFT)
60#define IMX274_MAX_ANALOG_GAIN ((2048 << IMX274_GAIN_SHIFT)\
61 / (2048 - IMX274_GAIN_REG_MAX))
62#define IMX274_MAX_DIGITAL_GAIN (8)
63#define IMX274_DEF_GAIN (20 << IMX274_GAIN_SHIFT)
64#define IMX274_GAIN_CONST (2048) /* for gain formula */
65
66/*
67 * 1 line time in us = (HMAX / 72), minimal is 4 lines
68 */
69#define IMX274_MIN_EXPOSURE_TIME (4 * 260 / 72)
70
Leon Luo0985dd32017-10-05 02:06:21 +020071#define IMX274_MAX_WIDTH (3840)
72#define IMX274_MAX_HEIGHT (2160)
73#define IMX274_MAX_FRAME_RATE (120)
74#define IMX274_MIN_FRAME_RATE (5)
75#define IMX274_DEF_FRAME_RATE (60)
76
77/*
78 * register SHR is limited to (SVR value + 1) x VMAX value - 4
79 */
80#define IMX274_SHR_LIMIT_CONST (4)
81
82/*
Luca Ceresoli4c858e92018-04-24 04:24:06 -040083 * Min and max sensor reset delay (microseconds)
Leon Luo0985dd32017-10-05 02:06:21 +020084 */
85#define IMX274_RESET_DELAY1 (2000)
86#define IMX274_RESET_DELAY2 (2200)
87
88/*
89 * shift and mask constants
90 */
91#define IMX274_SHIFT_8_BITS (8)
92#define IMX274_SHIFT_16_BITS (16)
93#define IMX274_MASK_LSB_2_BITS (0x03)
94#define IMX274_MASK_LSB_3_BITS (0x07)
95#define IMX274_MASK_LSB_4_BITS (0x0f)
96#define IMX274_MASK_LSB_8_BITS (0x00ff)
97
98#define DRIVER_NAME "IMX274"
99
100/*
101 * IMX274 register definitions
102 */
Luca Ceresoli4eb78462018-04-24 04:24:10 -0400103#define IMX274_SHR_REG_MSB 0x300D /* SHR */
104#define IMX274_SHR_REG_LSB 0x300C /* SHR */
Leon Luo0985dd32017-10-05 02:06:21 +0200105#define IMX274_SVR_REG_MSB 0x300F /* SVR */
106#define IMX274_SVR_REG_LSB 0x300E /* SVR */
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400107#define IMX274_HTRIM_EN_REG 0x3037
108#define IMX274_HTRIM_START_REG_LSB 0x3038
109#define IMX274_HTRIM_START_REG_MSB 0x3039
110#define IMX274_HTRIM_END_REG_LSB 0x303A
111#define IMX274_HTRIM_END_REG_MSB 0x303B
112#define IMX274_VWIDCUTEN_REG 0x30DD
113#define IMX274_VWIDCUT_REG_LSB 0x30DE
114#define IMX274_VWIDCUT_REG_MSB 0x30DF
115#define IMX274_VWINPOS_REG_LSB 0x30E0
116#define IMX274_VWINPOS_REG_MSB 0x30E1
117#define IMX274_WRITE_VSIZE_REG_LSB 0x3130
118#define IMX274_WRITE_VSIZE_REG_MSB 0x3131
119#define IMX274_Y_OUT_SIZE_REG_LSB 0x3132
120#define IMX274_Y_OUT_SIZE_REG_MSB 0x3133
Luca Ceresoli4eb78462018-04-24 04:24:10 -0400121#define IMX274_VMAX_REG_1 0x30FA /* VMAX, MSB */
122#define IMX274_VMAX_REG_2 0x30F9 /* VMAX */
123#define IMX274_VMAX_REG_3 0x30F8 /* VMAX, LSB */
Leon Luo0985dd32017-10-05 02:06:21 +0200124#define IMX274_HMAX_REG_MSB 0x30F7 /* HMAX */
125#define IMX274_HMAX_REG_LSB 0x30F6 /* HMAX */
Leon Luo0985dd32017-10-05 02:06:21 +0200126#define IMX274_ANALOG_GAIN_ADDR_LSB 0x300A /* ANALOG GAIN LSB */
127#define IMX274_ANALOG_GAIN_ADDR_MSB 0x300B /* ANALOG GAIN MSB */
128#define IMX274_DIGITAL_GAIN_REG 0x3012 /* Digital Gain */
129#define IMX274_VFLIP_REG 0x301A /* VERTICAL FLIP */
130#define IMX274_TEST_PATTERN_REG 0x303D /* TEST PATTERN */
131#define IMX274_STANDBY_REG 0x3000 /* STANDBY */
132
133#define IMX274_TABLE_WAIT_MS 0
134#define IMX274_TABLE_END 1
135
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200136/* regulator supplies */
137static const char * const imx274_supply_names[] = {
138 "vddl", /* IF (1.2V) supply */
139 "vdig", /* Digital Core (1.8V) supply */
140 "vana", /* Analog (2.8V) supply */
141};
142
143#define IMX274_NUM_SUPPLIES ARRAY_SIZE(imx274_supply_names)
144
Leon Luo0985dd32017-10-05 02:06:21 +0200145/*
146 * imx274 I2C operation related structure
147 */
148struct reg_8 {
149 u16 addr;
150 u8 val;
151};
152
153static const struct regmap_config imx274_regmap_config = {
154 .reg_bits = 16,
155 .val_bits = 8,
156 .cache_type = REGCACHE_RBTREE,
157};
158
Leon Luo0985dd32017-10-05 02:06:21 +0200159/*
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400160 * Parameters for each imx274 readout mode.
161 *
162 * These are the values to configure the sensor in one of the
163 * implemented modes.
164 *
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400165 * @init_regs: registers to initialize the mode
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200166 * @wbin_ratio: width downscale factor (e.g. 3 for 1280; 3 = 3840/1280)
167 * @hbin_ratio: height downscale factor (e.g. 3 for 720; 3 = 2160/720)
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400168 * @min_frame_len: Minimum frame length for each mode (see "Frame Rate
169 * Adjustment (CSI-2)" in the datasheet)
170 * @min_SHR: Minimum SHR register value (see "Shutter Setting (CSI-2)" in the
171 * datasheet)
172 * @max_fps: Maximum frames per second
173 * @nocpiop: Number of clocks per internal offset period (see "Integration Time
174 * in Each Readout Drive Mode (CSI-2)" in the datasheet)
Leon Luo0985dd32017-10-05 02:06:21 +0200175 */
Luca Ceresoli9648cb52018-08-24 12:35:22 -0400176struct imx274_mode {
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400177 const struct reg_8 *init_regs;
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200178 u8 wbin_ratio;
179 u8 hbin_ratio;
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400180 int min_frame_len;
181 int min_SHR;
182 int max_fps;
183 int nocpiop;
Leon Luo0985dd32017-10-05 02:06:21 +0200184};
185
186/*
187 * imx274 test pattern related structure
188 */
189enum {
190 TEST_PATTERN_DISABLED = 0,
191 TEST_PATTERN_ALL_000H,
192 TEST_PATTERN_ALL_FFFH,
193 TEST_PATTERN_ALL_555H,
194 TEST_PATTERN_ALL_AAAH,
195 TEST_PATTERN_VSP_5AH, /* VERTICAL STRIPE PATTERN 555H/AAAH */
196 TEST_PATTERN_VSP_A5H, /* VERTICAL STRIPE PATTERN AAAH/555H */
197 TEST_PATTERN_VSP_05H, /* VERTICAL STRIPE PATTERN 000H/555H */
198 TEST_PATTERN_VSP_50H, /* VERTICAL STRIPE PATTERN 555H/000H */
199 TEST_PATTERN_VSP_0FH, /* VERTICAL STRIPE PATTERN 000H/FFFH */
200 TEST_PATTERN_VSP_F0H, /* VERTICAL STRIPE PATTERN FFFH/000H */
201 TEST_PATTERN_H_COLOR_BARS,
202 TEST_PATTERN_V_COLOR_BARS,
203};
204
205static const char * const tp_qmenu[] = {
206 "Disabled",
207 "All 000h Pattern",
208 "All FFFh Pattern",
209 "All 555h Pattern",
210 "All AAAh Pattern",
211 "Vertical Stripe (555h / AAAh)",
212 "Vertical Stripe (AAAh / 555h)",
213 "Vertical Stripe (000h / 555h)",
214 "Vertical Stripe (555h / 000h)",
215 "Vertical Stripe (000h / FFFh)",
216 "Vertical Stripe (FFFh / 000h)",
Leon Luo0985dd32017-10-05 02:06:21 +0200217 "Vertical Color Bars",
Luca Ceresoli47ee7bd2018-12-05 11:32:21 -0500218 "Horizontal Color Bars",
Leon Luo0985dd32017-10-05 02:06:21 +0200219};
220
221/*
222 * All-pixel scan mode (10-bit)
223 * imx274 mode1(refer to datasheet) register configuration with
224 * 3840x2160 resolution, raw10 data and mipi four lane output
225 */
226static const struct reg_8 imx274_mode1_3840x2160_raw10[] = {
227 {0x3004, 0x01},
228 {0x3005, 0x01},
229 {0x3006, 0x00},
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400230 {0x3007, 0xa2},
Leon Luo0985dd32017-10-05 02:06:21 +0200231
232 {0x3018, 0xA2}, /* output XVS, HVS */
233
234 {0x306B, 0x05},
235 {0x30E2, 0x01},
Leon Luo0985dd32017-10-05 02:06:21 +0200236
237 {0x30EE, 0x01},
Leon Luo0985dd32017-10-05 02:06:21 +0200238 {0x3342, 0x0A},
239 {0x3343, 0x00},
240 {0x3344, 0x16},
241 {0x3345, 0x00},
242 {0x33A6, 0x01},
243 {0x3528, 0x0E},
244 {0x3554, 0x1F},
245 {0x3555, 0x01},
246 {0x3556, 0x01},
247 {0x3557, 0x01},
248 {0x3558, 0x01},
249 {0x3559, 0x00},
250 {0x355A, 0x00},
251 {0x35BA, 0x0E},
252 {0x366A, 0x1B},
253 {0x366B, 0x1A},
254 {0x366C, 0x19},
255 {0x366D, 0x17},
256 {0x3A41, 0x08},
257
258 {IMX274_TABLE_END, 0x00}
259};
260
261/*
262 * Horizontal/vertical 2/2-line binning
263 * (Horizontal and vertical weightedbinning, 10-bit)
264 * imx274 mode3(refer to datasheet) register configuration with
265 * 1920x1080 resolution, raw10 data and mipi four lane output
266 */
267static const struct reg_8 imx274_mode3_1920x1080_raw10[] = {
268 {0x3004, 0x02},
269 {0x3005, 0x21},
270 {0x3006, 0x00},
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400271 {0x3007, 0xb1},
Leon Luo0985dd32017-10-05 02:06:21 +0200272
273 {0x3018, 0xA2}, /* output XVS, HVS */
274
275 {0x306B, 0x05},
276 {0x30E2, 0x02},
277
Leon Luo0985dd32017-10-05 02:06:21 +0200278 {0x30EE, 0x01},
Leon Luo0985dd32017-10-05 02:06:21 +0200279 {0x3342, 0x0A},
280 {0x3343, 0x00},
281 {0x3344, 0x1A},
282 {0x3345, 0x00},
283 {0x33A6, 0x01},
284 {0x3528, 0x0E},
285 {0x3554, 0x00},
286 {0x3555, 0x01},
287 {0x3556, 0x01},
288 {0x3557, 0x01},
289 {0x3558, 0x01},
290 {0x3559, 0x00},
291 {0x355A, 0x00},
292 {0x35BA, 0x0E},
293 {0x366A, 0x1B},
294 {0x366B, 0x1A},
295 {0x366C, 0x19},
296 {0x366D, 0x17},
297 {0x3A41, 0x08},
298
299 {IMX274_TABLE_END, 0x00}
300};
301
302/*
303 * Vertical 2/3 subsampling binning horizontal 3 binning
304 * imx274 mode5(refer to datasheet) register configuration with
305 * 1280x720 resolution, raw10 data and mipi four lane output
306 */
307static const struct reg_8 imx274_mode5_1280x720_raw10[] = {
308 {0x3004, 0x03},
309 {0x3005, 0x31},
310 {0x3006, 0x00},
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400311 {0x3007, 0xa9},
Leon Luo0985dd32017-10-05 02:06:21 +0200312
313 {0x3018, 0xA2}, /* output XVS, HVS */
314
315 {0x306B, 0x05},
316 {0x30E2, 0x03},
317
Leon Luo0985dd32017-10-05 02:06:21 +0200318 {0x30EE, 0x01},
Leon Luo0985dd32017-10-05 02:06:21 +0200319 {0x3342, 0x0A},
320 {0x3343, 0x00},
321 {0x3344, 0x1B},
322 {0x3345, 0x00},
323 {0x33A6, 0x01},
324 {0x3528, 0x0E},
325 {0x3554, 0x00},
326 {0x3555, 0x01},
327 {0x3556, 0x01},
328 {0x3557, 0x01},
329 {0x3558, 0x01},
330 {0x3559, 0x00},
331 {0x355A, 0x00},
332 {0x35BA, 0x0E},
333 {0x366A, 0x1B},
334 {0x366B, 0x19},
335 {0x366C, 0x17},
336 {0x366D, 0x17},
337 {0x3A41, 0x04},
338
339 {IMX274_TABLE_END, 0x00}
340};
341
342/*
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200343 * Vertical 2/8 subsampling horizontal 3 binning
344 * imx274 mode6(refer to datasheet) register configuration with
345 * 1280x540 resolution, raw10 data and mipi four lane output
346 */
347static const struct reg_8 imx274_mode6_1280x540_raw10[] = {
348 {0x3004, 0x04}, /* mode setting */
349 {0x3005, 0x31},
350 {0x3006, 0x00},
351 {0x3007, 0x02}, /* mode setting */
352
353 {0x3018, 0xA2}, /* output XVS, HVS */
354
355 {0x306B, 0x05},
356 {0x30E2, 0x04}, /* mode setting */
357
358 {0x30EE, 0x01},
359 {0x3342, 0x0A},
360 {0x3343, 0x00},
361 {0x3344, 0x16},
362 {0x3345, 0x00},
363 {0x33A6, 0x01},
364 {0x3528, 0x0E},
365 {0x3554, 0x1F},
366 {0x3555, 0x01},
367 {0x3556, 0x01},
368 {0x3557, 0x01},
369 {0x3558, 0x01},
370 {0x3559, 0x00},
371 {0x355A, 0x00},
372 {0x35BA, 0x0E},
373 {0x366A, 0x1B},
374 {0x366B, 0x1A},
375 {0x366C, 0x19},
376 {0x366D, 0x17},
377 {0x3A41, 0x04},
378
379 {IMX274_TABLE_END, 0x00}
380};
381
382/*
Leon Luo0985dd32017-10-05 02:06:21 +0200383 * imx274 first step register configuration for
384 * starting stream
385 */
386static const struct reg_8 imx274_start_1[] = {
387 {IMX274_STANDBY_REG, 0x12},
Leon Luo0985dd32017-10-05 02:06:21 +0200388
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400389 /* PLRD: clock settings */
390 {0x3120, 0xF0},
391 {0x3121, 0x00},
392 {0x3122, 0x02},
393 {0x3129, 0x9C},
394 {0x312A, 0x02},
395 {0x312D, 0x02},
Leon Luo0985dd32017-10-05 02:06:21 +0200396
397 {0x310B, 0x00},
398
399 /* PLSTMG */
400 {0x304C, 0x00}, /* PLSTMG01 */
401 {0x304D, 0x03},
402 {0x331C, 0x1A},
403 {0x331D, 0x00},
404 {0x3502, 0x02},
405 {0x3529, 0x0E},
406 {0x352A, 0x0E},
407 {0x352B, 0x0E},
408 {0x3538, 0x0E},
409 {0x3539, 0x0E},
410 {0x3553, 0x00},
411 {0x357D, 0x05},
412 {0x357F, 0x05},
413 {0x3581, 0x04},
414 {0x3583, 0x76},
415 {0x3587, 0x01},
416 {0x35BB, 0x0E},
417 {0x35BC, 0x0E},
418 {0x35BD, 0x0E},
419 {0x35BE, 0x0E},
420 {0x35BF, 0x0E},
421 {0x366E, 0x00},
422 {0x366F, 0x00},
423 {0x3670, 0x00},
424 {0x3671, 0x00},
425
426 /* PSMIPI */
427 {0x3304, 0x32}, /* PSMIPI1 */
428 {0x3305, 0x00},
429 {0x3306, 0x32},
430 {0x3307, 0x00},
431 {0x3590, 0x32},
432 {0x3591, 0x00},
433 {0x3686, 0x32},
434 {0x3687, 0x00},
435
436 {IMX274_TABLE_END, 0x00}
437};
438
439/*
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400440 * imx274 second step register configuration for
Leon Luo0985dd32017-10-05 02:06:21 +0200441 * starting stream
442 */
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400443static const struct reg_8 imx274_start_2[] = {
Leon Luo0985dd32017-10-05 02:06:21 +0200444 {IMX274_STANDBY_REG, 0x00},
445 {0x303E, 0x02}, /* SYS_MODE = 2 */
446 {IMX274_TABLE_END, 0x00}
447};
448
449/*
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400450 * imx274 third step register configuration for
Leon Luo0985dd32017-10-05 02:06:21 +0200451 * starting stream
452 */
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400453static const struct reg_8 imx274_start_3[] = {
Leon Luo0985dd32017-10-05 02:06:21 +0200454 {0x30F4, 0x00},
Mauro Carvalho Chehabf8a76472019-02-18 14:28:58 -0500455 {0x3018, 0xA2}, /* XHS VHS OUTPUT */
Leon Luo0985dd32017-10-05 02:06:21 +0200456 {IMX274_TABLE_END, 0x00}
457};
458
459/*
Mauro Carvalho Chehabf8a76472019-02-18 14:28:58 -0500460 * imx274 register configuration for stopping stream
Leon Luo0985dd32017-10-05 02:06:21 +0200461 */
462static const struct reg_8 imx274_stop[] = {
463 {IMX274_STANDBY_REG, 0x01},
464 {IMX274_TABLE_END, 0x00}
465};
466
467/*
468 * imx274 disable test pattern register configuration
469 */
470static const struct reg_8 imx274_tp_disabled[] = {
471 {0x303C, 0x00},
472 {0x377F, 0x00},
473 {0x3781, 0x00},
474 {0x370B, 0x00},
475 {IMX274_TABLE_END, 0x00}
476};
477
478/*
479 * imx274 test pattern register configuration
480 * reg 0x303D defines the test pattern modes
481 */
482static const struct reg_8 imx274_tp_regs[] = {
483 {0x303C, 0x11},
484 {0x370E, 0x01},
485 {0x377F, 0x01},
486 {0x3781, 0x01},
487 {0x370B, 0x11},
488 {IMX274_TABLE_END, 0x00}
489};
490
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400491/* nocpiop happens to be the same number for the implemented modes */
Luca Ceresoli9648cb52018-08-24 12:35:22 -0400492static const struct imx274_mode imx274_modes[] = {
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400493 {
494 /* mode 1, 4K */
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200495 .wbin_ratio = 1, /* 3840 */
496 .hbin_ratio = 1, /* 2160 */
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400497 .init_regs = imx274_mode1_3840x2160_raw10,
498 .min_frame_len = 4550,
499 .min_SHR = 12,
500 .max_fps = 60,
501 .nocpiop = 112,
502 },
503 {
504 /* mode 3, 1080p */
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200505 .wbin_ratio = 2, /* 1920 */
506 .hbin_ratio = 2, /* 1080 */
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400507 .init_regs = imx274_mode3_1920x1080_raw10,
508 .min_frame_len = 2310,
509 .min_SHR = 8,
510 .max_fps = 120,
511 .nocpiop = 112,
512 },
513 {
514 /* mode 5, 720p */
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200515 .wbin_ratio = 3, /* 1280 */
516 .hbin_ratio = 3, /* 720 */
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400517 .init_regs = imx274_mode5_1280x720_raw10,
518 .min_frame_len = 2310,
519 .min_SHR = 8,
520 .max_fps = 120,
521 .nocpiop = 112,
522 },
Eugen Hristevf70ad2a2020-09-15 11:04:42 +0200523 {
524 /* mode 6, 540p */
525 .wbin_ratio = 3, /* 1280 */
526 .hbin_ratio = 4, /* 540 */
527 .init_regs = imx274_mode6_1280x540_raw10,
528 .min_frame_len = 2310,
529 .min_SHR = 4,
530 .max_fps = 120,
531 .nocpiop = 112,
532 },
Leon Luo0985dd32017-10-05 02:06:21 +0200533};
534
535/*
536 * struct imx274_ctrls - imx274 ctrl structure
537 * @handler: V4L2 ctrl handler structure
538 * @exposure: Pointer to expsure ctrl structure
539 * @gain: Pointer to gain ctrl structure
540 * @vflip: Pointer to vflip ctrl structure
541 * @test_pattern: Pointer to test pattern ctrl structure
542 */
543struct imx274_ctrls {
544 struct v4l2_ctrl_handler handler;
545 struct v4l2_ctrl *exposure;
546 struct v4l2_ctrl *gain;
547 struct v4l2_ctrl *vflip;
548 struct v4l2_ctrl *test_pattern;
549};
550
551/*
552 * struct stim274 - imx274 device structure
553 * @sd: V4L2 subdevice structure
Luca Ceresoli19d38b22018-06-11 07:35:38 -0400554 * @pad: Media pad structure
Leon Luo0985dd32017-10-05 02:06:21 +0200555 * @client: Pointer to I2C client
556 * @ctrls: imx274 control structure
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400557 * @crop: rect to be captured
558 * @compose: compose rect, i.e. output resolution
Leon Luo0985dd32017-10-05 02:06:21 +0200559 * @format: V4L2 media bus frame format structure
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400560 * (width and height are in sync with the compose rect)
Leon Luo0985dd32017-10-05 02:06:21 +0200561 * @frame_rate: V4L2 frame rate structure
562 * @regmap: Pointer to regmap structure
563 * @reset_gpio: Pointer to reset gpio
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200564 * @supplies: List of analog and digital supply regulators
565 * @inck: Pointer to sensor input clock
Leon Luo0985dd32017-10-05 02:06:21 +0200566 * @lock: Mutex structure
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400567 * @mode: Parameters for the selected readout mode
Leon Luo0985dd32017-10-05 02:06:21 +0200568 */
569struct stimx274 {
570 struct v4l2_subdev sd;
571 struct media_pad pad;
572 struct i2c_client *client;
573 struct imx274_ctrls ctrls;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400574 struct v4l2_rect crop;
Leon Luo0985dd32017-10-05 02:06:21 +0200575 struct v4l2_mbus_framefmt format;
576 struct v4l2_fract frame_interval;
577 struct regmap *regmap;
578 struct gpio_desc *reset_gpio;
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200579 struct regulator_bulk_data supplies[IMX274_NUM_SUPPLIES];
580 struct clk *inck;
Leon Luo0985dd32017-10-05 02:06:21 +0200581 struct mutex lock; /* mutex lock for operations */
Luca Ceresoli9648cb52018-08-24 12:35:22 -0400582 const struct imx274_mode *mode;
Leon Luo0985dd32017-10-05 02:06:21 +0200583};
584
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400585#define IMX274_ROUND(dim, step, flags) \
586 ((flags) & V4L2_SEL_FLAG_GE \
587 ? roundup((dim), (step)) \
588 : ((flags) & V4L2_SEL_FLAG_LE \
589 ? rounddown((dim), (step)) \
590 : rounddown((dim) + (step) / 2, (step))))
591
Leon Luo0985dd32017-10-05 02:06:21 +0200592/*
593 * Function declaration
594 */
595static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl);
596static int imx274_set_exposure(struct stimx274 *priv, int val);
597static int imx274_set_vflip(struct stimx274 *priv, int val);
598static int imx274_set_test_pattern(struct stimx274 *priv, int val);
599static int imx274_set_frame_interval(struct stimx274 *priv,
600 struct v4l2_fract frame_interval);
601
602static inline void msleep_range(unsigned int delay_base)
603{
604 usleep_range(delay_base * 1000, delay_base * 1000 + 500);
605}
606
607/*
608 * v4l2_ctrl and v4l2_subdev related operations
609 */
610static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
611{
612 return &container_of(ctrl->handler,
613 struct stimx274, ctrls.handler)->sd;
614}
615
616static inline struct stimx274 *to_imx274(struct v4l2_subdev *sd)
617{
618 return container_of(sd, struct stimx274, sd);
619}
620
621/*
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400622 * Writing a register table
623 *
624 * @priv: Pointer to device
625 * @table: Table containing register values (with optional delays)
Leon Luo0985dd32017-10-05 02:06:21 +0200626 *
627 * This is used to write register table into sensor's reg map.
628 *
629 * Return: 0 on success, errors otherwise
630 */
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400631static int imx274_write_table(struct stimx274 *priv, const struct reg_8 table[])
Leon Luo0985dd32017-10-05 02:06:21 +0200632{
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400633 struct regmap *regmap = priv->regmap;
Dan Carpenter021741a2017-12-05 09:37:39 -0500634 int err = 0;
Leon Luo0985dd32017-10-05 02:06:21 +0200635 const struct reg_8 *next;
636 u8 val;
637
638 int range_start = -1;
639 int range_count = 0;
640 u8 range_vals[16];
641 int max_range_vals = ARRAY_SIZE(range_vals);
642
643 for (next = table;; next++) {
644 if ((next->addr != range_start + range_count) ||
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400645 (next->addr == IMX274_TABLE_END) ||
646 (next->addr == IMX274_TABLE_WAIT_MS) ||
Leon Luo0985dd32017-10-05 02:06:21 +0200647 (range_count == max_range_vals)) {
648 if (range_count == 1)
649 err = regmap_write(regmap,
650 range_start, range_vals[0]);
651 else if (range_count > 1)
652 err = regmap_bulk_write(regmap, range_start,
653 &range_vals[0],
654 range_count);
Mauro Carvalho Chehab00b4bac72017-11-01 17:05:57 -0400655 else
656 err = 0;
Leon Luo0985dd32017-10-05 02:06:21 +0200657
658 if (err)
659 return err;
660
661 range_start = -1;
662 range_count = 0;
663
664 /* Handle special address values */
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400665 if (next->addr == IMX274_TABLE_END)
Leon Luo0985dd32017-10-05 02:06:21 +0200666 break;
667
Luca Ceresoli7ff67862018-06-11 07:35:36 -0400668 if (next->addr == IMX274_TABLE_WAIT_MS) {
Leon Luo0985dd32017-10-05 02:06:21 +0200669 msleep_range(next->val);
670 continue;
671 }
672 }
673
674 val = next->val;
675
676 if (range_start == -1)
677 range_start = next->addr;
678
679 range_vals[range_count++] = val;
680 }
681 return 0;
682}
683
Leon Luo0985dd32017-10-05 02:06:21 +0200684static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val)
685{
686 int err;
687
688 err = regmap_write(priv->regmap, addr, val);
689 if (err)
690 dev_err(&priv->client->dev,
691 "%s : i2c write failed, %x = %x\n", __func__,
692 addr, val);
693 else
694 dev_dbg(&priv->client->dev,
695 "%s : addr 0x%x, val=0x%x\n", __func__,
696 addr, val);
697 return err;
698}
699
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -0400700/**
Hans Verkuila4184b42021-03-03 13:55:10 +0100701 * imx274_read_mbreg - Read a multibyte register.
Luca Ceresolica0174672018-08-24 12:35:24 -0400702 *
703 * Uses a bulk read where possible.
704 *
705 * @priv: Pointer to device structure
706 * @addr: Address of the LSB register. Other registers must be
707 * consecutive, least-to-most significant.
708 * @val: Pointer to store the register value (cpu endianness)
709 * @nbytes: Number of bytes to read (range: [1..3]).
710 * Other bytes are zet to 0.
711 *
712 * Return: 0 on success, errors otherwise
713 */
714static int imx274_read_mbreg(struct stimx274 *priv, u16 addr, u32 *val,
715 size_t nbytes)
716{
717 __le32 val_le = 0;
718 int err;
719
720 err = regmap_bulk_read(priv->regmap, addr, &val_le, nbytes);
721 if (err) {
722 dev_err(&priv->client->dev,
723 "%s : i2c bulk read failed, %x (%zu bytes)\n",
724 __func__, addr, nbytes);
725 } else {
726 *val = le32_to_cpu(val_le);
727 dev_dbg(&priv->client->dev,
728 "%s : addr 0x%x, val=0x%x (%zu bytes)\n",
729 __func__, addr, *val, nbytes);
730 }
731
732 return err;
733}
734
735/**
Hans Verkuila4184b42021-03-03 13:55:10 +0100736 * imx274_write_mbreg - Write a multibyte register.
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -0400737 *
738 * Uses a bulk write where possible.
739 *
740 * @priv: Pointer to device structure
741 * @addr: Address of the LSB register. Other registers must be
742 * consecutive, least-to-most significant.
743 * @val: Value to be written to the register (cpu endianness)
Luca Ceresoli1657c282018-08-24 12:35:23 -0400744 * @nbytes: Number of bytes to write (range: [1..3])
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -0400745 */
746static int imx274_write_mbreg(struct stimx274 *priv, u16 addr, u32 val,
747 size_t nbytes)
748{
749 __le32 val_le = cpu_to_le32(val);
750 int err;
751
752 err = regmap_bulk_write(priv->regmap, addr, &val_le, nbytes);
753 if (err)
754 dev_err(&priv->client->dev,
755 "%s : i2c bulk write failed, %x = %x (%zu bytes)\n",
756 __func__, addr, val, nbytes);
757 else
758 dev_dbg(&priv->client->dev,
759 "%s : addr 0x%x, val=0x%x (%zu bytes)\n",
760 __func__, addr, val, nbytes);
761 return err;
762}
763
Leon Luo0985dd32017-10-05 02:06:21 +0200764/*
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400765 * Set mode registers to start stream.
Leon Luo0985dd32017-10-05 02:06:21 +0200766 * @priv: Pointer to device structure
Leon Luo0985dd32017-10-05 02:06:21 +0200767 *
768 * Return: 0 on success, errors otherwise
769 */
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400770static int imx274_mode_regs(struct stimx274 *priv)
Leon Luo0985dd32017-10-05 02:06:21 +0200771{
772 int err = 0;
773
Luca Ceresoli8ed8bba702018-04-24 04:24:11 -0400774 err = imx274_write_table(priv, imx274_start_1);
Leon Luo0985dd32017-10-05 02:06:21 +0200775 if (err)
776 return err;
777
Luca Ceresoli96a2c732018-06-11 07:35:33 -0400778 err = imx274_write_table(priv, priv->mode->init_regs);
Leon Luo0985dd32017-10-05 02:06:21 +0200779
780 return err;
781}
782
783/*
784 * imx274_start_stream - Function for starting stream per mode index
785 * @priv: Pointer to device structure
786 *
787 * Return: 0 on success, errors otherwise
788 */
789static int imx274_start_stream(struct stimx274 *priv)
790{
791 int err = 0;
792
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200793 err = __v4l2_ctrl_handler_setup(&priv->ctrls.handler);
794 if (err) {
795 dev_err(&priv->client->dev, "Error %d setup controls\n", err);
796 return err;
797 }
798
Leon Luo0985dd32017-10-05 02:06:21 +0200799 /*
800 * Refer to "Standby Cancel Sequence when using CSI-2" in
801 * imx274 datasheet, it should wait 10ms or more here.
802 * give it 1 extra ms for margin
803 */
804 msleep_range(11);
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400805 err = imx274_write_table(priv, imx274_start_2);
Leon Luo0985dd32017-10-05 02:06:21 +0200806 if (err)
807 return err;
808
809 /*
810 * Refer to "Standby Cancel Sequence when using CSI-2" in
811 * imx274 datasheet, it should wait 7ms or more here.
812 * give it 1 extra ms for margin
813 */
814 msleep_range(8);
Luca Ceresoli7d2332c2018-08-24 12:35:20 -0400815 err = imx274_write_table(priv, imx274_start_3);
Leon Luo0985dd32017-10-05 02:06:21 +0200816 if (err)
817 return err;
818
819 return 0;
820}
821
822/*
823 * imx274_reset - Function called to reset the sensor
824 * @priv: Pointer to device structure
825 * @rst: Input value for determining the sensor's end state after reset
826 *
827 * Set the senor in reset and then
828 * if rst = 0, keep it in reset;
829 * if rst = 1, bring it out of reset.
830 *
831 */
832static void imx274_reset(struct stimx274 *priv, int rst)
833{
834 gpiod_set_value_cansleep(priv->reset_gpio, 0);
835 usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2);
836 gpiod_set_value_cansleep(priv->reset_gpio, !!rst);
837 usleep_range(IMX274_RESET_DELAY1, IMX274_RESET_DELAY2);
838}
839
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200840static int imx274_power_on(struct device *dev)
841{
842 struct i2c_client *client = to_i2c_client(dev);
843 struct v4l2_subdev *sd = i2c_get_clientdata(client);
844 struct stimx274 *imx274 = to_imx274(sd);
845 int ret;
846
847 /* keep sensor in reset before power on */
848 imx274_reset(imx274, 0);
849
850 ret = clk_prepare_enable(imx274->inck);
851 if (ret) {
852 dev_err(&imx274->client->dev,
853 "Failed to enable input clock: %d\n", ret);
854 return ret;
855 }
856
857 ret = regulator_bulk_enable(IMX274_NUM_SUPPLIES, imx274->supplies);
858 if (ret) {
859 dev_err(&imx274->client->dev,
860 "Failed to enable regulators: %d\n", ret);
861 goto fail_reg;
862 }
863
864 udelay(2);
865 imx274_reset(imx274, 1);
866
867 return 0;
868
869fail_reg:
870 clk_disable_unprepare(imx274->inck);
871 return ret;
872}
873
874static int imx274_power_off(struct device *dev)
875{
876 struct i2c_client *client = to_i2c_client(dev);
877 struct v4l2_subdev *sd = i2c_get_clientdata(client);
878 struct stimx274 *imx274 = to_imx274(sd);
879
880 imx274_reset(imx274, 0);
881
882 regulator_bulk_disable(IMX274_NUM_SUPPLIES, imx274->supplies);
883
884 clk_disable_unprepare(imx274->inck);
885
886 return 0;
887}
888
889static int imx274_regulators_get(struct device *dev, struct stimx274 *imx274)
890{
891 unsigned int i;
892
893 for (i = 0; i < IMX274_NUM_SUPPLIES; i++)
894 imx274->supplies[i].supply = imx274_supply_names[i];
895
896 return devm_regulator_bulk_get(dev, IMX274_NUM_SUPPLIES,
897 imx274->supplies);
898}
899
Leon Luo0985dd32017-10-05 02:06:21 +0200900/**
901 * imx274_s_ctrl - This is used to set the imx274 V4L2 controls
902 * @ctrl: V4L2 control to be set
903 *
904 * This function is used to set the V4L2 controls for the imx274 sensor.
905 *
906 * Return: 0 on success, errors otherwise
907 */
908static int imx274_s_ctrl(struct v4l2_ctrl *ctrl)
909{
910 struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
911 struct stimx274 *imx274 = to_imx274(sd);
912 int ret = -EINVAL;
913
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200914 if (!pm_runtime_get_if_in_use(&imx274->client->dev))
915 return 0;
916
Leon Luo0985dd32017-10-05 02:06:21 +0200917 dev_dbg(&imx274->client->dev,
918 "%s : s_ctrl: %s, value: %d\n", __func__,
919 ctrl->name, ctrl->val);
920
921 switch (ctrl->id) {
922 case V4L2_CID_EXPOSURE:
923 dev_dbg(&imx274->client->dev,
924 "%s : set V4L2_CID_EXPOSURE\n", __func__);
925 ret = imx274_set_exposure(imx274, ctrl->val);
926 break;
927
928 case V4L2_CID_GAIN:
929 dev_dbg(&imx274->client->dev,
930 "%s : set V4L2_CID_GAIN\n", __func__);
931 ret = imx274_set_gain(imx274, ctrl);
932 break;
933
934 case V4L2_CID_VFLIP:
935 dev_dbg(&imx274->client->dev,
936 "%s : set V4L2_CID_VFLIP\n", __func__);
937 ret = imx274_set_vflip(imx274, ctrl->val);
938 break;
939
940 case V4L2_CID_TEST_PATTERN:
941 dev_dbg(&imx274->client->dev,
942 "%s : set V4L2_CID_TEST_PATTERN\n", __func__);
943 ret = imx274_set_test_pattern(imx274, ctrl->val);
944 break;
945 }
946
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +0200947 pm_runtime_put(&imx274->client->dev);
948
Leon Luo0985dd32017-10-05 02:06:21 +0200949 return ret;
950}
951
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400952static int imx274_binning_goodness(struct stimx274 *imx274,
953 int w, int ask_w,
954 int h, int ask_h, u32 flags)
955{
956 struct device *dev = &imx274->client->dev;
957 const int goodness = 100000;
958 int val = 0;
959
960 if (flags & V4L2_SEL_FLAG_GE) {
961 if (w < ask_w)
962 val -= goodness;
963 if (h < ask_h)
964 val -= goodness;
965 }
966
967 if (flags & V4L2_SEL_FLAG_LE) {
968 if (w > ask_w)
969 val -= goodness;
970 if (h > ask_h)
971 val -= goodness;
972 }
973
974 val -= abs(w - ask_w);
975 val -= abs(h - ask_h);
976
977 dev_dbg(dev, "%s: ask %dx%d, size %dx%d, goodness %d\n",
978 __func__, ask_w, ask_h, w, h, val);
979
980 return val;
981}
982
983/**
Hans Verkuila4184b42021-03-03 13:55:10 +0100984 * __imx274_change_compose - Helper function to change binning and set both
985 * compose and format.
Luca Ceresoli39dd23d2018-07-25 12:24:55 -0400986 *
987 * We have two entry points to change binning: set_fmt and
988 * set_selection(COMPOSE). Both have to compute the new output size
989 * and set it in both the compose rect and the frame format size. We
990 * also need to do the same things after setting cropping to restore
991 * 1:1 binning.
992 *
993 * This function contains the common code for these three cases, it
994 * has many arguments in order to accommodate the needs of all of
995 * them.
996 *
997 * Must be called with imx274->lock locked.
998 *
999 * @imx274: The device object
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001000 * @sd_state: The subdev state we are editing for TRY requests
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001001 * @which: V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY from the caller
1002 * @width: Input-output parameter: set to the desired width before
1003 * the call, contains the chosen value after returning successfully
1004 * @height: Input-output parameter for height (see @width)
1005 * @flags: Selection flags from struct v4l2_subdev_selection, or 0 if not
1006 * available (when called from set_fmt)
1007 */
1008static int __imx274_change_compose(struct stimx274 *imx274,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001009 struct v4l2_subdev_state *sd_state,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001010 u32 which,
1011 u32 *width,
1012 u32 *height,
1013 u32 flags)
1014{
1015 struct device *dev = &imx274->client->dev;
1016 const struct v4l2_rect *cur_crop;
1017 struct v4l2_mbus_framefmt *tgt_fmt;
1018 unsigned int i;
Luca Ceresoli9648cb52018-08-24 12:35:22 -04001019 const struct imx274_mode *best_mode = &imx274_modes[0];
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001020 int best_goodness = INT_MIN;
1021
1022 if (which == V4L2_SUBDEV_FORMAT_TRY) {
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001023 cur_crop = &sd_state->pads->try_crop;
1024 tgt_fmt = &sd_state->pads->try_fmt;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001025 } else {
1026 cur_crop = &imx274->crop;
1027 tgt_fmt = &imx274->format;
1028 }
1029
Luca Ceresoli9648cb52018-08-24 12:35:22 -04001030 for (i = 0; i < ARRAY_SIZE(imx274_modes); i++) {
Eugen Hristevf70ad2a2020-09-15 11:04:42 +02001031 u8 wratio = imx274_modes[i].wbin_ratio;
1032 u8 hratio = imx274_modes[i].hbin_ratio;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001033
1034 int goodness = imx274_binning_goodness(
1035 imx274,
Eugen Hristevf70ad2a2020-09-15 11:04:42 +02001036 cur_crop->width / wratio, *width,
1037 cur_crop->height / hratio, *height,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001038 flags);
1039
1040 if (goodness >= best_goodness) {
1041 best_goodness = goodness;
Luca Ceresoli9648cb52018-08-24 12:35:22 -04001042 best_mode = &imx274_modes[i];
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001043 }
1044 }
1045
Eugen Hristevf70ad2a2020-09-15 11:04:42 +02001046 *width = cur_crop->width / best_mode->wbin_ratio;
1047 *height = cur_crop->height / best_mode->hbin_ratio;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001048
1049 if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
1050 imx274->mode = best_mode;
1051
Eugen Hristevf70ad2a2020-09-15 11:04:42 +02001052 dev_dbg(dev, "%s: selected %ux%u binning\n",
1053 __func__, best_mode->wbin_ratio, best_mode->hbin_ratio);
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001054
1055 tgt_fmt->width = *width;
1056 tgt_fmt->height = *height;
1057 tgt_fmt->field = V4L2_FIELD_NONE;
1058
1059 return 0;
1060}
1061
Leon Luo0985dd32017-10-05 02:06:21 +02001062/**
1063 * imx274_get_fmt - Get the pad format
1064 * @sd: Pointer to V4L2 Sub device structure
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001065 * @sd_state: Pointer to sub device state structure
Leon Luo0985dd32017-10-05 02:06:21 +02001066 * @fmt: Pointer to pad level media bus format
1067 *
1068 * This function is used to get the pad format information.
1069 *
1070 * Return: 0 on success
1071 */
1072static int imx274_get_fmt(struct v4l2_subdev *sd,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001073 struct v4l2_subdev_state *sd_state,
Leon Luo0985dd32017-10-05 02:06:21 +02001074 struct v4l2_subdev_format *fmt)
1075{
1076 struct stimx274 *imx274 = to_imx274(sd);
1077
1078 mutex_lock(&imx274->lock);
1079 fmt->format = imx274->format;
1080 mutex_unlock(&imx274->lock);
1081 return 0;
1082}
1083
1084/**
1085 * imx274_set_fmt - This is used to set the pad format
1086 * @sd: Pointer to V4L2 Sub device structure
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001087 * @sd_state: Pointer to sub device state information structure
Leon Luo0985dd32017-10-05 02:06:21 +02001088 * @format: Pointer to pad level media bus format
1089 *
1090 * This function is used to set the pad format.
1091 *
1092 * Return: 0 on success
1093 */
1094static int imx274_set_fmt(struct v4l2_subdev *sd,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001095 struct v4l2_subdev_state *sd_state,
Leon Luo0985dd32017-10-05 02:06:21 +02001096 struct v4l2_subdev_format *format)
1097{
1098 struct v4l2_mbus_framefmt *fmt = &format->format;
1099 struct stimx274 *imx274 = to_imx274(sd);
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001100 int err = 0;
Leon Luo0985dd32017-10-05 02:06:21 +02001101
1102 mutex_lock(&imx274->lock);
1103
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001104 err = __imx274_change_compose(imx274, sd_state, format->which,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001105 &fmt->width, &fmt->height, 0);
Leon Luo0985dd32017-10-05 02:06:21 +02001106
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001107 if (err)
1108 goto out;
Leon Luo0985dd32017-10-05 02:06:21 +02001109
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001110 /*
1111 * __imx274_change_compose already set width and height in the
1112 * applicable format, but we need to keep all other format
1113 * values, so do a full copy here
1114 */
Leon Luo0985dd32017-10-05 02:06:21 +02001115 fmt->field = V4L2_FIELD_NONE;
Leon Luo0985dd32017-10-05 02:06:21 +02001116 if (format->which == V4L2_SUBDEV_FORMAT_TRY)
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001117 sd_state->pads->try_fmt = *fmt;
Leon Luo0985dd32017-10-05 02:06:21 +02001118 else
1119 imx274->format = *fmt;
1120
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001121out:
Leon Luo0985dd32017-10-05 02:06:21 +02001122 mutex_unlock(&imx274->lock);
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001123
1124 return err;
1125}
1126
1127static int imx274_get_selection(struct v4l2_subdev *sd,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001128 struct v4l2_subdev_state *sd_state,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001129 struct v4l2_subdev_selection *sel)
1130{
1131 struct stimx274 *imx274 = to_imx274(sd);
1132 const struct v4l2_rect *src_crop;
1133 const struct v4l2_mbus_framefmt *src_fmt;
1134 int ret = 0;
1135
1136 if (sel->pad != 0)
1137 return -EINVAL;
1138
1139 if (sel->target == V4L2_SEL_TGT_CROP_BOUNDS) {
1140 sel->r.left = 0;
1141 sel->r.top = 0;
1142 sel->r.width = IMX274_MAX_WIDTH;
1143 sel->r.height = IMX274_MAX_HEIGHT;
1144 return 0;
1145 }
1146
1147 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001148 src_crop = &sd_state->pads->try_crop;
1149 src_fmt = &sd_state->pads->try_fmt;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001150 } else {
1151 src_crop = &imx274->crop;
1152 src_fmt = &imx274->format;
1153 }
1154
1155 mutex_lock(&imx274->lock);
1156
1157 switch (sel->target) {
1158 case V4L2_SEL_TGT_CROP:
1159 sel->r = *src_crop;
1160 break;
1161 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1162 sel->r.top = 0;
1163 sel->r.left = 0;
1164 sel->r.width = src_crop->width;
1165 sel->r.height = src_crop->height;
1166 break;
1167 case V4L2_SEL_TGT_COMPOSE:
1168 sel->r.top = 0;
1169 sel->r.left = 0;
1170 sel->r.width = src_fmt->width;
1171 sel->r.height = src_fmt->height;
1172 break;
1173 default:
1174 ret = -EINVAL;
1175 }
1176
1177 mutex_unlock(&imx274->lock);
1178
1179 return ret;
1180}
1181
1182static int imx274_set_selection_crop(struct stimx274 *imx274,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001183 struct v4l2_subdev_state *sd_state,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001184 struct v4l2_subdev_selection *sel)
1185{
1186 struct v4l2_rect *tgt_crop;
1187 struct v4l2_rect new_crop;
1188 bool size_changed;
1189
1190 /*
1191 * h_step could be 12 or 24 depending on the binning. But we
1192 * won't know the binning until we choose the mode later in
1193 * __imx274_change_compose(). Thus let's be safe and use the
1194 * most conservative value in all cases.
1195 */
1196 const u32 h_step = 24;
1197
1198 new_crop.width = min_t(u32,
1199 IMX274_ROUND(sel->r.width, h_step, sel->flags),
1200 IMX274_MAX_WIDTH);
1201
1202 /* Constraint: HTRIMMING_END - HTRIMMING_START >= 144 */
1203 if (new_crop.width < 144)
1204 new_crop.width = 144;
1205
1206 new_crop.left = min_t(u32,
1207 IMX274_ROUND(sel->r.left, h_step, 0),
1208 IMX274_MAX_WIDTH - new_crop.width);
1209
1210 new_crop.height = min_t(u32,
1211 IMX274_ROUND(sel->r.height, 2, sel->flags),
1212 IMX274_MAX_HEIGHT);
1213
1214 new_crop.top = min_t(u32, IMX274_ROUND(sel->r.top, 2, 0),
1215 IMX274_MAX_HEIGHT - new_crop.height);
1216
1217 sel->r = new_crop;
1218
1219 if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001220 tgt_crop = &sd_state->pads->try_crop;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001221 else
1222 tgt_crop = &imx274->crop;
1223
1224 mutex_lock(&imx274->lock);
1225
1226 size_changed = (new_crop.width != tgt_crop->width ||
1227 new_crop.height != tgt_crop->height);
1228
1229 /* __imx274_change_compose needs the new size in *tgt_crop */
1230 *tgt_crop = new_crop;
1231
1232 /* if crop size changed then reset the output image size */
1233 if (size_changed)
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001234 __imx274_change_compose(imx274, sd_state, sel->which,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001235 &new_crop.width, &new_crop.height,
1236 sel->flags);
1237
1238 mutex_unlock(&imx274->lock);
1239
Leon Luo0985dd32017-10-05 02:06:21 +02001240 return 0;
1241}
1242
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001243static int imx274_set_selection(struct v4l2_subdev *sd,
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001244 struct v4l2_subdev_state *sd_state,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001245 struct v4l2_subdev_selection *sel)
1246{
1247 struct stimx274 *imx274 = to_imx274(sd);
1248
1249 if (sel->pad != 0)
1250 return -EINVAL;
1251
1252 if (sel->target == V4L2_SEL_TGT_CROP)
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001253 return imx274_set_selection_crop(imx274, sd_state, sel);
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001254
1255 if (sel->target == V4L2_SEL_TGT_COMPOSE) {
1256 int err;
1257
1258 mutex_lock(&imx274->lock);
Tomi Valkeinen0d346d22021-06-10 17:55:58 +03001259 err = __imx274_change_compose(imx274, sd_state, sel->which,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001260 &sel->r.width, &sel->r.height,
1261 sel->flags);
1262 mutex_unlock(&imx274->lock);
1263
1264 /*
1265 * __imx274_change_compose already set width and
1266 * height in set->r, we still need to set top-left
1267 */
1268 if (!err) {
1269 sel->r.top = 0;
1270 sel->r.left = 0;
1271 }
1272
1273 return err;
1274 }
1275
1276 return -EINVAL;
1277}
1278
1279static int imx274_apply_trimming(struct stimx274 *imx274)
1280{
1281 u32 h_start;
1282 u32 h_end;
1283 u32 hmax;
1284 u32 v_cut;
1285 s32 v_pos;
1286 u32 write_v_size;
1287 u32 y_out_size;
1288 int err;
1289
1290 h_start = imx274->crop.left + 12;
1291 h_end = h_start + imx274->crop.width;
1292
1293 /* Use the minimum allowed value of HMAX */
1294 /* Note: except in mode 1, (width / 16 + 23) is always < hmax_min */
1295 /* Note: 260 is the minimum HMAX in all implemented modes */
1296 hmax = max_t(u32, 260, (imx274->crop.width) / 16 + 23);
1297
1298 /* invert v_pos if VFLIP */
1299 v_pos = imx274->ctrls.vflip->cur.val ?
1300 (-imx274->crop.top / 2) : (imx274->crop.top / 2);
1301 v_cut = (IMX274_MAX_HEIGHT - imx274->crop.height) / 2;
1302 write_v_size = imx274->crop.height + 22;
Sowjanya Komatinenic87bfb62020-09-21 23:39:37 +02001303 y_out_size = imx274->crop.height;
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001304
1305 err = imx274_write_mbreg(imx274, IMX274_HMAX_REG_LSB, hmax, 2);
1306 if (!err)
1307 err = imx274_write_mbreg(imx274, IMX274_HTRIM_EN_REG, 1, 1);
1308 if (!err)
1309 err = imx274_write_mbreg(imx274, IMX274_HTRIM_START_REG_LSB,
1310 h_start, 2);
1311 if (!err)
1312 err = imx274_write_mbreg(imx274, IMX274_HTRIM_END_REG_LSB,
1313 h_end, 2);
1314 if (!err)
1315 err = imx274_write_mbreg(imx274, IMX274_VWIDCUTEN_REG, 1, 1);
1316 if (!err)
1317 err = imx274_write_mbreg(imx274, IMX274_VWIDCUT_REG_LSB,
1318 v_cut, 2);
1319 if (!err)
1320 err = imx274_write_mbreg(imx274, IMX274_VWINPOS_REG_LSB,
1321 v_pos, 2);
1322 if (!err)
1323 err = imx274_write_mbreg(imx274, IMX274_WRITE_VSIZE_REG_LSB,
1324 write_v_size, 2);
1325 if (!err)
1326 err = imx274_write_mbreg(imx274, IMX274_Y_OUT_SIZE_REG_LSB,
1327 y_out_size, 2);
1328
1329 return err;
1330}
1331
Leon Luo0985dd32017-10-05 02:06:21 +02001332/**
1333 * imx274_g_frame_interval - Get the frame interval
1334 * @sd: Pointer to V4L2 Sub device structure
1335 * @fi: Pointer to V4l2 Sub device frame interval structure
1336 *
1337 * This function is used to get the frame interval.
1338 *
1339 * Return: 0 on success
1340 */
1341static int imx274_g_frame_interval(struct v4l2_subdev *sd,
1342 struct v4l2_subdev_frame_interval *fi)
1343{
1344 struct stimx274 *imx274 = to_imx274(sd);
1345
1346 fi->interval = imx274->frame_interval;
1347 dev_dbg(&imx274->client->dev, "%s frame rate = %d / %d\n",
1348 __func__, imx274->frame_interval.numerator,
1349 imx274->frame_interval.denominator);
1350
1351 return 0;
1352}
1353
1354/**
1355 * imx274_s_frame_interval - Set the frame interval
1356 * @sd: Pointer to V4L2 Sub device structure
1357 * @fi: Pointer to V4l2 Sub device frame interval structure
1358 *
1359 * This function is used to set the frame intervavl.
1360 *
1361 * Return: 0 on success
1362 */
1363static int imx274_s_frame_interval(struct v4l2_subdev *sd,
1364 struct v4l2_subdev_frame_interval *fi)
1365{
1366 struct stimx274 *imx274 = to_imx274(sd);
1367 struct v4l2_ctrl *ctrl = imx274->ctrls.exposure;
1368 int min, max, def;
1369 int ret;
1370
Eugen Hristevda653492021-11-17 16:40:09 +01001371 ret = pm_runtime_resume_and_get(&imx274->client->dev);
1372 if (ret < 0)
1373 return ret;
1374
Leon Luo0985dd32017-10-05 02:06:21 +02001375 mutex_lock(&imx274->lock);
1376 ret = imx274_set_frame_interval(imx274, fi->interval);
1377
1378 if (!ret) {
Hans Verkuil49b20d92020-07-03 11:20:32 +02001379 fi->interval = imx274->frame_interval;
1380
Leon Luo0985dd32017-10-05 02:06:21 +02001381 /*
1382 * exposure time range is decided by frame interval
Luca Ceresoli01343392018-04-24 04:24:07 -04001383 * need to update it after frame interval changes
Leon Luo0985dd32017-10-05 02:06:21 +02001384 */
1385 min = IMX274_MIN_EXPOSURE_TIME;
1386 max = fi->interval.numerator * 1000000
1387 / fi->interval.denominator;
1388 def = max;
Jia-Ju Bai9a4619e2021-03-05 04:19:42 +01001389 ret = __v4l2_ctrl_modify_range(ctrl, min, max, 1, def);
1390 if (ret) {
Leon Luo0985dd32017-10-05 02:06:21 +02001391 dev_err(&imx274->client->dev,
1392 "Exposure ctrl range update failed\n");
1393 goto unlock;
1394 }
1395
1396 /* update exposure time accordingly */
Luca Ceresolicf908702018-04-24 04:24:08 -04001397 imx274_set_exposure(imx274, ctrl->val);
Leon Luo0985dd32017-10-05 02:06:21 +02001398
1399 dev_dbg(&imx274->client->dev, "set frame interval to %uus\n",
1400 fi->interval.numerator * 1000000
1401 / fi->interval.denominator);
1402 }
1403
1404unlock:
1405 mutex_unlock(&imx274->lock);
Eugen Hristevda653492021-11-17 16:40:09 +01001406 pm_runtime_put(&imx274->client->dev);
Leon Luo0985dd32017-10-05 02:06:21 +02001407
1408 return ret;
1409}
1410
1411/**
1412 * imx274_load_default - load default control values
1413 * @priv: Pointer to device structure
1414 *
1415 * Return: 0 on success, errors otherwise
1416 */
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02001417static void imx274_load_default(struct stimx274 *priv)
Leon Luo0985dd32017-10-05 02:06:21 +02001418{
Leon Luo0985dd32017-10-05 02:06:21 +02001419 /* load default control values */
1420 priv->frame_interval.numerator = 1;
1421 priv->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
1422 priv->ctrls.exposure->val = 1000000 / IMX274_DEF_FRAME_RATE;
1423 priv->ctrls.gain->val = IMX274_DEF_GAIN;
1424 priv->ctrls.vflip->val = 0;
1425 priv->ctrls.test_pattern->val = TEST_PATTERN_DISABLED;
Leon Luo0985dd32017-10-05 02:06:21 +02001426}
1427
1428/**
1429 * imx274_s_stream - It is used to start/stop the streaming.
1430 * @sd: V4L2 Sub device
1431 * @on: Flag (True / False)
1432 *
1433 * This function controls the start or stop of streaming for the
1434 * imx274 sensor.
1435 *
1436 * Return: 0 on success, errors otherwise
1437 */
1438static int imx274_s_stream(struct v4l2_subdev *sd, int on)
1439{
1440 struct stimx274 *imx274 = to_imx274(sd);
1441 int ret = 0;
1442
Luca Ceresoli43173222018-06-11 07:35:34 -04001443 dev_dbg(&imx274->client->dev, "%s : %s, mode index = %td\n", __func__,
1444 on ? "Stream Start" : "Stream Stop",
Luca Ceresoli9648cb52018-08-24 12:35:22 -04001445 imx274->mode - &imx274_modes[0]);
Leon Luo0985dd32017-10-05 02:06:21 +02001446
1447 mutex_lock(&imx274->lock);
1448
1449 if (on) {
Mauro Carvalho Chehabbb94b8f2021-04-23 17:19:13 +02001450 ret = pm_runtime_resume_and_get(&imx274->client->dev);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02001451 if (ret < 0) {
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02001452 mutex_unlock(&imx274->lock);
1453 return ret;
1454 }
1455
Leon Luo0985dd32017-10-05 02:06:21 +02001456 /* load mode registers */
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001457 ret = imx274_mode_regs(imx274);
Leon Luo0985dd32017-10-05 02:06:21 +02001458 if (ret)
1459 goto fail;
1460
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001461 ret = imx274_apply_trimming(imx274);
1462 if (ret)
1463 goto fail;
1464
Leon Luo0985dd32017-10-05 02:06:21 +02001465 /*
Eugen Hristev4e05d5f2021-11-18 08:17:15 +01001466 * update frame rate & exposure. if the last mode is different,
Leon Luo0985dd32017-10-05 02:06:21 +02001467 * HMAX could be changed. As the result, frame rate & exposure
1468 * are changed.
1469 * gain is not affected.
1470 */
1471 ret = imx274_set_frame_interval(imx274,
1472 imx274->frame_interval);
1473 if (ret)
1474 goto fail;
1475
Leon Luo0985dd32017-10-05 02:06:21 +02001476 /* start stream */
1477 ret = imx274_start_stream(imx274);
1478 if (ret)
1479 goto fail;
1480 } else {
1481 /* stop stream */
Luca Ceresoli8ed8bba702018-04-24 04:24:11 -04001482 ret = imx274_write_table(imx274, imx274_stop);
Leon Luo0985dd32017-10-05 02:06:21 +02001483 if (ret)
1484 goto fail;
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02001485
1486 pm_runtime_put(&imx274->client->dev);
Leon Luo0985dd32017-10-05 02:06:21 +02001487 }
1488
1489 mutex_unlock(&imx274->lock);
Luca Ceresoli43173222018-06-11 07:35:34 -04001490 dev_dbg(&imx274->client->dev, "%s : Done\n", __func__);
Leon Luo0985dd32017-10-05 02:06:21 +02001491 return 0;
1492
1493fail:
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02001494 pm_runtime_put(&imx274->client->dev);
Leon Luo0985dd32017-10-05 02:06:21 +02001495 mutex_unlock(&imx274->lock);
1496 dev_err(&imx274->client->dev, "s_stream failed\n");
1497 return ret;
1498}
1499
1500/*
1501 * imx274_get_frame_length - Function for obtaining current frame length
1502 * @priv: Pointer to device structure
Eugen Hristev358ed662021-11-18 13:51:51 +01001503 * @val: Pointer to obtained value
Leon Luo0985dd32017-10-05 02:06:21 +02001504 *
1505 * frame_length = vmax x (svr + 1), in unit of hmax.
1506 *
1507 * Return: 0 on success
1508 */
1509static int imx274_get_frame_length(struct stimx274 *priv, u32 *val)
1510{
1511 int err;
Luca Ceresolica0174672018-08-24 12:35:24 -04001512 u32 svr;
Leon Luo0985dd32017-10-05 02:06:21 +02001513 u32 vmax;
Leon Luo0985dd32017-10-05 02:06:21 +02001514
Luca Ceresolica0174672018-08-24 12:35:24 -04001515 err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
Leon Luo0985dd32017-10-05 02:06:21 +02001516 if (err)
1517 goto fail;
1518
Luca Ceresolica0174672018-08-24 12:35:24 -04001519 err = imx274_read_mbreg(priv, IMX274_VMAX_REG_3, &vmax, 3);
Leon Luo0985dd32017-10-05 02:06:21 +02001520 if (err)
1521 goto fail;
1522
Leon Luo0985dd32017-10-05 02:06:21 +02001523 *val = vmax * (svr + 1);
1524
1525 return 0;
1526
1527fail:
1528 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1529 return err;
1530}
1531
1532static int imx274_clamp_coarse_time(struct stimx274 *priv, u32 *val,
1533 u32 *frame_length)
1534{
1535 int err;
1536
1537 err = imx274_get_frame_length(priv, frame_length);
1538 if (err)
1539 return err;
1540
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001541 if (*frame_length < priv->mode->min_frame_len)
1542 *frame_length = priv->mode->min_frame_len;
Leon Luo0985dd32017-10-05 02:06:21 +02001543
1544 *val = *frame_length - *val; /* convert to raw shr */
1545 if (*val > *frame_length - IMX274_SHR_LIMIT_CONST)
1546 *val = *frame_length - IMX274_SHR_LIMIT_CONST;
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001547 else if (*val < priv->mode->min_SHR)
1548 *val = priv->mode->min_SHR;
Leon Luo0985dd32017-10-05 02:06:21 +02001549
1550 return 0;
1551}
1552
1553/*
1554 * imx274_set_digital gain - Function called when setting digital gain
1555 * @priv: Pointer to device structure
1556 * @dgain: Value of digital gain.
1557 *
1558 * Digital gain has only 4 steps: 1x, 2x, 4x, and 8x
1559 *
1560 * Return: 0 on success
1561 */
1562static int imx274_set_digital_gain(struct stimx274 *priv, u32 dgain)
1563{
1564 u8 reg_val;
1565
1566 reg_val = ffs(dgain);
1567
1568 if (reg_val)
1569 reg_val--;
1570
1571 reg_val = clamp(reg_val, (u8)0, (u8)3);
1572
1573 return imx274_write_reg(priv, IMX274_DIGITAL_GAIN_REG,
1574 reg_val & IMX274_MASK_LSB_4_BITS);
1575}
1576
Leon Luo0985dd32017-10-05 02:06:21 +02001577/*
1578 * imx274_set_gain - Function called when setting gain
1579 * @priv: Pointer to device structure
1580 * @val: Value of gain. the real value = val << IMX274_GAIN_SHIFT;
1581 * @ctrl: v4l2 control pointer
1582 *
1583 * Set the gain based on input value.
1584 * The caller should hold the mutex lock imx274->lock if necessary
1585 *
1586 * Return: 0 on success
1587 */
1588static int imx274_set_gain(struct stimx274 *priv, struct v4l2_ctrl *ctrl)
1589{
Leon Luo0985dd32017-10-05 02:06:21 +02001590 int err;
1591 u32 gain, analog_gain, digital_gain, gain_reg;
Leon Luo0985dd32017-10-05 02:06:21 +02001592
1593 gain = (u32)(ctrl->val);
1594
1595 dev_dbg(&priv->client->dev,
1596 "%s : input gain = %d.%d\n", __func__,
1597 gain >> IMX274_GAIN_SHIFT,
1598 ((gain & IMX274_GAIN_SHIFT_MASK) * 100) >> IMX274_GAIN_SHIFT);
1599
1600 if (gain > IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN)
1601 gain = IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN;
1602 else if (gain < IMX274_MIN_GAIN)
1603 gain = IMX274_MIN_GAIN;
1604
1605 if (gain <= IMX274_MAX_ANALOG_GAIN)
1606 digital_gain = 1;
1607 else if (gain <= IMX274_MAX_ANALOG_GAIN * 2)
1608 digital_gain = 2;
1609 else if (gain <= IMX274_MAX_ANALOG_GAIN * 4)
1610 digital_gain = 4;
1611 else
1612 digital_gain = IMX274_MAX_DIGITAL_GAIN;
1613
1614 analog_gain = gain / digital_gain;
1615
1616 dev_dbg(&priv->client->dev,
1617 "%s : digital gain = %d, analog gain = %d.%d\n",
1618 __func__, digital_gain, analog_gain >> IMX274_GAIN_SHIFT,
1619 ((analog_gain & IMX274_GAIN_SHIFT_MASK) * 100)
1620 >> IMX274_GAIN_SHIFT);
1621
1622 err = imx274_set_digital_gain(priv, digital_gain);
1623 if (err)
1624 goto fail;
1625
1626 /* convert to register value, refer to imx274 datasheet */
1627 gain_reg = (u32)IMX274_GAIN_CONST -
1628 (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT) / analog_gain;
1629 if (gain_reg > IMX274_GAIN_REG_MAX)
1630 gain_reg = IMX274_GAIN_REG_MAX;
1631
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -04001632 err = imx274_write_mbreg(priv, IMX274_ANALOG_GAIN_ADDR_LSB, gain_reg,
1633 2);
1634 if (err)
1635 goto fail;
Leon Luo0985dd32017-10-05 02:06:21 +02001636
1637 if (IMX274_GAIN_CONST - gain_reg == 0) {
1638 err = -EINVAL;
1639 goto fail;
1640 }
1641
1642 /* convert register value back to gain value */
1643 ctrl->val = (IMX274_GAIN_CONST << IMX274_GAIN_SHIFT)
1644 / (IMX274_GAIN_CONST - gain_reg) * digital_gain;
1645
1646 dev_dbg(&priv->client->dev,
1647 "%s : GAIN control success, gain_reg = %d, new gain = %d\n",
1648 __func__, gain_reg, ctrl->val);
1649
1650 return 0;
1651
1652fail:
1653 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1654 return err;
1655}
1656
Leon Luo0985dd32017-10-05 02:06:21 +02001657/*
1658 * imx274_set_coarse_time - Function called when setting SHR value
1659 * @priv: Pointer to device structure
1660 * @val: Value for exposure time in number of line_length, or [HMAX]
1661 *
1662 * Set SHR value based on input value.
1663 *
1664 * Return: 0 on success
1665 */
1666static int imx274_set_coarse_time(struct stimx274 *priv, u32 *val)
1667{
Leon Luo0985dd32017-10-05 02:06:21 +02001668 int err;
1669 u32 coarse_time, frame_length;
Leon Luo0985dd32017-10-05 02:06:21 +02001670
1671 coarse_time = *val;
1672
1673 /* convert exposure_time to appropriate SHR value */
1674 err = imx274_clamp_coarse_time(priv, &coarse_time, &frame_length);
1675 if (err)
1676 goto fail;
1677
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -04001678 err = imx274_write_mbreg(priv, IMX274_SHR_REG_LSB, coarse_time, 2);
1679 if (err)
1680 goto fail;
Leon Luo0985dd32017-10-05 02:06:21 +02001681
1682 *val = frame_length - coarse_time;
1683 return 0;
1684
1685fail:
1686 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1687 return err;
1688}
1689
1690/*
1691 * imx274_set_exposure - Function called when setting exposure time
1692 * @priv: Pointer to device structure
1693 * @val: Variable for exposure time, in the unit of micro-second
1694 *
1695 * Set exposure time based on input value.
1696 * The caller should hold the mutex lock imx274->lock if necessary
1697 *
1698 * Return: 0 on success
1699 */
1700static int imx274_set_exposure(struct stimx274 *priv, int val)
1701{
1702 int err;
Luca Ceresolica0174672018-08-24 12:35:24 -04001703 u32 hmax;
Leon Luo0985dd32017-10-05 02:06:21 +02001704 u32 coarse_time; /* exposure time in unit of line (HMAX)*/
1705
1706 dev_dbg(&priv->client->dev,
1707 "%s : EXPOSURE control input = %d\n", __func__, val);
1708
1709 /* step 1: convert input exposure_time (val) into number of 1[HMAX] */
1710
Luca Ceresolica0174672018-08-24 12:35:24 -04001711 err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
Leon Luo0985dd32017-10-05 02:06:21 +02001712 if (err)
1713 goto fail;
Luca Ceresolica0174672018-08-24 12:35:24 -04001714
Leon Luo0985dd32017-10-05 02:06:21 +02001715 if (hmax == 0) {
1716 err = -EINVAL;
1717 goto fail;
1718 }
1719
1720 coarse_time = (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2 * val
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001721 - priv->mode->nocpiop) / hmax;
Leon Luo0985dd32017-10-05 02:06:21 +02001722
1723 /* step 2: convert exposure_time into SHR value */
1724
1725 /* set SHR */
1726 err = imx274_set_coarse_time(priv, &coarse_time);
1727 if (err)
1728 goto fail;
1729
1730 priv->ctrls.exposure->val =
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001731 (coarse_time * hmax + priv->mode->nocpiop)
Leon Luo0985dd32017-10-05 02:06:21 +02001732 / (IMX274_PIXCLK_CONST1 / IMX274_PIXCLK_CONST2);
1733
1734 dev_dbg(&priv->client->dev,
1735 "%s : EXPOSURE control success\n", __func__);
1736 return 0;
1737
1738fail:
1739 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1740
1741 return err;
1742}
1743
1744/*
1745 * imx274_set_vflip - Function called when setting vertical flip
1746 * @priv: Pointer to device structure
1747 * @val: Value for vflip setting
1748 *
1749 * Set vertical flip based on input value.
1750 * val = 0: normal, no vertical flip
1751 * val = 1: vertical flip enabled
1752 * The caller should hold the mutex lock imx274->lock if necessary
1753 *
1754 * Return: 0 on success
1755 */
1756static int imx274_set_vflip(struct stimx274 *priv, int val)
1757{
1758 int err;
1759
1760 err = imx274_write_reg(priv, IMX274_VFLIP_REG, val);
1761 if (err) {
Luca Ceresoli9f67a5e2018-02-23 03:57:15 -05001762 dev_err(&priv->client->dev, "VFLIP control error\n");
Leon Luo0985dd32017-10-05 02:06:21 +02001763 return err;
1764 }
1765
1766 dev_dbg(&priv->client->dev,
1767 "%s : VFLIP control success\n", __func__);
1768
1769 return 0;
1770}
1771
1772/*
1773 * imx274_set_test_pattern - Function called when setting test pattern
1774 * @priv: Pointer to device structure
1775 * @val: Variable for test pattern
1776 *
1777 * Set to different test patterns based on input value.
1778 *
1779 * Return: 0 on success
1780 */
1781static int imx274_set_test_pattern(struct stimx274 *priv, int val)
1782{
1783 int err = 0;
1784
1785 if (val == TEST_PATTERN_DISABLED) {
1786 err = imx274_write_table(priv, imx274_tp_disabled);
1787 } else if (val <= TEST_PATTERN_V_COLOR_BARS) {
1788 err = imx274_write_reg(priv, IMX274_TEST_PATTERN_REG, val - 1);
1789 if (!err)
1790 err = imx274_write_table(priv, imx274_tp_regs);
1791 } else {
1792 err = -EINVAL;
1793 }
1794
1795 if (!err)
1796 dev_dbg(&priv->client->dev,
1797 "%s : TEST PATTERN control success\n", __func__);
1798 else
1799 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1800
1801 return err;
1802}
1803
Leon Luo0985dd32017-10-05 02:06:21 +02001804/*
1805 * imx274_set_frame_length - Function called when setting frame length
1806 * @priv: Pointer to device structure
1807 * @val: Variable for frame length (= VMAX, i.e. vertical drive period length)
1808 *
1809 * Set frame length based on input value.
1810 *
1811 * Return: 0 on success
1812 */
1813static int imx274_set_frame_length(struct stimx274 *priv, u32 val)
1814{
Leon Luo0985dd32017-10-05 02:06:21 +02001815 int err;
1816 u32 frame_length;
Leon Luo0985dd32017-10-05 02:06:21 +02001817
1818 dev_dbg(&priv->client->dev, "%s : input length = %d\n",
1819 __func__, val);
1820
1821 frame_length = (u32)val;
1822
Luca Ceresoli279b4b9a2018-07-25 12:24:54 -04001823 err = imx274_write_mbreg(priv, IMX274_VMAX_REG_3, frame_length, 3);
1824 if (err)
1825 goto fail;
Leon Luo0985dd32017-10-05 02:06:21 +02001826
1827 return 0;
1828
1829fail:
1830 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1831 return err;
1832}
1833
1834/*
1835 * imx274_set_frame_interval - Function called when setting frame interval
1836 * @priv: Pointer to device structure
1837 * @frame_interval: Variable for frame interval
1838 *
1839 * Change frame interval by updating VMAX value
1840 * The caller should hold the mutex lock imx274->lock if necessary
1841 *
1842 * Return: 0 on success
1843 */
1844static int imx274_set_frame_interval(struct stimx274 *priv,
1845 struct v4l2_fract frame_interval)
1846{
1847 int err;
1848 u32 frame_length, req_frame_rate;
Luca Ceresolica0174672018-08-24 12:35:24 -04001849 u32 svr;
1850 u32 hmax;
Leon Luo0985dd32017-10-05 02:06:21 +02001851
1852 dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d",
1853 __func__, frame_interval.numerator,
1854 frame_interval.denominator);
1855
Hans Verkuil49b20d92020-07-03 11:20:32 +02001856 if (frame_interval.numerator == 0 || frame_interval.denominator == 0) {
1857 frame_interval.denominator = IMX274_DEF_FRAME_RATE;
1858 frame_interval.numerator = 1;
Leon Luo0985dd32017-10-05 02:06:21 +02001859 }
1860
1861 req_frame_rate = (u32)(frame_interval.denominator
1862 / frame_interval.numerator);
1863
1864 /* boundary check */
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001865 if (req_frame_rate > priv->mode->max_fps) {
Leon Luo0985dd32017-10-05 02:06:21 +02001866 frame_interval.numerator = 1;
Luca Ceresoli96a2c732018-06-11 07:35:33 -04001867 frame_interval.denominator = priv->mode->max_fps;
Leon Luo0985dd32017-10-05 02:06:21 +02001868 } else if (req_frame_rate < IMX274_MIN_FRAME_RATE) {
1869 frame_interval.numerator = 1;
1870 frame_interval.denominator = IMX274_MIN_FRAME_RATE;
1871 }
1872
1873 /*
1874 * VMAX = 1/frame_rate x 72M / (SVR+1) / HMAX
1875 * frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX
1876 */
1877
Luca Ceresolica0174672018-08-24 12:35:24 -04001878 err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2);
Leon Luo0985dd32017-10-05 02:06:21 +02001879 if (err)
1880 goto fail;
Luca Ceresolica0174672018-08-24 12:35:24 -04001881
Leon Luo0985dd32017-10-05 02:06:21 +02001882 dev_dbg(&priv->client->dev,
1883 "%s : register SVR = %d\n", __func__, svr);
1884
Luca Ceresolica0174672018-08-24 12:35:24 -04001885 err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2);
Leon Luo0985dd32017-10-05 02:06:21 +02001886 if (err)
1887 goto fail;
Luca Ceresolica0174672018-08-24 12:35:24 -04001888
Leon Luo0985dd32017-10-05 02:06:21 +02001889 dev_dbg(&priv->client->dev,
1890 "%s : register HMAX = %d\n", __func__, hmax);
1891
1892 if (hmax == 0 || frame_interval.denominator == 0) {
1893 err = -EINVAL;
1894 goto fail;
1895 }
1896
1897 frame_length = IMX274_PIXCLK_CONST1 / (svr + 1) / hmax
1898 * frame_interval.numerator
1899 / frame_interval.denominator;
1900
1901 err = imx274_set_frame_length(priv, frame_length);
1902 if (err)
1903 goto fail;
1904
1905 priv->frame_interval = frame_interval;
1906 return 0;
1907
1908fail:
1909 dev_err(&priv->client->dev, "%s error = %d\n", __func__, err);
1910 return err;
1911}
1912
Eugen Hristev72189052021-11-18 16:40:09 +01001913static int imx274_enum_mbus_code(struct v4l2_subdev *sd,
1914 struct v4l2_subdev_state *sd_state,
1915 struct v4l2_subdev_mbus_code_enum *code)
1916{
1917 if (code->index > 0)
1918 return -EINVAL;
1919
1920 /* only supported format in the driver is Raw 10 bits SRGGB */
1921 code->code = MEDIA_BUS_FMT_SRGGB10_1X10;
1922
1923 return 0;
1924}
1925
Leon Luo0985dd32017-10-05 02:06:21 +02001926static const struct v4l2_subdev_pad_ops imx274_pad_ops = {
Eugen Hristev72189052021-11-18 16:40:09 +01001927 .enum_mbus_code = imx274_enum_mbus_code,
Leon Luo0985dd32017-10-05 02:06:21 +02001928 .get_fmt = imx274_get_fmt,
1929 .set_fmt = imx274_set_fmt,
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04001930 .get_selection = imx274_get_selection,
1931 .set_selection = imx274_set_selection,
Leon Luo0985dd32017-10-05 02:06:21 +02001932};
1933
1934static const struct v4l2_subdev_video_ops imx274_video_ops = {
1935 .g_frame_interval = imx274_g_frame_interval,
1936 .s_frame_interval = imx274_s_frame_interval,
1937 .s_stream = imx274_s_stream,
1938};
1939
1940static const struct v4l2_subdev_ops imx274_subdev_ops = {
1941 .pad = &imx274_pad_ops,
1942 .video = &imx274_video_ops,
1943};
1944
1945static const struct v4l2_ctrl_ops imx274_ctrl_ops = {
1946 .s_ctrl = imx274_s_ctrl,
1947};
1948
1949static const struct of_device_id imx274_of_id_table[] = {
1950 { .compatible = "sony,imx274" },
1951 { }
1952};
1953MODULE_DEVICE_TABLE(of, imx274_of_id_table);
1954
1955static const struct i2c_device_id imx274_id[] = {
1956 { "IMX274", 0 },
1957 { }
1958};
1959MODULE_DEVICE_TABLE(i2c, imx274_id);
1960
Eugen Hristev0abb8f92021-11-23 13:04:21 +01001961static int imx274_fwnode_parse(struct device *dev)
1962{
1963 struct fwnode_handle *endpoint;
1964 /* Only CSI2 is supported */
1965 struct v4l2_fwnode_endpoint ep = {
1966 .bus_type = V4L2_MBUS_CSI2_DPHY
1967 };
1968 int ret;
1969
1970 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
1971 if (!endpoint) {
1972 dev_err(dev, "Endpoint node not found\n");
1973 return -EINVAL;
1974 }
1975
1976 ret = v4l2_fwnode_endpoint_parse(endpoint, &ep);
1977 fwnode_handle_put(endpoint);
1978 if (ret == -ENXIO) {
1979 dev_err(dev, "Unsupported bus type, should be CSI2\n");
1980 return ret;
1981 } else if (ret) {
1982 dev_err(dev, "Parsing endpoint node failed %d\n", ret);
1983 return ret;
1984 }
1985
1986 /* Check number of data lanes, only 4 lanes supported */
1987 if (ep.bus.mipi_csi2.num_data_lanes != 4) {
1988 dev_err(dev, "Invalid data lanes: %d\n",
1989 ep.bus.mipi_csi2.num_data_lanes);
1990 return -EINVAL;
1991 }
1992
1993 return 0;
1994}
1995
Kieran Binghame6714992019-07-10 18:51:49 -03001996static int imx274_probe(struct i2c_client *client)
Leon Luo0985dd32017-10-05 02:06:21 +02001997{
1998 struct v4l2_subdev *sd;
1999 struct stimx274 *imx274;
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002000 struct device *dev = &client->dev;
Leon Luo0985dd32017-10-05 02:06:21 +02002001 int ret;
2002
2003 /* initialize imx274 */
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002004 imx274 = devm_kzalloc(dev, sizeof(*imx274), GFP_KERNEL);
Leon Luo0985dd32017-10-05 02:06:21 +02002005 if (!imx274)
2006 return -ENOMEM;
2007
2008 mutex_init(&imx274->lock);
2009
Eugen Hristev0abb8f92021-11-23 13:04:21 +01002010 ret = imx274_fwnode_parse(dev);
2011 if (ret)
2012 return ret;
2013
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002014 imx274->inck = devm_clk_get_optional(dev, "inck");
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002015 if (IS_ERR(imx274->inck))
2016 return PTR_ERR(imx274->inck);
2017
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002018 ret = imx274_regulators_get(dev, imx274);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002019 if (ret) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002020 dev_err(dev, "Failed to get power regulators, err: %d\n", ret);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002021 return ret;
2022 }
2023
Luca Ceresoli438ac1f2018-06-11 07:35:32 -04002024 /* initialize format */
Eugen Hristeve599fc82020-09-15 11:04:41 +02002025 imx274->mode = &imx274_modes[0];
Luca Ceresoli39dd23d2018-07-25 12:24:55 -04002026 imx274->crop.width = IMX274_MAX_WIDTH;
2027 imx274->crop.height = IMX274_MAX_HEIGHT;
Eugen Hristevf70ad2a2020-09-15 11:04:42 +02002028 imx274->format.width = imx274->crop.width / imx274->mode->wbin_ratio;
2029 imx274->format.height = imx274->crop.height / imx274->mode->hbin_ratio;
Luca Ceresoli438ac1f2018-06-11 07:35:32 -04002030 imx274->format.field = V4L2_FIELD_NONE;
2031 imx274->format.code = MEDIA_BUS_FMT_SRGGB10_1X10;
2032 imx274->format.colorspace = V4L2_COLORSPACE_SRGB;
2033 imx274->frame_interval.numerator = 1;
2034 imx274->frame_interval.denominator = IMX274_DEF_FRAME_RATE;
2035
Leon Luo0985dd32017-10-05 02:06:21 +02002036 /* initialize regmap */
2037 imx274->regmap = devm_regmap_init_i2c(client, &imx274_regmap_config);
2038 if (IS_ERR(imx274->regmap)) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002039 dev_err(dev,
Leon Luo0985dd32017-10-05 02:06:21 +02002040 "regmap init failed: %ld\n", PTR_ERR(imx274->regmap));
2041 ret = -ENODEV;
2042 goto err_regmap;
2043 }
2044
2045 /* initialize subdevice */
2046 imx274->client = client;
2047 sd = &imx274->sd;
2048 v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops);
Leon Luo0985dd32017-10-05 02:06:21 +02002049 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
2050
2051 /* initialize subdev media pad */
2052 imx274->pad.flags = MEDIA_PAD_FL_SOURCE;
2053 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
2054 ret = media_entity_pads_init(&sd->entity, 1, &imx274->pad);
2055 if (ret < 0) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002056 dev_err(dev,
Leon Luo0985dd32017-10-05 02:06:21 +02002057 "%s : media entity init Failed %d\n", __func__, ret);
2058 goto err_regmap;
2059 }
2060
2061 /* initialize sensor reset gpio */
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002062 imx274->reset_gpio = devm_gpiod_get_optional(dev, "reset",
Leon Luo0985dd32017-10-05 02:06:21 +02002063 GPIOD_OUT_HIGH);
2064 if (IS_ERR(imx274->reset_gpio)) {
2065 if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER)
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002066 dev_err(dev, "Reset GPIO not setup in DT");
Leon Luo0985dd32017-10-05 02:06:21 +02002067 ret = PTR_ERR(imx274->reset_gpio);
2068 goto err_me;
2069 }
2070
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002071 /* power on the sensor */
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002072 ret = imx274_power_on(dev);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002073 if (ret < 0) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002074 dev_err(dev, "%s : imx274 power on failed\n", __func__);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002075 goto err_me;
2076 }
Leon Luo0985dd32017-10-05 02:06:21 +02002077
2078 /* initialize controls */
Luca Ceresoli82f5b502018-11-27 03:34:44 -05002079 ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 4);
Leon Luo0985dd32017-10-05 02:06:21 +02002080 if (ret < 0) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002081 dev_err(dev, "%s : ctrl handler init Failed\n", __func__);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002082 goto err_power_off;
Leon Luo0985dd32017-10-05 02:06:21 +02002083 }
2084
2085 imx274->ctrls.handler.lock = &imx274->lock;
2086
2087 /* add new controls */
2088 imx274->ctrls.test_pattern = v4l2_ctrl_new_std_menu_items(
2089 &imx274->ctrls.handler, &imx274_ctrl_ops,
2090 V4L2_CID_TEST_PATTERN,
2091 ARRAY_SIZE(tp_qmenu) - 1, 0, 0, tp_qmenu);
2092
2093 imx274->ctrls.gain = v4l2_ctrl_new_std(
2094 &imx274->ctrls.handler,
2095 &imx274_ctrl_ops,
2096 V4L2_CID_GAIN, IMX274_MIN_GAIN,
2097 IMX274_MAX_DIGITAL_GAIN * IMX274_MAX_ANALOG_GAIN, 1,
2098 IMX274_DEF_GAIN);
2099
2100 imx274->ctrls.exposure = v4l2_ctrl_new_std(
2101 &imx274->ctrls.handler,
2102 &imx274_ctrl_ops,
2103 V4L2_CID_EXPOSURE, IMX274_MIN_EXPOSURE_TIME,
2104 1000000 / IMX274_DEF_FRAME_RATE, 1,
2105 IMX274_MIN_EXPOSURE_TIME);
2106
2107 imx274->ctrls.vflip = v4l2_ctrl_new_std(
2108 &imx274->ctrls.handler,
2109 &imx274_ctrl_ops,
2110 V4L2_CID_VFLIP, 0, 1, 1, 0);
2111
2112 imx274->sd.ctrl_handler = &imx274->ctrls.handler;
2113 if (imx274->ctrls.handler.error) {
2114 ret = imx274->ctrls.handler.error;
2115 goto err_ctrls;
2116 }
2117
Leon Luo0985dd32017-10-05 02:06:21 +02002118 /* load default control values */
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002119 imx274_load_default(imx274);
Leon Luo0985dd32017-10-05 02:06:21 +02002120
2121 /* register subdevice */
2122 ret = v4l2_async_register_subdev(sd);
2123 if (ret < 0) {
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002124 dev_err(dev, "%s : v4l2_async_register_subdev failed %d\n",
Leon Luo0985dd32017-10-05 02:06:21 +02002125 __func__, ret);
2126 goto err_ctrls;
2127 }
2128
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002129 pm_runtime_set_active(dev);
2130 pm_runtime_enable(dev);
2131 pm_runtime_idle(dev);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002132
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002133 dev_info(dev, "imx274 : imx274 probe success !\n");
Leon Luo0985dd32017-10-05 02:06:21 +02002134 return 0;
2135
2136err_ctrls:
Sakari Ailus781b0452017-11-01 05:40:58 -04002137 v4l2_ctrl_handler_free(&imx274->ctrls.handler);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002138err_power_off:
Eugen Hristev57de5bb2021-11-23 12:15:20 +01002139 imx274_power_off(dev);
Leon Luo0985dd32017-10-05 02:06:21 +02002140err_me:
2141 media_entity_cleanup(&sd->entity);
2142err_regmap:
2143 mutex_destroy(&imx274->lock);
2144 return ret;
2145}
2146
2147static int imx274_remove(struct i2c_client *client)
2148{
2149 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2150 struct stimx274 *imx274 = to_imx274(sd);
2151
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002152 pm_runtime_disable(&client->dev);
2153 if (!pm_runtime_status_suspended(&client->dev))
2154 imx274_power_off(&client->dev);
2155 pm_runtime_set_suspended(&client->dev);
2156
Leon Luo0985dd32017-10-05 02:06:21 +02002157 v4l2_async_unregister_subdev(sd);
Sakari Ailus781b0452017-11-01 05:40:58 -04002158 v4l2_ctrl_handler_free(&imx274->ctrls.handler);
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002159
Leon Luo0985dd32017-10-05 02:06:21 +02002160 media_entity_cleanup(&sd->entity);
2161 mutex_destroy(&imx274->lock);
2162 return 0;
2163}
2164
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002165static const struct dev_pm_ops imx274_pm_ops = {
2166 SET_RUNTIME_PM_OPS(imx274_power_off, imx274_power_on, NULL)
2167};
2168
Leon Luo0985dd32017-10-05 02:06:21 +02002169static struct i2c_driver imx274_i2c_driver = {
2170 .driver = {
2171 .name = DRIVER_NAME,
Sowjanya Komatineniad97bc32020-09-21 23:39:39 +02002172 .pm = &imx274_pm_ops,
Leon Luo0985dd32017-10-05 02:06:21 +02002173 .of_match_table = imx274_of_id_table,
2174 },
Kieran Binghame6714992019-07-10 18:51:49 -03002175 .probe_new = imx274_probe,
Leon Luo0985dd32017-10-05 02:06:21 +02002176 .remove = imx274_remove,
2177 .id_table = imx274_id,
2178};
2179
2180module_i2c_driver(imx274_i2c_driver);
2181
2182MODULE_AUTHOR("Leon Luo <leonl@leopardimaging.com>");
2183MODULE_DESCRIPTION("IMX274 CMOS Image Sensor driver");
2184MODULE_LICENSE("GPL v2");