Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2022 Intel Corporation.
3
4#include <linux/acpi.h>
5#include <linux/clk.h>
6#include <linux/delay.h>
7#include <linux/gpio/consumer.h>
8#include <linux/i2c.h>
9#include <linux/module.h>
10#include <linux/pm_runtime.h>
11#include <linux/regulator/consumer.h>
12#include <linux/unaligned.h>
13
14#include <media/v4l2-ctrls.h>
15#include <media/v4l2-device.h>
16#include <media/v4l2-fwnode.h>
17
18#define OG01A1B_REG_VALUE_08BIT 1
19#define OG01A1B_REG_VALUE_16BIT 2
20#define OG01A1B_REG_VALUE_24BIT 3
21
22#define OG01A1B_LINK_FREQ_500MHZ 500000000ULL
23#define OG01A1B_SCLK 120000000LL
24#define OG01A1B_MCLK 19200000
25#define OG01A1B_DATA_LANES 2
26#define OG01A1B_RGB_DEPTH 10
27
28#define OG01A1B_REG_CHIP_ID 0x300a
29#define OG01A1B_CHIP_ID 0x470141
30
31#define OG01A1B_REG_MODE_SELECT 0x0100
32#define OG01A1B_MODE_STANDBY 0x00
33#define OG01A1B_MODE_STREAMING 0x01
34
35/* vertical-timings from sensor */
36#define OG01A1B_REG_VTS 0x380e
37#define OG01A1B_VTS_120FPS 0x0498
38#define OG01A1B_VTS_120FPS_MIN 0x0498
39#define OG01A1B_VTS_MAX 0x7fff
40
41/* horizontal-timings from sensor */
42#define OG01A1B_REG_HTS 0x380c
43
44/* Exposure controls from sensor */
45#define OG01A1B_REG_EXPOSURE 0x3501
46#define OG01A1B_EXPOSURE_MIN 1
47#define OG01A1B_EXPOSURE_MAX_MARGIN 14
48#define OG01A1B_EXPOSURE_STEP 1
49
50/* Analog gain controls from sensor */
51#define OG01A1B_REG_ANALOG_GAIN 0x3508
52#define OG01A1B_ANAL_GAIN_MIN 16
53#define OG01A1B_ANAL_GAIN_MAX 248 /* Max = 15.5x */
54#define OG01A1B_ANAL_GAIN_STEP 1
55
56/* Digital gain controls from sensor */
57#define OG01A1B_REG_DIG_GAIN 0x350a
58#define OG01A1B_DGTL_GAIN_MIN 1024
59#define OG01A1B_DGTL_GAIN_MAX 16384 /* Max = 16x */
60#define OG01A1B_DGTL_GAIN_STEP 1
61#define OG01A1B_DGTL_GAIN_DEFAULT 1024
62
63/* Group Access */
64#define OG01A1B_REG_GROUP_ACCESS 0x3208
65#define OG01A1B_GROUP_HOLD_START 0x0
66#define OG01A1B_GROUP_HOLD_END 0x10
67#define OG01A1B_GROUP_HOLD_LAUNCH 0xa0
68
69/* Test Pattern Control */
70#define OG01A1B_REG_TEST_PATTERN 0x5100
71#define OG01A1B_TEST_PATTERN_ENABLE BIT(7)
72#define OG01A1B_TEST_PATTERN_BAR_SHIFT 2
73
74#define to_og01a1b(_sd) container_of(_sd, struct og01a1b, sd)
75
76enum {
77 OG01A1B_LINK_FREQ_1000MBPS,
78};
79
80struct og01a1b_reg {
81 u16 address;
82 u8 val;
83};
84
85struct og01a1b_reg_list {
86 u32 num_of_regs;
87 const struct og01a1b_reg *regs;
88};
89
90struct og01a1b_link_freq_config {
91 const struct og01a1b_reg_list reg_list;
92};
93
94struct og01a1b_mode {
95 /* Frame width in pixels */
96 u32 width;
97
98 /* Frame height in pixels */
99 u32 height;
100
101 /* Horizontal timining size */
102 u32 hts;
103
104 /* Default vertical timining size */
105 u32 vts_def;
106
107 /* Min vertical timining size */
108 u32 vts_min;
109
110 /* Link frequency needed for this resolution */
111 u32 link_freq_index;
112
113 /* Sensor register settings for this resolution */
114 const struct og01a1b_reg_list reg_list;
115};
116
117static const struct og01a1b_reg mipi_data_rate_1000mbps[] = {
118 {0x0103, 0x01},
119 {0x0303, 0x02},
120 {0x0304, 0x00},
121 {0x0305, 0xd2},
122 {0x0323, 0x02},
123 {0x0324, 0x01},
124 {0x0325, 0x77},
125};
126
127static const struct og01a1b_reg mode_1280x1024_regs[] = {
128 {0x0300, 0x0a},
129 {0x0301, 0x29},
130 {0x0302, 0x31},
131 {0x0303, 0x02},
132 {0x0304, 0x00},
133 {0x0305, 0xd2},
134 {0x0306, 0x00},
135 {0x0307, 0x01},
136 {0x0308, 0x02},
137 {0x0309, 0x00},
138 {0x0310, 0x00},
139 {0x0311, 0x00},
140 {0x0312, 0x07},
141 {0x0313, 0x00},
142 {0x0314, 0x00},
143 {0x0315, 0x00},
144 {0x0320, 0x02},
145 {0x0321, 0x01},
146 {0x0322, 0x01},
147 {0x0323, 0x02},
148 {0x0324, 0x01},
149 {0x0325, 0x77},
150 {0x0326, 0xce},
151 {0x0327, 0x04},
152 {0x0329, 0x02},
153 {0x032a, 0x04},
154 {0x032b, 0x04},
155 {0x032c, 0x02},
156 {0x032d, 0x01},
157 {0x032e, 0x00},
158 {0x300d, 0x02},
159 {0x300e, 0x04},
160 {0x3021, 0x08},
161 {0x301e, 0x03},
162 {0x3103, 0x00},
163 {0x3106, 0x08},
164 {0x3107, 0x40},
165 {0x3216, 0x01},
166 {0x3217, 0x00},
167 {0x3218, 0xc0},
168 {0x3219, 0x55},
169 {0x3500, 0x00},
170 {0x3501, 0x04},
171 {0x3502, 0x8a},
172 {0x3506, 0x01},
173 {0x3507, 0x72},
174 {0x3508, 0x01},
175 {0x3509, 0x00},
176 {0x350a, 0x01},
177 {0x350b, 0x00},
178 {0x350c, 0x00},
179 {0x3541, 0x00},
180 {0x3542, 0x40},
181 {0x3605, 0xe0},
182 {0x3606, 0x41},
183 {0x3614, 0x20},
184 {0x3620, 0x0b},
185 {0x3630, 0x07},
186 {0x3636, 0xa0},
187 {0x3637, 0xf9},
188 {0x3638, 0x09},
189 {0x3639, 0x38},
190 {0x363f, 0x09},
191 {0x3640, 0x17},
192 {0x3662, 0x04},
193 {0x3665, 0x80},
194 {0x3670, 0x68},
195 {0x3674, 0x00},
196 {0x3677, 0x3f},
197 {0x3679, 0x00},
198 {0x369f, 0x19},
199 {0x36a0, 0x03},
200 {0x36a2, 0x19},
201 {0x36a3, 0x03},
202 {0x370d, 0x66},
203 {0x370f, 0x00},
204 {0x3710, 0x03},
205 {0x3715, 0x03},
206 {0x3716, 0x03},
207 {0x3717, 0x06},
208 {0x3733, 0x00},
209 {0x3778, 0x00},
210 {0x37a8, 0x0f},
211 {0x37a9, 0x01},
212 {0x37aa, 0x07},
213 {0x37bd, 0x1c},
214 {0x37c1, 0x2f},
215 {0x37c3, 0x09},
216 {0x37c8, 0x1d},
217 {0x37ca, 0x30},
218 {0x37df, 0x00},
219 {0x3800, 0x00},
220 {0x3801, 0x00},
221 {0x3802, 0x00},
222 {0x3803, 0x00},
223 {0x3804, 0x05},
224 {0x3805, 0x0f},
225 {0x3806, 0x04},
226 {0x3807, 0x0f},
227 {0x3808, 0x05},
228 {0x3809, 0x00},
229 {0x380a, 0x04},
230 {0x380b, 0x00},
231 {0x380c, 0x03},
232 {0x380d, 0x50},
233 {0x380e, 0x04},
234 {0x380f, 0x98},
235 {0x3810, 0x00},
236 {0x3811, 0x08},
237 {0x3812, 0x00},
238 {0x3813, 0x08},
239 {0x3814, 0x11},
240 {0x3815, 0x11},
241 {0x3820, 0x40},
242 {0x3821, 0x04},
243 {0x3826, 0x00},
244 {0x3827, 0x00},
245 {0x382a, 0x08},
246 {0x382b, 0x52},
247 {0x382d, 0xba},
248 {0x383d, 0x14},
249 {0x384a, 0xa2},
250 {0x3866, 0x0e},
251 {0x3867, 0x07},
252 {0x3884, 0x00},
253 {0x3885, 0x08},
254 {0x3893, 0x68},
255 {0x3894, 0x2a},
256 {0x3898, 0x00},
257 {0x3899, 0x31},
258 {0x389a, 0x04},
259 {0x389b, 0x00},
260 {0x389c, 0x0b},
261 {0x389d, 0xad},
262 {0x389f, 0x08},
263 {0x38a0, 0x00},
264 {0x38a1, 0x00},
265 {0x38a8, 0x70},
266 {0x38ac, 0xea},
267 {0x38b2, 0x00},
268 {0x38b3, 0x08},
269 {0x38bc, 0x20},
270 {0x38c4, 0x0c},
271 {0x38c5, 0x3a},
272 {0x38c7, 0x3a},
273 {0x38e1, 0xc0},
274 {0x38ec, 0x3c},
275 {0x38f0, 0x09},
276 {0x38f1, 0x6f},
277 {0x38fe, 0x3c},
278 {0x391e, 0x00},
279 {0x391f, 0x00},
280 {0x3920, 0xa5},
281 {0x3921, 0x00},
282 {0x3922, 0x00},
283 {0x3923, 0x00},
284 {0x3924, 0x05},
285 {0x3925, 0x00},
286 {0x3926, 0x00},
287 {0x3927, 0x00},
288 {0x3928, 0x1a},
289 {0x3929, 0x01},
290 {0x392a, 0xb4},
291 {0x392b, 0x00},
292 {0x392c, 0x10},
293 {0x392f, 0x40},
294 {0x4000, 0xcf},
295 {0x4003, 0x40},
296 {0x4008, 0x00},
297 {0x4009, 0x07},
298 {0x400a, 0x02},
299 {0x400b, 0x54},
300 {0x400c, 0x00},
301 {0x400d, 0x07},
302 {0x4010, 0xc0},
303 {0x4012, 0x02},
304 {0x4014, 0x04},
305 {0x4015, 0x04},
306 {0x4017, 0x02},
307 {0x4042, 0x01},
308 {0x4306, 0x04},
309 {0x4307, 0x12},
310 {0x4509, 0x00},
311 {0x450b, 0x83},
312 {0x4604, 0x68},
313 {0x4608, 0x0a},
314 {0x4700, 0x06},
315 {0x4800, 0x64},
316 {0x481b, 0x3c},
317 {0x4825, 0x32},
318 {0x4833, 0x18},
319 {0x4837, 0x0f},
320 {0x4850, 0x40},
321 {0x4860, 0x00},
322 {0x4861, 0xec},
323 {0x4864, 0x00},
324 {0x4883, 0x00},
325 {0x4888, 0x90},
326 {0x4889, 0x05},
327 {0x488b, 0x04},
328 {0x4f00, 0x04},
329 {0x4f10, 0x04},
330 {0x4f21, 0x01},
331 {0x4f22, 0x40},
332 {0x4f23, 0x44},
333 {0x4f24, 0x51},
334 {0x4f25, 0x41},
335 {0x5000, 0x1f},
336 {0x500a, 0x00},
337 {0x5100, 0x00},
338 {0x5111, 0x20},
339 {0x3020, 0x20},
340 {0x3613, 0x03},
341 {0x38c9, 0x02},
342 {0x5304, 0x01},
343 {0x3620, 0x08},
344 {0x3639, 0x58},
345 {0x363a, 0x10},
346 {0x3674, 0x04},
347 {0x3780, 0xff},
348 {0x3781, 0xff},
349 {0x3782, 0x00},
350 {0x3783, 0x01},
351 {0x3798, 0xa3},
352 {0x37aa, 0x10},
353 {0x38a8, 0xf0},
354 {0x38c4, 0x09},
355 {0x38c5, 0xb0},
356 {0x38df, 0x80},
357 {0x38ff, 0x05},
358 {0x4010, 0xf1},
359 {0x4011, 0x70},
360 {0x3667, 0x80},
361 {0x4d00, 0x4a},
362 {0x4d01, 0x18},
363 {0x4d02, 0xbb},
364 {0x4d03, 0xde},
365 {0x4d04, 0x93},
366 {0x4d05, 0xff},
367 {0x4d09, 0x0a},
368 {0x37aa, 0x16},
369 {0x3606, 0x42},
370 {0x3605, 0x00},
371 {0x36a2, 0x17},
372 {0x300d, 0x0a},
373 {0x4d00, 0x4d},
374 {0x4d01, 0x95},
375 {0x3d8C, 0x70},
376 {0x3d8d, 0xE9},
377 {0x5300, 0x00},
378 {0x5301, 0x10},
379 {0x5302, 0x00},
380 {0x5303, 0xE3},
381 {0x3d88, 0x00},
382 {0x3d89, 0x10},
383 {0x3d8a, 0x00},
384 {0x3d8b, 0xE3},
385 {0x4f22, 0x00},
386};
387
388static const char * const og01a1b_test_pattern_menu[] = {
389 "Disabled",
390 "Standard Color Bar",
391 "Top-Bottom Darker Color Bar",
392 "Right-Left Darker Color Bar",
393 "Bottom-Top Darker Color Bar"
394};
395
396static const s64 link_freq_menu_items[] = {
397 OG01A1B_LINK_FREQ_500MHZ,
398};
399
400static const struct og01a1b_link_freq_config link_freq_configs[] = {
401 [OG01A1B_LINK_FREQ_1000MBPS] = {
402 .reg_list = {
403 .num_of_regs = ARRAY_SIZE(mipi_data_rate_1000mbps),
404 .regs = mipi_data_rate_1000mbps,
405 }
406 }
407};
408
409static const struct og01a1b_mode supported_modes[] = {
410 {
411 .width = 1280,
412 .height = 1024,
413 .hts = 848,
414 .vts_def = OG01A1B_VTS_120FPS,
415 .vts_min = OG01A1B_VTS_120FPS_MIN,
416 .reg_list = {
417 .num_of_regs = ARRAY_SIZE(mode_1280x1024_regs),
418 .regs = mode_1280x1024_regs,
419 },
420 .link_freq_index = OG01A1B_LINK_FREQ_1000MBPS,
421 },
422};
423
424struct og01a1b {
425 struct device *dev;
426 struct clk *xvclk;
427 struct gpio_desc *reset_gpio;
428 struct regulator *avdd;
429 struct regulator *dovdd;
430 struct regulator *dvdd;
431
432 struct v4l2_subdev sd;
433 struct media_pad pad;
434 struct v4l2_ctrl_handler ctrl_handler;
435
436 /* V4L2 Controls */
437 struct v4l2_ctrl *link_freq;
438 struct v4l2_ctrl *pixel_rate;
439 struct v4l2_ctrl *vblank;
440 struct v4l2_ctrl *hblank;
441 struct v4l2_ctrl *exposure;
442
443 /* Current mode */
444 const struct og01a1b_mode *cur_mode;
445
446 /* To serialize asynchronus callbacks */
447 struct mutex mutex;
448};
449
450static u64 to_pixel_rate(u32 f_index)
451{
452 u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OG01A1B_DATA_LANES;
453
454 do_div(pixel_rate, OG01A1B_RGB_DEPTH);
455
456 return pixel_rate;
457}
458
459static u64 to_pixels_per_line(u32 hts, u32 f_index)
460{
461 u64 ppl = hts * to_pixel_rate(f_index);
462
463 do_div(ppl, OG01A1B_SCLK);
464
465 return ppl;
466}
467
468static int og01a1b_read_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 *val)
469{
470 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
471 struct i2c_msg msgs[2];
472 u8 addr_buf[2];
473 u8 data_buf[4] = {0};
474 int ret;
475
476 if (len > 4)
477 return -EINVAL;
478
479 put_unaligned_be16(reg, addr_buf);
480 msgs[0].addr = client->addr;
481 msgs[0].flags = 0;
482 msgs[0].len = sizeof(addr_buf);
483 msgs[0].buf = addr_buf;
484 msgs[1].addr = client->addr;
485 msgs[1].flags = I2C_M_RD;
486 msgs[1].len = len;
487 msgs[1].buf = &data_buf[4 - len];
488
489 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
490 if (ret != ARRAY_SIZE(msgs))
491 return -EIO;
492
493 *val = get_unaligned_be32(data_buf);
494
495 return 0;
496}
497
498static int og01a1b_write_reg(struct og01a1b *og01a1b, u16 reg, u16 len, u32 val)
499{
500 struct i2c_client *client = v4l2_get_subdevdata(&og01a1b->sd);
501 u8 buf[6];
502
503 if (len > 4)
504 return -EINVAL;
505
506 put_unaligned_be16(reg, buf);
507 put_unaligned_be32(val << 8 * (4 - len), buf + 2);
508 if (i2c_master_send(client, buf, len + 2) != len + 2)
509 return -EIO;
510
511 return 0;
512}
513
514static int og01a1b_write_reg_list(struct og01a1b *og01a1b,
515 const struct og01a1b_reg_list *r_list)
516{
517 unsigned int i;
518 int ret;
519
520 for (i = 0; i < r_list->num_of_regs; i++) {
521 ret = og01a1b_write_reg(og01a1b, r_list->regs[i].address, 1,
522 r_list->regs[i].val);
523 if (ret) {
524 dev_err_ratelimited(og01a1b->dev,
525 "failed to write reg 0x%4.4x. error = %d",
526 r_list->regs[i].address, ret);
527 return ret;
528 }
529 }
530
531 return 0;
532}
533
534static int og01a1b_test_pattern(struct og01a1b *og01a1b, u32 pattern)
535{
536 if (pattern)
537 pattern = (pattern - 1) << OG01A1B_TEST_PATTERN_BAR_SHIFT |
538 OG01A1B_TEST_PATTERN_ENABLE;
539
540 return og01a1b_write_reg(og01a1b, OG01A1B_REG_TEST_PATTERN,
541 OG01A1B_REG_VALUE_08BIT, pattern);
542}
543
544static int og01a1b_set_ctrl(struct v4l2_ctrl *ctrl)
545{
546 struct og01a1b *og01a1b = container_of(ctrl->handler,
547 struct og01a1b, ctrl_handler);
548 s64 exposure_max;
549 int ret = 0;
550
551 /* Propagate change of current control to all related controls */
552 if (ctrl->id == V4L2_CID_VBLANK) {
553 /* Update max exposure while meeting expected vblanking */
554 exposure_max = og01a1b->cur_mode->height + ctrl->val -
555 OG01A1B_EXPOSURE_MAX_MARGIN;
556 __v4l2_ctrl_modify_range(og01a1b->exposure,
557 og01a1b->exposure->minimum,
558 exposure_max, og01a1b->exposure->step,
559 exposure_max);
560 }
561
562 /* V4L2 controls values will be applied only when power is already up */
563 if (!pm_runtime_get_if_in_use(og01a1b->dev))
564 return 0;
565
566 switch (ctrl->id) {
567 case V4L2_CID_ANALOGUE_GAIN:
568 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_ANALOG_GAIN,
569 OG01A1B_REG_VALUE_16BIT,
570 ctrl->val << 4);
571 break;
572
573 case V4L2_CID_DIGITAL_GAIN:
574 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_DIG_GAIN,
575 OG01A1B_REG_VALUE_24BIT,
576 ctrl->val << 6);
577 break;
578
579 case V4L2_CID_EXPOSURE:
580 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_EXPOSURE,
581 OG01A1B_REG_VALUE_16BIT, ctrl->val);
582 break;
583
584 case V4L2_CID_VBLANK:
585 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_VTS,
586 OG01A1B_REG_VALUE_16BIT,
587 og01a1b->cur_mode->height + ctrl->val);
588 break;
589
590 case V4L2_CID_TEST_PATTERN:
591 ret = og01a1b_test_pattern(og01a1b, ctrl->val);
592 break;
593
594 default:
595 ret = -EINVAL;
596 break;
597 }
598
599 pm_runtime_put(og01a1b->dev);
600
601 return ret;
602}
603
604static const struct v4l2_ctrl_ops og01a1b_ctrl_ops = {
605 .s_ctrl = og01a1b_set_ctrl,
606};
607
608static int og01a1b_init_controls(struct og01a1b *og01a1b)
609{
610 struct v4l2_ctrl_handler *ctrl_hdlr;
611 s64 exposure_max, h_blank;
612 int ret;
613
614 ctrl_hdlr = &og01a1b->ctrl_handler;
615 ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
616 if (ret)
617 return ret;
618
619 ctrl_hdlr->lock = &og01a1b->mutex;
620 og01a1b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
621 &og01a1b_ctrl_ops,
622 V4L2_CID_LINK_FREQ,
623 ARRAY_SIZE
624 (link_freq_menu_items) - 1,
625 0, link_freq_menu_items);
626 if (og01a1b->link_freq)
627 og01a1b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
628
629 og01a1b->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
630 V4L2_CID_PIXEL_RATE, 0,
631 to_pixel_rate
632 (OG01A1B_LINK_FREQ_1000MBPS),
633 1,
634 to_pixel_rate
635 (OG01A1B_LINK_FREQ_1000MBPS));
636 og01a1b->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
637 V4L2_CID_VBLANK,
638 og01a1b->cur_mode->vts_min -
639 og01a1b->cur_mode->height,
640 OG01A1B_VTS_MAX -
641 og01a1b->cur_mode->height, 1,
642 og01a1b->cur_mode->vts_def -
643 og01a1b->cur_mode->height);
644 h_blank = to_pixels_per_line(og01a1b->cur_mode->hts,
645 og01a1b->cur_mode->link_freq_index) -
646 og01a1b->cur_mode->width;
647 og01a1b->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
648 V4L2_CID_HBLANK, h_blank, h_blank,
649 1, h_blank);
650 if (og01a1b->hblank)
651 og01a1b->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
652
653 v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
654 OG01A1B_ANAL_GAIN_MIN, OG01A1B_ANAL_GAIN_MAX,
655 OG01A1B_ANAL_GAIN_STEP, OG01A1B_ANAL_GAIN_MIN);
656 v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
657 OG01A1B_DGTL_GAIN_MIN, OG01A1B_DGTL_GAIN_MAX,
658 OG01A1B_DGTL_GAIN_STEP, OG01A1B_DGTL_GAIN_DEFAULT);
659 exposure_max = (og01a1b->cur_mode->vts_def -
660 OG01A1B_EXPOSURE_MAX_MARGIN);
661 og01a1b->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &og01a1b_ctrl_ops,
662 V4L2_CID_EXPOSURE,
663 OG01A1B_EXPOSURE_MIN,
664 exposure_max,
665 OG01A1B_EXPOSURE_STEP,
666 exposure_max);
667 v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &og01a1b_ctrl_ops,
668 V4L2_CID_TEST_PATTERN,
669 ARRAY_SIZE(og01a1b_test_pattern_menu) - 1,
670 0, 0, og01a1b_test_pattern_menu);
671
672 if (ctrl_hdlr->error)
673 return ctrl_hdlr->error;
674
675 og01a1b->sd.ctrl_handler = ctrl_hdlr;
676
677 return 0;
678}
679
680static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,
681 struct v4l2_mbus_framefmt *fmt)
682{
683 fmt->width = mode->width;
684 fmt->height = mode->height;
685 fmt->code = MEDIA_BUS_FMT_Y10_1X10;
686 fmt->field = V4L2_FIELD_NONE;
687}
688
689static int og01a1b_start_streaming(struct og01a1b *og01a1b)
690{
691 const struct og01a1b_reg_list *reg_list;
692 int link_freq_index, ret;
693
694 link_freq_index = og01a1b->cur_mode->link_freq_index;
695 reg_list = &link_freq_configs[link_freq_index].reg_list;
696
697 ret = og01a1b_write_reg_list(og01a1b, reg_list);
698 if (ret) {
699 dev_err(og01a1b->dev, "failed to set plls");
700 return ret;
701 }
702
703 reg_list = &og01a1b->cur_mode->reg_list;
704 ret = og01a1b_write_reg_list(og01a1b, reg_list);
705 if (ret) {
706 dev_err(og01a1b->dev, "failed to set mode");
707 return ret;
708 }
709
710 ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
711 if (ret)
712 return ret;
713
714 ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
715 OG01A1B_REG_VALUE_08BIT,
716 OG01A1B_MODE_STREAMING);
717 if (ret) {
718 dev_err(og01a1b->dev, "failed to set stream");
719 return ret;
720 }
721
722 return 0;
723}
724
725static void og01a1b_stop_streaming(struct og01a1b *og01a1b)
726{
727 if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
728 OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY))
729 dev_err(og01a1b->dev, "failed to set stream");
730}
731
732static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)
733{
734 struct og01a1b *og01a1b = to_og01a1b(sd);
735 int ret = 0;
736
737 mutex_lock(&og01a1b->mutex);
738 if (enable) {
739 ret = pm_runtime_resume_and_get(og01a1b->dev);
740 if (ret) {
741 mutex_unlock(&og01a1b->mutex);
742 return ret;
743 }
744
745 ret = og01a1b_start_streaming(og01a1b);
746 if (ret) {
747 enable = 0;
748 og01a1b_stop_streaming(og01a1b);
749 pm_runtime_put(og01a1b->dev);
750 }
751 } else {
752 og01a1b_stop_streaming(og01a1b);
753 pm_runtime_put(og01a1b->dev);
754 }
755
756 mutex_unlock(&og01a1b->mutex);
757
758 return ret;
759}
760
761static int og01a1b_set_format(struct v4l2_subdev *sd,
762 struct v4l2_subdev_state *sd_state,
763 struct v4l2_subdev_format *fmt)
764{
765 struct og01a1b *og01a1b = to_og01a1b(sd);
766 const struct og01a1b_mode *mode;
767 s32 vblank_def, h_blank;
768
769 mode = v4l2_find_nearest_size(supported_modes,
770 ARRAY_SIZE(supported_modes), width,
771 height, fmt->format.width,
772 fmt->format.height);
773
774 mutex_lock(&og01a1b->mutex);
775 og01a1b_update_pad_format(mode, &fmt->format);
776 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
777 *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
778 } else {
779 og01a1b->cur_mode = mode;
780 __v4l2_ctrl_s_ctrl(og01a1b->link_freq, mode->link_freq_index);
781 __v4l2_ctrl_s_ctrl_int64(og01a1b->pixel_rate,
782 to_pixel_rate(mode->link_freq_index));
783
784 /* Update limits and set FPS to default */
785 vblank_def = mode->vts_def - mode->height;
786 __v4l2_ctrl_modify_range(og01a1b->vblank,
787 mode->vts_min - mode->height,
788 OG01A1B_VTS_MAX - mode->height, 1,
789 vblank_def);
790 __v4l2_ctrl_s_ctrl(og01a1b->vblank, vblank_def);
791 h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) -
792 mode->width;
793 __v4l2_ctrl_modify_range(og01a1b->hblank, h_blank, h_blank, 1,
794 h_blank);
795 }
796
797 mutex_unlock(&og01a1b->mutex);
798
799 return 0;
800}
801
802static int og01a1b_get_format(struct v4l2_subdev *sd,
803 struct v4l2_subdev_state *sd_state,
804 struct v4l2_subdev_format *fmt)
805{
806 struct og01a1b *og01a1b = to_og01a1b(sd);
807
808 mutex_lock(&og01a1b->mutex);
809 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
810 fmt->format = *v4l2_subdev_state_get_format(sd_state,
811 fmt->pad);
812 else
813 og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format);
814
815 mutex_unlock(&og01a1b->mutex);
816
817 return 0;
818}
819
820static int og01a1b_enum_mbus_code(struct v4l2_subdev *sd,
821 struct v4l2_subdev_state *sd_state,
822 struct v4l2_subdev_mbus_code_enum *code)
823{
824 if (code->index > 0)
825 return -EINVAL;
826
827 code->code = MEDIA_BUS_FMT_Y10_1X10;
828
829 return 0;
830}
831
832static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
833 struct v4l2_subdev_state *sd_state,
834 struct v4l2_subdev_frame_size_enum *fse)
835{
836 if (fse->index >= ARRAY_SIZE(supported_modes))
837 return -EINVAL;
838
839 if (fse->code != MEDIA_BUS_FMT_Y10_1X10)
840 return -EINVAL;
841
842 fse->min_width = supported_modes[fse->index].width;
843 fse->max_width = fse->min_width;
844 fse->min_height = supported_modes[fse->index].height;
845 fse->max_height = fse->min_height;
846
847 return 0;
848}
849
850static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
851{
852 struct og01a1b *og01a1b = to_og01a1b(sd);
853
854 mutex_lock(&og01a1b->mutex);
855 og01a1b_update_pad_format(&supported_modes[0],
856 v4l2_subdev_state_get_format(fh->state, 0));
857 mutex_unlock(&og01a1b->mutex);
858
859 return 0;
860}
861
862static const struct v4l2_subdev_video_ops og01a1b_video_ops = {
863 .s_stream = og01a1b_set_stream,
864};
865
866static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
867 .set_fmt = og01a1b_set_format,
868 .get_fmt = og01a1b_get_format,
869 .enum_mbus_code = og01a1b_enum_mbus_code,
870 .enum_frame_size = og01a1b_enum_frame_size,
871};
872
873static const struct v4l2_subdev_ops og01a1b_subdev_ops = {
874 .video = &og01a1b_video_ops,
875 .pad = &og01a1b_pad_ops,
876};
877
878static const struct media_entity_operations og01a1b_subdev_entity_ops = {
879 .link_validate = v4l2_subdev_link_validate,
880};
881
882static const struct v4l2_subdev_internal_ops og01a1b_internal_ops = {
883 .open = og01a1b_open,
884};
885
886static int og01a1b_identify_module(struct og01a1b *og01a1b)
887{
888 int ret;
889 u32 val;
890
891 ret = og01a1b_read_reg(og01a1b, OG01A1B_REG_CHIP_ID,
892 OG01A1B_REG_VALUE_24BIT, &val);
893 if (ret)
894 return ret;
895
896 if (val != OG01A1B_CHIP_ID) {
897 dev_err(og01a1b->dev, "chip id mismatch: %x!=%x",
898 OG01A1B_CHIP_ID, val);
899 return -ENXIO;
900 }
901
902 return 0;
903}
904
905static int og01a1b_check_hwcfg(struct og01a1b *og01a1b)
906{
907 struct device *dev = og01a1b->dev;
908 struct fwnode_handle *ep;
909 struct fwnode_handle *fwnode = dev_fwnode(dev);
910 struct v4l2_fwnode_endpoint bus_cfg = {
911 .bus_type = V4L2_MBUS_CSI2_DPHY
912 };
913 int ret;
914 unsigned int i, j;
915
916 if (!fwnode)
917 return -ENXIO;
918
919 ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
920 if (!ep)
921 return -ENXIO;
922
923 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
924 fwnode_handle_put(ep);
925 if (ret)
926 return ret;
927
928 if (bus_cfg.bus.mipi_csi2.num_data_lanes != OG01A1B_DATA_LANES) {
929 dev_err(dev, "number of CSI2 data lanes %d is not supported",
930 bus_cfg.bus.mipi_csi2.num_data_lanes);
931 ret = -EINVAL;
932 goto check_hwcfg_error;
933 }
934
935 if (!bus_cfg.nr_of_link_frequencies) {
936 dev_err(dev, "no link frequencies defined");
937 ret = -EINVAL;
938 goto check_hwcfg_error;
939 }
940
941 for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
942 for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
943 if (link_freq_menu_items[i] ==
944 bus_cfg.link_frequencies[j])
945 break;
946 }
947
948 if (j == bus_cfg.nr_of_link_frequencies) {
949 dev_err(dev, "no link frequency %lld supported",
950 link_freq_menu_items[i]);
951 ret = -EINVAL;
952 goto check_hwcfg_error;
953 }
954 }
955
956check_hwcfg_error:
957 v4l2_fwnode_endpoint_free(&bus_cfg);
958
959 return ret;
960}
961
962/* Power/clock management functions */
963static int og01a1b_power_on(struct device *dev)
964{
965 unsigned long delay = DIV_ROUND_UP(8192UL * USEC_PER_SEC, OG01A1B_MCLK);
966 struct v4l2_subdev *sd = dev_get_drvdata(dev);
967 struct og01a1b *og01a1b = to_og01a1b(sd);
968 int ret;
969
970 if (og01a1b->avdd) {
971 ret = regulator_enable(og01a1b->avdd);
972 if (ret)
973 return ret;
974 }
975
976 if (og01a1b->dovdd) {
977 ret = regulator_enable(og01a1b->dovdd);
978 if (ret)
979 goto avdd_disable;
980 }
981
982 if (og01a1b->dvdd) {
983 ret = regulator_enable(og01a1b->dvdd);
984 if (ret)
985 goto dovdd_disable;
986 }
987
988 ret = clk_prepare_enable(og01a1b->xvclk);
989 if (ret)
990 goto dvdd_disable;
991
992 gpiod_set_value_cansleep(og01a1b->reset_gpio, 0);
993
994 if (og01a1b->reset_gpio)
995 usleep_range(5 * USEC_PER_MSEC, 6 * USEC_PER_MSEC);
996 else if (og01a1b->xvclk)
997 usleep_range(delay, 2 * delay);
998
999 return 0;
1000
1001dvdd_disable:
1002 if (og01a1b->dvdd)
1003 regulator_disable(og01a1b->dvdd);
1004dovdd_disable:
1005 if (og01a1b->dovdd)
1006 regulator_disable(og01a1b->dovdd);
1007avdd_disable:
1008 if (og01a1b->avdd)
1009 regulator_disable(og01a1b->avdd);
1010
1011 return ret;
1012}
1013
1014static int og01a1b_power_off(struct device *dev)
1015{
1016 unsigned long delay = DIV_ROUND_UP(512 * USEC_PER_SEC, OG01A1B_MCLK);
1017 struct v4l2_subdev *sd = dev_get_drvdata(dev);
1018 struct og01a1b *og01a1b = to_og01a1b(sd);
1019
1020 if (og01a1b->xvclk)
1021 usleep_range(delay, 2 * delay);
1022
1023 clk_disable_unprepare(og01a1b->xvclk);
1024
1025 gpiod_set_value_cansleep(og01a1b->reset_gpio, 1);
1026
1027 if (og01a1b->dvdd)
1028 regulator_disable(og01a1b->dvdd);
1029
1030 if (og01a1b->dovdd)
1031 regulator_disable(og01a1b->dovdd);
1032
1033 if (og01a1b->avdd)
1034 regulator_disable(og01a1b->avdd);
1035
1036 return 0;
1037}
1038
1039static void og01a1b_remove(struct i2c_client *client)
1040{
1041 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1042 struct og01a1b *og01a1b = to_og01a1b(sd);
1043
1044 v4l2_async_unregister_subdev(sd);
1045 media_entity_cleanup(&sd->entity);
1046 v4l2_ctrl_handler_free(sd->ctrl_handler);
1047 pm_runtime_disable(og01a1b->dev);
1048 mutex_destroy(&og01a1b->mutex);
1049}
1050
1051static int og01a1b_probe(struct i2c_client *client)
1052{
1053 struct og01a1b *og01a1b;
1054 unsigned long freq;
1055 int ret;
1056
1057 og01a1b = devm_kzalloc(&client->dev, sizeof(*og01a1b), GFP_KERNEL);
1058 if (!og01a1b)
1059 return -ENOMEM;
1060
1061 og01a1b->dev = &client->dev;
1062
1063 v4l2_i2c_subdev_init(&og01a1b->sd, client, &og01a1b_subdev_ops);
1064
1065 og01a1b->xvclk = devm_v4l2_sensor_clk_get(og01a1b->dev, NULL);
1066 if (IS_ERR(og01a1b->xvclk))
1067 return dev_err_probe(og01a1b->dev, PTR_ERR(og01a1b->xvclk),
1068 "failed to get xvclk clock\n");
1069
1070 freq = clk_get_rate(og01a1b->xvclk);
1071 if (freq != OG01A1B_MCLK)
1072 return dev_err_probe(og01a1b->dev, -EINVAL,
1073 "external clock %lu is not supported",
1074 freq);
1075
1076 ret = og01a1b_check_hwcfg(og01a1b);
1077 if (ret) {
1078 dev_err(og01a1b->dev, "failed to check HW configuration: %d",
1079 ret);
1080 return ret;
1081 }
1082
1083 og01a1b->reset_gpio = devm_gpiod_get_optional(og01a1b->dev, "reset",
1084 GPIOD_OUT_LOW);
1085 if (IS_ERR(og01a1b->reset_gpio)) {
1086 dev_err(og01a1b->dev, "cannot get reset GPIO\n");
1087 return PTR_ERR(og01a1b->reset_gpio);
1088 }
1089
1090 og01a1b->avdd = devm_regulator_get_optional(og01a1b->dev, "avdd");
1091 if (IS_ERR(og01a1b->avdd)) {
1092 ret = PTR_ERR(og01a1b->avdd);
1093 if (ret != -ENODEV) {
1094 dev_err_probe(og01a1b->dev, ret,
1095 "Failed to get 'avdd' regulator\n");
1096 return ret;
1097 }
1098
1099 og01a1b->avdd = NULL;
1100 }
1101
1102 og01a1b->dovdd = devm_regulator_get_optional(og01a1b->dev, "dovdd");
1103 if (IS_ERR(og01a1b->dovdd)) {
1104 ret = PTR_ERR(og01a1b->dovdd);
1105 if (ret != -ENODEV) {
1106 dev_err_probe(og01a1b->dev, ret,
1107 "Failed to get 'dovdd' regulator\n");
1108 return ret;
1109 }
1110
1111 og01a1b->dovdd = NULL;
1112 }
1113
1114 og01a1b->dvdd = devm_regulator_get_optional(og01a1b->dev, "dvdd");
1115 if (IS_ERR(og01a1b->dvdd)) {
1116 ret = PTR_ERR(og01a1b->dvdd);
1117 if (ret != -ENODEV) {
1118 dev_err_probe(og01a1b->dev, ret,
1119 "Failed to get 'dvdd' regulator\n");
1120 return ret;
1121 }
1122
1123 og01a1b->dvdd = NULL;
1124 }
1125
1126 /* The sensor must be powered on to read the CHIP_ID register */
1127 ret = og01a1b_power_on(og01a1b->dev);
1128 if (ret)
1129 return ret;
1130
1131 ret = og01a1b_identify_module(og01a1b);
1132 if (ret) {
1133 dev_err(og01a1b->dev, "failed to find sensor: %d", ret);
1134 goto power_off;
1135 }
1136
1137 mutex_init(&og01a1b->mutex);
1138 og01a1b->cur_mode = &supported_modes[0];
1139 ret = og01a1b_init_controls(og01a1b);
1140 if (ret) {
1141 dev_err(og01a1b->dev, "failed to init controls: %d", ret);
1142 goto probe_error_v4l2_ctrl_handler_free;
1143 }
1144
1145 og01a1b->sd.internal_ops = &og01a1b_internal_ops;
1146 og01a1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1147 og01a1b->sd.entity.ops = &og01a1b_subdev_entity_ops;
1148 og01a1b->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1149 og01a1b->pad.flags = MEDIA_PAD_FL_SOURCE;
1150 ret = media_entity_pads_init(&og01a1b->sd.entity, 1, &og01a1b->pad);
1151 if (ret) {
1152 dev_err(og01a1b->dev, "failed to init entity pads: %d", ret);
1153 goto probe_error_v4l2_ctrl_handler_free;
1154 }
1155
1156 ret = v4l2_async_register_subdev_sensor(&og01a1b->sd);
1157 if (ret < 0) {
1158 dev_err(og01a1b->dev, "failed to register V4L2 subdev: %d",
1159 ret);
1160 goto probe_error_media_entity_cleanup;
1161 }
1162
1163 /* Enable runtime PM and turn off the device */
1164 pm_runtime_set_active(og01a1b->dev);
1165 pm_runtime_enable(og01a1b->dev);
1166 pm_runtime_idle(og01a1b->dev);
1167
1168 return 0;
1169
1170probe_error_media_entity_cleanup:
1171 media_entity_cleanup(&og01a1b->sd.entity);
1172
1173probe_error_v4l2_ctrl_handler_free:
1174 v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler);
1175 mutex_destroy(&og01a1b->mutex);
1176
1177power_off:
1178 og01a1b_power_off(og01a1b->dev);
1179
1180 return ret;
1181}
1182
1183static const struct dev_pm_ops og01a1b_pm_ops = {
1184 SET_RUNTIME_PM_OPS(og01a1b_power_off, og01a1b_power_on, NULL)
1185};
1186
1187#ifdef CONFIG_ACPI
1188static const struct acpi_device_id og01a1b_acpi_ids[] = {
1189 {"OVTI01AC"},
1190 {}
1191};
1192
1193MODULE_DEVICE_TABLE(acpi, og01a1b_acpi_ids);
1194#endif
1195
1196static const struct of_device_id og01a1b_of_match[] = {
1197 { .compatible = "ovti,og01a1b" },
1198 { /* sentinel */ }
1199};
1200MODULE_DEVICE_TABLE(of, og01a1b_of_match);
1201
1202static struct i2c_driver og01a1b_i2c_driver = {
1203 .driver = {
1204 .name = "og01a1b",
1205 .pm = &og01a1b_pm_ops,
1206 .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids),
1207 .of_match_table = og01a1b_of_match,
1208 },
1209 .probe = og01a1b_probe,
1210 .remove = og01a1b_remove,
1211};
1212
1213module_i2c_driver(og01a1b_i2c_driver);
1214
1215MODULE_AUTHOR("Shawn Tu");
1216MODULE_DESCRIPTION("OmniVision OG01A1B sensor driver");
1217MODULE_LICENSE("GPL v2");