1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2020 MediaTek Inc. |
3 | |
4 | #include <linux/clk.h> |
5 | #include <linux/delay.h> |
6 | #include <linux/device.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/units.h> |
13 | #include <media/media-entity.h> |
14 | #include <media/v4l2-async.h> |
15 | #include <media/v4l2-ctrls.h> |
16 | #include <media/v4l2-fwnode.h> |
17 | #include <media/v4l2-subdev.h> |
18 | |
19 | #define OV02A10_ID 0x2509 |
20 | #define OV02A10_ID_MASK GENMASK(15, 0) |
21 | |
22 | #define OV02A10_REG_CHIP_ID 0x02 |
23 | |
24 | /* Bit[1] vertical upside down */ |
25 | /* Bit[0] horizontal mirror */ |
26 | #define REG_MIRROR_FLIP_CONTROL 0x3f |
27 | |
28 | /* Orientation */ |
29 | #define REG_MIRROR_FLIP_ENABLE 0x03 |
30 | |
31 | /* Bit[2:0] MIPI transmission speed select */ |
32 | #define TX_SPEED_AREA_SEL 0xa1 |
33 | #define OV02A10_MIPI_TX_SPEED_DEFAULT 0x04 |
34 | |
35 | #define REG_PAGE_SWITCH 0xfd |
36 | #define REG_GLOBAL_EFFECTIVE 0x01 |
37 | #define REG_ENABLE BIT(0) |
38 | |
39 | #define REG_SC_CTRL_MODE 0xac |
40 | #define SC_CTRL_MODE_STANDBY 0x00 |
41 | #define SC_CTRL_MODE_STREAMING 0x01 |
42 | |
43 | /* Exposure control */ |
44 | #define OV02A10_EXP_SHIFT 8 |
45 | #define OV02A10_REG_EXPOSURE_H 0x03 |
46 | #define OV02A10_REG_EXPOSURE_L 0x04 |
47 | #define OV02A10_EXPOSURE_MIN 4 |
48 | #define OV02A10_EXPOSURE_MAX_MARGIN 4 |
49 | #define OV02A10_EXPOSURE_STEP 1 |
50 | |
51 | /* Vblanking control */ |
52 | #define OV02A10_VTS_SHIFT 8 |
53 | #define OV02A10_REG_VTS_H 0x05 |
54 | #define OV02A10_REG_VTS_L 0x06 |
55 | #define OV02A10_VTS_MAX 0x209f |
56 | #define OV02A10_BASE_LINES 1224 |
57 | |
58 | /* Analog gain control */ |
59 | #define OV02A10_REG_GAIN 0x24 |
60 | #define OV02A10_GAIN_MIN 0x10 |
61 | #define OV02A10_GAIN_MAX 0xf8 |
62 | #define OV02A10_GAIN_STEP 0x01 |
63 | #define OV02A10_GAIN_DEFAULT 0x40 |
64 | |
65 | /* Test pattern control */ |
66 | #define OV02A10_REG_TEST_PATTERN 0xb6 |
67 | |
68 | #define OV02A10_LINK_FREQ_390MHZ (390 * HZ_PER_MHZ) |
69 | #define OV02A10_ECLK_FREQ (24 * HZ_PER_MHZ) |
70 | |
71 | /* Number of lanes supported by this driver */ |
72 | #define OV02A10_DATA_LANES 1 |
73 | |
74 | /* Bits per sample of sensor output */ |
75 | #define OV02A10_BITS_PER_SAMPLE 10 |
76 | |
77 | static const char * const ov02a10_supply_names[] = { |
78 | "dovdd" , /* Digital I/O power */ |
79 | "avdd" , /* Analog power */ |
80 | "dvdd" , /* Digital core power */ |
81 | }; |
82 | |
83 | struct ov02a10_reg { |
84 | u8 addr; |
85 | u8 val; |
86 | }; |
87 | |
88 | struct ov02a10_reg_list { |
89 | u32 num_of_regs; |
90 | const struct ov02a10_reg *regs; |
91 | }; |
92 | |
93 | struct ov02a10_mode { |
94 | u32 width; |
95 | u32 height; |
96 | u32 exp_def; |
97 | u32 hts_def; |
98 | u32 vts_def; |
99 | const struct ov02a10_reg_list reg_list; |
100 | }; |
101 | |
102 | struct ov02a10 { |
103 | u32 eclk_freq; |
104 | /* Indication of MIPI transmission speed select */ |
105 | u32 mipi_clock_voltage; |
106 | |
107 | struct clk *eclk; |
108 | struct gpio_desc *pd_gpio; |
109 | struct gpio_desc *rst_gpio; |
110 | struct regulator_bulk_data supplies[ARRAY_SIZE(ov02a10_supply_names)]; |
111 | |
112 | bool streaming; |
113 | bool upside_down; |
114 | |
115 | /* |
116 | * Serialize control access, get/set format, get selection |
117 | * and start streaming. |
118 | */ |
119 | struct mutex mutex; |
120 | struct v4l2_subdev subdev; |
121 | struct media_pad pad; |
122 | struct v4l2_mbus_framefmt fmt; |
123 | struct v4l2_ctrl_handler ctrl_handler; |
124 | struct v4l2_ctrl *exposure; |
125 | |
126 | const struct ov02a10_mode *cur_mode; |
127 | }; |
128 | |
129 | static inline struct ov02a10 *to_ov02a10(struct v4l2_subdev *sd) |
130 | { |
131 | return container_of(sd, struct ov02a10, subdev); |
132 | } |
133 | |
134 | /* |
135 | * eclk 24Mhz |
136 | * pclk 39Mhz |
137 | * linelength 934(0x3a6) |
138 | * framelength 1390(0x56E) |
139 | * grabwindow_width 1600 |
140 | * grabwindow_height 1200 |
141 | * max_framerate 30fps |
142 | * mipi_datarate per lane 780Mbps |
143 | */ |
144 | static const struct ov02a10_reg ov02a10_1600x1200_regs[] = { |
145 | {0xfd, 0x01}, |
146 | {0xac, 0x00}, |
147 | {0xfd, 0x00}, |
148 | {0x2f, 0x29}, |
149 | {0x34, 0x00}, |
150 | {0x35, 0x21}, |
151 | {0x30, 0x15}, |
152 | {0x33, 0x01}, |
153 | {0xfd, 0x01}, |
154 | {0x44, 0x00}, |
155 | {0x2a, 0x4c}, |
156 | {0x2b, 0x1e}, |
157 | {0x2c, 0x60}, |
158 | {0x25, 0x11}, |
159 | {0x03, 0x01}, |
160 | {0x04, 0xae}, |
161 | {0x09, 0x00}, |
162 | {0x0a, 0x02}, |
163 | {0x06, 0xa6}, |
164 | {0x31, 0x00}, |
165 | {0x24, 0x40}, |
166 | {0x01, 0x01}, |
167 | {0xfb, 0x73}, |
168 | {0xfd, 0x01}, |
169 | {0x16, 0x04}, |
170 | {0x1c, 0x09}, |
171 | {0x21, 0x42}, |
172 | {0x12, 0x04}, |
173 | {0x13, 0x10}, |
174 | {0x11, 0x40}, |
175 | {0x33, 0x81}, |
176 | {0xd0, 0x00}, |
177 | {0xd1, 0x01}, |
178 | {0xd2, 0x00}, |
179 | {0x50, 0x10}, |
180 | {0x51, 0x23}, |
181 | {0x52, 0x20}, |
182 | {0x53, 0x10}, |
183 | {0x54, 0x02}, |
184 | {0x55, 0x20}, |
185 | {0x56, 0x02}, |
186 | {0x58, 0x48}, |
187 | {0x5d, 0x15}, |
188 | {0x5e, 0x05}, |
189 | {0x66, 0x66}, |
190 | {0x68, 0x68}, |
191 | {0x6b, 0x00}, |
192 | {0x6c, 0x00}, |
193 | {0x6f, 0x40}, |
194 | {0x70, 0x40}, |
195 | {0x71, 0x0a}, |
196 | {0x72, 0xf0}, |
197 | {0x73, 0x10}, |
198 | {0x75, 0x80}, |
199 | {0x76, 0x10}, |
200 | {0x84, 0x00}, |
201 | {0x85, 0x10}, |
202 | {0x86, 0x10}, |
203 | {0x87, 0x00}, |
204 | {0x8a, 0x22}, |
205 | {0x8b, 0x22}, |
206 | {0x19, 0xf1}, |
207 | {0x29, 0x01}, |
208 | {0xfd, 0x01}, |
209 | {0x9d, 0x16}, |
210 | {0xa0, 0x29}, |
211 | {0xa1, 0x04}, |
212 | {0xad, 0x62}, |
213 | {0xae, 0x00}, |
214 | {0xaf, 0x85}, |
215 | {0xb1, 0x01}, |
216 | {0x8e, 0x06}, |
217 | {0x8f, 0x40}, |
218 | {0x90, 0x04}, |
219 | {0x91, 0xb0}, |
220 | {0x45, 0x01}, |
221 | {0x46, 0x00}, |
222 | {0x47, 0x6c}, |
223 | {0x48, 0x03}, |
224 | {0x49, 0x8b}, |
225 | {0x4a, 0x00}, |
226 | {0x4b, 0x07}, |
227 | {0x4c, 0x04}, |
228 | {0x4d, 0xb7}, |
229 | {0xf0, 0x40}, |
230 | {0xf1, 0x40}, |
231 | {0xf2, 0x40}, |
232 | {0xf3, 0x40}, |
233 | {0x3f, 0x00}, |
234 | {0xfd, 0x01}, |
235 | {0x05, 0x00}, |
236 | {0x06, 0xa6}, |
237 | {0xfd, 0x01}, |
238 | }; |
239 | |
240 | static const char * const [] = { |
241 | "Disabled" , |
242 | "Eight Vertical Colour Bars" , |
243 | }; |
244 | |
245 | static const s64 [] = { |
246 | OV02A10_LINK_FREQ_390MHZ, |
247 | }; |
248 | |
249 | static u64 to_pixel_rate(u32 f_index) |
250 | { |
251 | u64 pixel_rate = link_freq_menu_items[f_index] * 2 * OV02A10_DATA_LANES; |
252 | |
253 | do_div(pixel_rate, OV02A10_BITS_PER_SAMPLE); |
254 | |
255 | return pixel_rate; |
256 | } |
257 | |
258 | static const struct ov02a10_mode supported_modes[] = { |
259 | { |
260 | .width = 1600, |
261 | .height = 1200, |
262 | .exp_def = 0x01ae, |
263 | .hts_def = 0x03a6, |
264 | .vts_def = 0x056e, |
265 | .reg_list = { |
266 | .num_of_regs = ARRAY_SIZE(ov02a10_1600x1200_regs), |
267 | .regs = ov02a10_1600x1200_regs, |
268 | }, |
269 | }, |
270 | }; |
271 | |
272 | static int ov02a10_write_array(struct ov02a10 *ov02a10, |
273 | const struct ov02a10_reg_list *r_list) |
274 | { |
275 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
276 | unsigned int i; |
277 | int ret; |
278 | |
279 | for (i = 0; i < r_list->num_of_regs; i++) { |
280 | ret = i2c_smbus_write_byte_data(client, command: r_list->regs[i].addr, |
281 | value: r_list->regs[i].val); |
282 | if (ret < 0) |
283 | return ret; |
284 | } |
285 | |
286 | return 0; |
287 | } |
288 | |
289 | static void ov02a10_fill_fmt(const struct ov02a10_mode *mode, |
290 | struct v4l2_mbus_framefmt *fmt) |
291 | { |
292 | fmt->width = mode->width; |
293 | fmt->height = mode->height; |
294 | fmt->field = V4L2_FIELD_NONE; |
295 | } |
296 | |
297 | static int ov02a10_set_fmt(struct v4l2_subdev *sd, |
298 | struct v4l2_subdev_state *sd_state, |
299 | struct v4l2_subdev_format *fmt) |
300 | { |
301 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
302 | struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; |
303 | struct v4l2_mbus_framefmt *frame_fmt; |
304 | int ret = 0; |
305 | |
306 | mutex_lock(&ov02a10->mutex); |
307 | |
308 | if (ov02a10->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
309 | ret = -EBUSY; |
310 | goto out_unlock; |
311 | } |
312 | |
313 | /* Only one sensor mode supported */ |
314 | mbus_fmt->code = ov02a10->fmt.code; |
315 | ov02a10_fill_fmt(mode: ov02a10->cur_mode, fmt: mbus_fmt); |
316 | |
317 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) |
318 | frame_fmt = v4l2_subdev_state_get_format(sd_state, 0); |
319 | else |
320 | frame_fmt = &ov02a10->fmt; |
321 | |
322 | *frame_fmt = *mbus_fmt; |
323 | |
324 | out_unlock: |
325 | mutex_unlock(lock: &ov02a10->mutex); |
326 | return ret; |
327 | } |
328 | |
329 | static int ov02a10_get_fmt(struct v4l2_subdev *sd, |
330 | struct v4l2_subdev_state *sd_state, |
331 | struct v4l2_subdev_format *fmt) |
332 | { |
333 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
334 | struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; |
335 | |
336 | mutex_lock(&ov02a10->mutex); |
337 | |
338 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
339 | fmt->format = *v4l2_subdev_state_get_format(sd_state, |
340 | fmt->pad); |
341 | } else { |
342 | fmt->format = ov02a10->fmt; |
343 | mbus_fmt->code = ov02a10->fmt.code; |
344 | ov02a10_fill_fmt(mode: ov02a10->cur_mode, fmt: mbus_fmt); |
345 | } |
346 | |
347 | mutex_unlock(lock: &ov02a10->mutex); |
348 | |
349 | return 0; |
350 | } |
351 | |
352 | static int ov02a10_enum_mbus_code(struct v4l2_subdev *sd, |
353 | struct v4l2_subdev_state *sd_state, |
354 | struct v4l2_subdev_mbus_code_enum *code) |
355 | { |
356 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
357 | |
358 | if (code->index != 0) |
359 | return -EINVAL; |
360 | |
361 | code->code = ov02a10->fmt.code; |
362 | |
363 | return 0; |
364 | } |
365 | |
366 | static int ov02a10_enum_frame_sizes(struct v4l2_subdev *sd, |
367 | struct v4l2_subdev_state *sd_state, |
368 | struct v4l2_subdev_frame_size_enum *fse) |
369 | { |
370 | if (fse->index >= ARRAY_SIZE(supported_modes)) |
371 | return -EINVAL; |
372 | |
373 | fse->min_width = supported_modes[fse->index].width; |
374 | fse->max_width = supported_modes[fse->index].width; |
375 | fse->max_height = supported_modes[fse->index].height; |
376 | fse->min_height = supported_modes[fse->index].height; |
377 | |
378 | return 0; |
379 | } |
380 | |
381 | static int ov02a10_check_sensor_id(struct ov02a10 *ov02a10) |
382 | { |
383 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
384 | u16 chip_id; |
385 | int ret; |
386 | |
387 | /* Validate the chip ID */ |
388 | ret = i2c_smbus_read_word_swapped(client, OV02A10_REG_CHIP_ID); |
389 | if (ret < 0) |
390 | return ret; |
391 | |
392 | chip_id = le16_to_cpu((__force __le16)ret); |
393 | |
394 | if ((chip_id & OV02A10_ID_MASK) != OV02A10_ID) { |
395 | dev_err(&client->dev, "unexpected sensor id(0x%04x)\n" , chip_id); |
396 | return -EINVAL; |
397 | } |
398 | |
399 | return 0; |
400 | } |
401 | |
402 | static int ov02a10_power_on(struct device *dev) |
403 | { |
404 | struct i2c_client *client = to_i2c_client(dev); |
405 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
406 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
407 | int ret; |
408 | |
409 | gpiod_set_value_cansleep(desc: ov02a10->rst_gpio, value: 1); |
410 | gpiod_set_value_cansleep(desc: ov02a10->pd_gpio, value: 1); |
411 | |
412 | ret = clk_prepare_enable(clk: ov02a10->eclk); |
413 | if (ret < 0) { |
414 | dev_err(dev, "failed to enable eclk\n" ); |
415 | return ret; |
416 | } |
417 | |
418 | ret = regulator_bulk_enable(ARRAY_SIZE(ov02a10_supply_names), |
419 | consumers: ov02a10->supplies); |
420 | if (ret < 0) { |
421 | dev_err(dev, "failed to enable regulators\n" ); |
422 | goto disable_clk; |
423 | } |
424 | usleep_range(min: 5000, max: 6000); |
425 | |
426 | gpiod_set_value_cansleep(desc: ov02a10->pd_gpio, value: 0); |
427 | usleep_range(min: 5000, max: 6000); |
428 | |
429 | gpiod_set_value_cansleep(desc: ov02a10->rst_gpio, value: 0); |
430 | usleep_range(min: 5000, max: 6000); |
431 | |
432 | ret = ov02a10_check_sensor_id(ov02a10); |
433 | if (ret) |
434 | goto disable_regulator; |
435 | |
436 | return 0; |
437 | |
438 | disable_regulator: |
439 | regulator_bulk_disable(ARRAY_SIZE(ov02a10_supply_names), |
440 | consumers: ov02a10->supplies); |
441 | disable_clk: |
442 | clk_disable_unprepare(clk: ov02a10->eclk); |
443 | |
444 | return ret; |
445 | } |
446 | |
447 | static int ov02a10_power_off(struct device *dev) |
448 | { |
449 | struct i2c_client *client = to_i2c_client(dev); |
450 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
451 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
452 | |
453 | gpiod_set_value_cansleep(desc: ov02a10->rst_gpio, value: 1); |
454 | clk_disable_unprepare(clk: ov02a10->eclk); |
455 | gpiod_set_value_cansleep(desc: ov02a10->pd_gpio, value: 1); |
456 | regulator_bulk_disable(ARRAY_SIZE(ov02a10_supply_names), |
457 | consumers: ov02a10->supplies); |
458 | |
459 | return 0; |
460 | } |
461 | |
462 | static int __ov02a10_start_stream(struct ov02a10 *ov02a10) |
463 | { |
464 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
465 | const struct ov02a10_reg_list *reg_list; |
466 | int ret; |
467 | |
468 | /* Apply default values of current mode */ |
469 | reg_list = &ov02a10->cur_mode->reg_list; |
470 | ret = ov02a10_write_array(ov02a10, r_list: reg_list); |
471 | if (ret) |
472 | return ret; |
473 | |
474 | /* Apply customized values from user */ |
475 | ret = __v4l2_ctrl_handler_setup(hdl: ov02a10->subdev.ctrl_handler); |
476 | if (ret) |
477 | return ret; |
478 | |
479 | /* Set orientation to 180 degree */ |
480 | if (ov02a10->upside_down) { |
481 | ret = i2c_smbus_write_byte_data(client, REG_MIRROR_FLIP_CONTROL, |
482 | REG_MIRROR_FLIP_ENABLE); |
483 | if (ret < 0) { |
484 | dev_err(&client->dev, "failed to set orientation\n" ); |
485 | return ret; |
486 | } |
487 | ret = i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE, |
488 | REG_ENABLE); |
489 | if (ret < 0) |
490 | return ret; |
491 | } |
492 | |
493 | /* Set MIPI TX speed according to DT property */ |
494 | if (ov02a10->mipi_clock_voltage != OV02A10_MIPI_TX_SPEED_DEFAULT) { |
495 | ret = i2c_smbus_write_byte_data(client, TX_SPEED_AREA_SEL, |
496 | value: ov02a10->mipi_clock_voltage); |
497 | if (ret < 0) |
498 | return ret; |
499 | } |
500 | |
501 | /* Set stream on register */ |
502 | return i2c_smbus_write_byte_data(client, REG_SC_CTRL_MODE, |
503 | SC_CTRL_MODE_STREAMING); |
504 | } |
505 | |
506 | static int __ov02a10_stop_stream(struct ov02a10 *ov02a10) |
507 | { |
508 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
509 | |
510 | return i2c_smbus_write_byte_data(client, REG_SC_CTRL_MODE, |
511 | SC_CTRL_MODE_STANDBY); |
512 | } |
513 | |
514 | static int ov02a10_init_state(struct v4l2_subdev *sd, |
515 | struct v4l2_subdev_state *sd_state) |
516 | { |
517 | struct v4l2_subdev_format fmt = { |
518 | .which = V4L2_SUBDEV_FORMAT_TRY, |
519 | .format = { |
520 | .width = 1600, |
521 | .height = 1200, |
522 | } |
523 | }; |
524 | |
525 | ov02a10_set_fmt(sd, sd_state, fmt: &fmt); |
526 | |
527 | return 0; |
528 | } |
529 | |
530 | static int ov02a10_s_stream(struct v4l2_subdev *sd, int on) |
531 | { |
532 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
533 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
534 | int ret; |
535 | |
536 | mutex_lock(&ov02a10->mutex); |
537 | |
538 | if (ov02a10->streaming == on) { |
539 | ret = 0; |
540 | goto unlock_and_return; |
541 | } |
542 | |
543 | if (on) { |
544 | ret = pm_runtime_resume_and_get(dev: &client->dev); |
545 | if (ret < 0) |
546 | goto unlock_and_return; |
547 | |
548 | ret = __ov02a10_start_stream(ov02a10); |
549 | if (ret) { |
550 | __ov02a10_stop_stream(ov02a10); |
551 | ov02a10->streaming = !on; |
552 | goto err_rpm_put; |
553 | } |
554 | } else { |
555 | __ov02a10_stop_stream(ov02a10); |
556 | pm_runtime_put(dev: &client->dev); |
557 | } |
558 | |
559 | ov02a10->streaming = on; |
560 | mutex_unlock(lock: &ov02a10->mutex); |
561 | |
562 | return 0; |
563 | |
564 | err_rpm_put: |
565 | pm_runtime_put(dev: &client->dev); |
566 | unlock_and_return: |
567 | mutex_unlock(lock: &ov02a10->mutex); |
568 | |
569 | return ret; |
570 | } |
571 | |
572 | static const struct dev_pm_ops ov02a10_pm_ops = { |
573 | SET_RUNTIME_PM_OPS(ov02a10_power_off, ov02a10_power_on, NULL) |
574 | }; |
575 | |
576 | static int ov02a10_set_exposure(struct ov02a10 *ov02a10, int val) |
577 | { |
578 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
579 | int ret; |
580 | |
581 | ret = i2c_smbus_write_byte_data(client, REG_PAGE_SWITCH, REG_ENABLE); |
582 | if (ret < 0) |
583 | return ret; |
584 | |
585 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_EXPOSURE_H, |
586 | value: val >> OV02A10_EXP_SHIFT); |
587 | if (ret < 0) |
588 | return ret; |
589 | |
590 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_EXPOSURE_L, value: val); |
591 | if (ret < 0) |
592 | return ret; |
593 | |
594 | return i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE, |
595 | REG_ENABLE); |
596 | } |
597 | |
598 | static int ov02a10_set_gain(struct ov02a10 *ov02a10, int val) |
599 | { |
600 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
601 | int ret; |
602 | |
603 | ret = i2c_smbus_write_byte_data(client, REG_PAGE_SWITCH, REG_ENABLE); |
604 | if (ret < 0) |
605 | return ret; |
606 | |
607 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_GAIN, value: val); |
608 | if (ret < 0) |
609 | return ret; |
610 | |
611 | return i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE, |
612 | REG_ENABLE); |
613 | } |
614 | |
615 | static int ov02a10_set_vblank(struct ov02a10 *ov02a10, int val) |
616 | { |
617 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
618 | u32 vts = val + ov02a10->cur_mode->height - OV02A10_BASE_LINES; |
619 | int ret; |
620 | |
621 | ret = i2c_smbus_write_byte_data(client, REG_PAGE_SWITCH, REG_ENABLE); |
622 | if (ret < 0) |
623 | return ret; |
624 | |
625 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_VTS_H, |
626 | value: vts >> OV02A10_VTS_SHIFT); |
627 | if (ret < 0) |
628 | return ret; |
629 | |
630 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_VTS_L, value: vts); |
631 | if (ret < 0) |
632 | return ret; |
633 | |
634 | return i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE, |
635 | REG_ENABLE); |
636 | } |
637 | |
638 | static int ov02a10_set_test_pattern(struct ov02a10 *ov02a10, int pattern) |
639 | { |
640 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
641 | int ret; |
642 | |
643 | ret = i2c_smbus_write_byte_data(client, REG_PAGE_SWITCH, REG_ENABLE); |
644 | if (ret < 0) |
645 | return ret; |
646 | |
647 | ret = i2c_smbus_write_byte_data(client, OV02A10_REG_TEST_PATTERN, |
648 | value: pattern); |
649 | if (ret < 0) |
650 | return ret; |
651 | |
652 | ret = i2c_smbus_write_byte_data(client, REG_GLOBAL_EFFECTIVE, |
653 | REG_ENABLE); |
654 | if (ret < 0) |
655 | return ret; |
656 | |
657 | return i2c_smbus_write_byte_data(client, REG_SC_CTRL_MODE, |
658 | SC_CTRL_MODE_STREAMING); |
659 | } |
660 | |
661 | static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl) |
662 | { |
663 | struct ov02a10 *ov02a10 = container_of(ctrl->handler, |
664 | struct ov02a10, ctrl_handler); |
665 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
666 | s64 max_expo; |
667 | int ret; |
668 | |
669 | /* Propagate change of current control to all related controls */ |
670 | if (ctrl->id == V4L2_CID_VBLANK) { |
671 | /* Update max exposure while meeting expected vblanking */ |
672 | max_expo = ov02a10->cur_mode->height + ctrl->val - |
673 | OV02A10_EXPOSURE_MAX_MARGIN; |
674 | __v4l2_ctrl_modify_range(ctrl: ov02a10->exposure, |
675 | min: ov02a10->exposure->minimum, max: max_expo, |
676 | step: ov02a10->exposure->step, |
677 | def: ov02a10->exposure->default_value); |
678 | } |
679 | |
680 | /* V4L2 controls values will be applied only when power is already up */ |
681 | if (!pm_runtime_get_if_in_use(dev: &client->dev)) |
682 | return 0; |
683 | |
684 | switch (ctrl->id) { |
685 | case V4L2_CID_EXPOSURE: |
686 | ret = ov02a10_set_exposure(ov02a10, val: ctrl->val); |
687 | break; |
688 | case V4L2_CID_ANALOGUE_GAIN: |
689 | ret = ov02a10_set_gain(ov02a10, val: ctrl->val); |
690 | break; |
691 | case V4L2_CID_VBLANK: |
692 | ret = ov02a10_set_vblank(ov02a10, val: ctrl->val); |
693 | break; |
694 | case V4L2_CID_TEST_PATTERN: |
695 | ret = ov02a10_set_test_pattern(ov02a10, pattern: ctrl->val); |
696 | break; |
697 | default: |
698 | ret = -EINVAL; |
699 | break; |
700 | } |
701 | |
702 | pm_runtime_put(dev: &client->dev); |
703 | |
704 | return ret; |
705 | } |
706 | |
707 | static const struct v4l2_subdev_video_ops ov02a10_video_ops = { |
708 | .s_stream = ov02a10_s_stream, |
709 | }; |
710 | |
711 | static const struct v4l2_subdev_pad_ops ov02a10_pad_ops = { |
712 | .enum_mbus_code = ov02a10_enum_mbus_code, |
713 | .enum_frame_size = ov02a10_enum_frame_sizes, |
714 | .get_fmt = ov02a10_get_fmt, |
715 | .set_fmt = ov02a10_set_fmt, |
716 | }; |
717 | |
718 | static const struct v4l2_subdev_ops ov02a10_subdev_ops = { |
719 | .video = &ov02a10_video_ops, |
720 | .pad = &ov02a10_pad_ops, |
721 | }; |
722 | |
723 | static const struct v4l2_subdev_internal_ops ov02a10_internal_ops = { |
724 | .init_state = ov02a10_init_state, |
725 | }; |
726 | |
727 | static const struct media_entity_operations ov02a10_subdev_entity_ops = { |
728 | .link_validate = v4l2_subdev_link_validate, |
729 | }; |
730 | |
731 | static const struct v4l2_ctrl_ops ov02a10_ctrl_ops = { |
732 | .s_ctrl = ov02a10_set_ctrl, |
733 | }; |
734 | |
735 | static int ov02a10_initialize_controls(struct ov02a10 *ov02a10) |
736 | { |
737 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov02a10->subdev); |
738 | const struct ov02a10_mode *mode; |
739 | struct v4l2_ctrl_handler *handler; |
740 | struct v4l2_ctrl *ctrl; |
741 | s64 exposure_max; |
742 | s64 vblank_def; |
743 | s64 pixel_rate; |
744 | s64 h_blank; |
745 | int ret; |
746 | |
747 | handler = &ov02a10->ctrl_handler; |
748 | mode = ov02a10->cur_mode; |
749 | ret = v4l2_ctrl_handler_init(handler, 7); |
750 | if (ret) |
751 | return ret; |
752 | |
753 | handler->lock = &ov02a10->mutex; |
754 | |
755 | ctrl = v4l2_ctrl_new_int_menu(hdl: handler, NULL, V4L2_CID_LINK_FREQ, max: 0, def: 0, |
756 | qmenu_int: link_freq_menu_items); |
757 | if (ctrl) |
758 | ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
759 | |
760 | pixel_rate = to_pixel_rate(f_index: 0); |
761 | v4l2_ctrl_new_std(hdl: handler, NULL, V4L2_CID_PIXEL_RATE, min: 0, max: pixel_rate, step: 1, |
762 | def: pixel_rate); |
763 | |
764 | h_blank = mode->hts_def - mode->width; |
765 | v4l2_ctrl_new_std(hdl: handler, NULL, V4L2_CID_HBLANK, min: h_blank, max: h_blank, step: 1, |
766 | def: h_blank); |
767 | |
768 | vblank_def = mode->vts_def - mode->height; |
769 | v4l2_ctrl_new_std(hdl: handler, ops: &ov02a10_ctrl_ops, V4L2_CID_VBLANK, |
770 | min: vblank_def, OV02A10_VTS_MAX - mode->height, step: 1, |
771 | def: vblank_def); |
772 | |
773 | exposure_max = mode->vts_def - 4; |
774 | ov02a10->exposure = v4l2_ctrl_new_std(hdl: handler, ops: &ov02a10_ctrl_ops, |
775 | V4L2_CID_EXPOSURE, |
776 | OV02A10_EXPOSURE_MIN, |
777 | max: exposure_max, |
778 | OV02A10_EXPOSURE_STEP, |
779 | def: mode->exp_def); |
780 | |
781 | v4l2_ctrl_new_std(hdl: handler, ops: &ov02a10_ctrl_ops, |
782 | V4L2_CID_ANALOGUE_GAIN, OV02A10_GAIN_MIN, |
783 | OV02A10_GAIN_MAX, OV02A10_GAIN_STEP, |
784 | OV02A10_GAIN_DEFAULT); |
785 | |
786 | v4l2_ctrl_new_std_menu_items(hdl: handler, ops: &ov02a10_ctrl_ops, |
787 | V4L2_CID_TEST_PATTERN, |
788 | ARRAY_SIZE(ov02a10_test_pattern_menu) - 1, |
789 | mask: 0, def: 0, qmenu: ov02a10_test_pattern_menu); |
790 | |
791 | if (handler->error) { |
792 | ret = handler->error; |
793 | dev_err(&client->dev, "failed to init controls(%d)\n" , ret); |
794 | goto err_free_handler; |
795 | } |
796 | |
797 | ov02a10->subdev.ctrl_handler = handler; |
798 | |
799 | return 0; |
800 | |
801 | err_free_handler: |
802 | v4l2_ctrl_handler_free(hdl: handler); |
803 | |
804 | return ret; |
805 | } |
806 | |
807 | static int ov02a10_check_hwcfg(struct device *dev, struct ov02a10 *ov02a10) |
808 | { |
809 | struct fwnode_handle *ep; |
810 | struct fwnode_handle *fwnode = dev_fwnode(dev); |
811 | struct v4l2_fwnode_endpoint bus_cfg = { |
812 | .bus_type = V4L2_MBUS_CSI2_DPHY, |
813 | }; |
814 | unsigned int i, j; |
815 | u32 clk_volt; |
816 | int ret; |
817 | |
818 | if (!fwnode) |
819 | return -EINVAL; |
820 | |
821 | ep = fwnode_graph_get_next_endpoint(fwnode, NULL); |
822 | if (!ep) |
823 | return -ENXIO; |
824 | |
825 | ret = v4l2_fwnode_endpoint_alloc_parse(fwnode: ep, vep: &bus_cfg); |
826 | fwnode_handle_put(fwnode: ep); |
827 | if (ret) |
828 | return ret; |
829 | |
830 | /* Optional indication of MIPI clock voltage unit */ |
831 | ret = fwnode_property_read_u32(fwnode: ep, propname: "ovti,mipi-clock-voltage" , |
832 | val: &clk_volt); |
833 | |
834 | if (!ret) |
835 | ov02a10->mipi_clock_voltage = clk_volt; |
836 | |
837 | for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { |
838 | for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { |
839 | if (link_freq_menu_items[i] == |
840 | bus_cfg.link_frequencies[j]) |
841 | break; |
842 | } |
843 | |
844 | if (j == bus_cfg.nr_of_link_frequencies) { |
845 | dev_err(dev, "no link frequency %lld supported\n" , |
846 | link_freq_menu_items[i]); |
847 | ret = -EINVAL; |
848 | break; |
849 | } |
850 | } |
851 | |
852 | v4l2_fwnode_endpoint_free(vep: &bus_cfg); |
853 | |
854 | return ret; |
855 | } |
856 | |
857 | static int ov02a10_probe(struct i2c_client *client) |
858 | { |
859 | struct device *dev = &client->dev; |
860 | struct ov02a10 *ov02a10; |
861 | unsigned int i; |
862 | unsigned int rotation; |
863 | int ret; |
864 | |
865 | ov02a10 = devm_kzalloc(dev, size: sizeof(*ov02a10), GFP_KERNEL); |
866 | if (!ov02a10) |
867 | return -ENOMEM; |
868 | |
869 | ret = ov02a10_check_hwcfg(dev, ov02a10); |
870 | if (ret) |
871 | return dev_err_probe(dev, err: ret, |
872 | fmt: "failed to check HW configuration\n" ); |
873 | |
874 | v4l2_i2c_subdev_init(sd: &ov02a10->subdev, client, ops: &ov02a10_subdev_ops); |
875 | ov02a10->subdev.internal_ops = &ov02a10_internal_ops; |
876 | |
877 | ov02a10->mipi_clock_voltage = OV02A10_MIPI_TX_SPEED_DEFAULT; |
878 | ov02a10->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10; |
879 | |
880 | /* Optional indication of physical rotation of sensor */ |
881 | rotation = 0; |
882 | device_property_read_u32(dev, propname: "rotation" , val: &rotation); |
883 | if (rotation == 180) { |
884 | ov02a10->upside_down = true; |
885 | ov02a10->fmt.code = MEDIA_BUS_FMT_SRGGB10_1X10; |
886 | } |
887 | |
888 | ov02a10->eclk = devm_clk_get(dev, id: "eclk" ); |
889 | if (IS_ERR(ptr: ov02a10->eclk)) |
890 | return dev_err_probe(dev, err: PTR_ERR(ptr: ov02a10->eclk), |
891 | fmt: "failed to get eclk\n" ); |
892 | |
893 | ret = device_property_read_u32(dev, propname: "clock-frequency" , |
894 | val: &ov02a10->eclk_freq); |
895 | if (ret < 0) |
896 | return dev_err_probe(dev, err: ret, |
897 | fmt: "failed to get eclk frequency\n" ); |
898 | |
899 | ret = clk_set_rate(clk: ov02a10->eclk, rate: ov02a10->eclk_freq); |
900 | if (ret < 0) |
901 | return dev_err_probe(dev, err: ret, |
902 | fmt: "failed to set eclk frequency (24MHz)\n" ); |
903 | |
904 | if (clk_get_rate(clk: ov02a10->eclk) != OV02A10_ECLK_FREQ) |
905 | dev_warn(dev, "eclk mismatched, mode is based on 24MHz\n" ); |
906 | |
907 | ov02a10->pd_gpio = devm_gpiod_get(dev, con_id: "powerdown" , flags: GPIOD_OUT_HIGH); |
908 | if (IS_ERR(ptr: ov02a10->pd_gpio)) |
909 | return dev_err_probe(dev, err: PTR_ERR(ptr: ov02a10->pd_gpio), |
910 | fmt: "failed to get powerdown-gpios\n" ); |
911 | |
912 | ov02a10->rst_gpio = devm_gpiod_get(dev, con_id: "reset" , flags: GPIOD_OUT_HIGH); |
913 | if (IS_ERR(ptr: ov02a10->rst_gpio)) |
914 | return dev_err_probe(dev, err: PTR_ERR(ptr: ov02a10->rst_gpio), |
915 | fmt: "failed to get reset-gpios\n" ); |
916 | |
917 | for (i = 0; i < ARRAY_SIZE(ov02a10_supply_names); i++) |
918 | ov02a10->supplies[i].supply = ov02a10_supply_names[i]; |
919 | |
920 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ov02a10_supply_names), |
921 | consumers: ov02a10->supplies); |
922 | if (ret) |
923 | return dev_err_probe(dev, err: ret, fmt: "failed to get regulators\n" ); |
924 | |
925 | mutex_init(&ov02a10->mutex); |
926 | |
927 | /* Set default mode */ |
928 | ov02a10->cur_mode = &supported_modes[0]; |
929 | |
930 | ret = ov02a10_initialize_controls(ov02a10); |
931 | if (ret) { |
932 | dev_err_probe(dev, err: ret, fmt: "failed to initialize controls\n" ); |
933 | goto err_destroy_mutex; |
934 | } |
935 | |
936 | /* Initialize subdev */ |
937 | ov02a10->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
938 | ov02a10->subdev.entity.ops = &ov02a10_subdev_entity_ops; |
939 | ov02a10->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; |
940 | ov02a10->pad.flags = MEDIA_PAD_FL_SOURCE; |
941 | |
942 | ret = media_entity_pads_init(entity: &ov02a10->subdev.entity, num_pads: 1, pads: &ov02a10->pad); |
943 | if (ret < 0) { |
944 | dev_err_probe(dev, err: ret, fmt: "failed to initialize entity pads\n" ); |
945 | goto err_free_handler; |
946 | } |
947 | |
948 | pm_runtime_enable(dev); |
949 | if (!pm_runtime_enabled(dev)) { |
950 | ret = ov02a10_power_on(dev); |
951 | if (ret < 0) { |
952 | dev_err_probe(dev, err: ret, fmt: "failed to power on\n" ); |
953 | goto err_clean_entity; |
954 | } |
955 | } |
956 | |
957 | ret = v4l2_async_register_subdev(sd: &ov02a10->subdev); |
958 | if (ret) { |
959 | dev_err_probe(dev, err: ret, fmt: "failed to register V4L2 subdev\n" ); |
960 | goto err_power_off; |
961 | } |
962 | |
963 | return 0; |
964 | |
965 | err_power_off: |
966 | if (pm_runtime_enabled(dev)) |
967 | pm_runtime_disable(dev); |
968 | else |
969 | ov02a10_power_off(dev); |
970 | err_clean_entity: |
971 | media_entity_cleanup(entity: &ov02a10->subdev.entity); |
972 | err_free_handler: |
973 | v4l2_ctrl_handler_free(hdl: ov02a10->subdev.ctrl_handler); |
974 | err_destroy_mutex: |
975 | mutex_destroy(lock: &ov02a10->mutex); |
976 | |
977 | return ret; |
978 | } |
979 | |
980 | static void ov02a10_remove(struct i2c_client *client) |
981 | { |
982 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
983 | struct ov02a10 *ov02a10 = to_ov02a10(sd); |
984 | |
985 | v4l2_async_unregister_subdev(sd); |
986 | media_entity_cleanup(entity: &sd->entity); |
987 | v4l2_ctrl_handler_free(hdl: sd->ctrl_handler); |
988 | pm_runtime_disable(dev: &client->dev); |
989 | if (!pm_runtime_status_suspended(dev: &client->dev)) |
990 | ov02a10_power_off(dev: &client->dev); |
991 | pm_runtime_set_suspended(dev: &client->dev); |
992 | mutex_destroy(lock: &ov02a10->mutex); |
993 | } |
994 | |
995 | static const struct of_device_id ov02a10_of_match[] = { |
996 | { .compatible = "ovti,ov02a10" }, |
997 | {} |
998 | }; |
999 | MODULE_DEVICE_TABLE(of, ov02a10_of_match); |
1000 | |
1001 | static struct i2c_driver ov02a10_i2c_driver = { |
1002 | .driver = { |
1003 | .name = "ov02a10" , |
1004 | .pm = &ov02a10_pm_ops, |
1005 | .of_match_table = ov02a10_of_match, |
1006 | }, |
1007 | .probe = ov02a10_probe, |
1008 | .remove = ov02a10_remove, |
1009 | }; |
1010 | module_i2c_driver(ov02a10_i2c_driver); |
1011 | |
1012 | MODULE_AUTHOR("Dongchun Zhu <dongchun.zhu@mediatek.com>" ); |
1013 | MODULE_DESCRIPTION("OmniVision OV02A10 sensor driver" ); |
1014 | MODULE_LICENSE("GPL v2" ); |
1015 | |