[COMMON] fimc-is2: add GM1 sensor mode (add setB)
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / media / platform / exynos / fimc-is2 / sensor / module_framework / cis / fimc-is-cis-2x5sp.c
CommitLineData
197e9ada
WK
1/*
2 * Samsung Exynos5 SoC series Sensor driver
3 *
4 *
5 * Copyright (c) 2018 Samsung Electronics Co., Ltd
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/i2c.h>
13#include <linux/slab.h>
14#include <linux/irq.h>
15#include <linux/interrupt.h>
16#include <linux/delay.h>
17#include <linux/version.h>
18#include <linux/gpio.h>
19#include <linux/clk.h>
20#include <linux/regulator/consumer.h>
21#include <linux/videodev2.h>
22#include <linux/videodev2_exynos_camera.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/platform_device.h>
26#include <linux/of_gpio.h>
27#include <media/v4l2-ctrls.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-subdev.h>
30
31#include <exynos-fimc-is-sensor.h>
32#include "fimc-is-hw.h"
33#include "fimc-is-core.h"
34#include "fimc-is-param.h"
35#include "fimc-is-device-sensor.h"
36#include "fimc-is-device-sensor-peri.h"
37#include "fimc-is-resourcemgr.h"
38#include "fimc-is-dt.h"
39#include "fimc-is-cis-2x5sp.h"
40#include "fimc-is-cis-2x5sp-setA.h"
41
42#include "fimc-is-helper-i2c.h"
43
44#define SENSOR_NAME "S5K2X5SP"
45/* #define DEBUG_2X5SP_PLL */
46
47static const struct v4l2_subdev_ops subdev_ops;
48
49static const u32 *sensor_2x5sp_global;
50static u32 sensor_2x5sp_global_size;
51static const u32 **sensor_2x5sp_setfiles;
52static const u32 *sensor_2x5sp_setfile_sizes;
53static const struct sensor_pll_info_compact **sensor_2x5sp_pllinfos;
54static u32 sensor_2x5sp_max_setfile_num;
55
56static void sensor_2x5sp_cis_data_calculation(const struct sensor_pll_info_compact *pll_info_compact, cis_shared_data *cis_data)
57{
58 u32 vt_pix_clk_hz = 0;
59 u32 frame_rate = 0, max_fps = 0, frame_valid_us = 0;
60
61 FIMC_BUG_VOID(!pll_info_compact);
62
63 /* 1. get pclk value from pll info */
64 vt_pix_clk_hz = pll_info_compact->pclk;
65
66 dbg_sensor(1, "ext_clock(%d), mipi_datarate(%d), pclk(%d)\n",
67 pll_info_compact->ext_clk, pll_info_compact->mipi_datarate, pll_info_compact->pclk);
68
69 /* 2. the time of processing one frame calculation (us) */
70 cis_data->min_frame_us_time = (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck
71 / (vt_pix_clk_hz / (1000 * 1000)));
72 cis_data->cur_frame_us_time = cis_data->min_frame_us_time;
73
74 /* 3. FPS calculation */
75 frame_rate = vt_pix_clk_hz / (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck);
76 dbg_sensor(1, "frame_rate (%d) = vt_pix_clk_hz(%d) / "
77 KERN_CONT "(pll_info_compact->frame_length_lines(%d) * pll_info_compact->line_length_pck(%d))\n",
78 frame_rate, vt_pix_clk_hz, pll_info_compact->frame_length_lines, pll_info_compact->line_length_pck);
79
80 /* calculate max fps */
81 max_fps = (vt_pix_clk_hz * 10) / (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck);
82 max_fps = (max_fps % 10 >= 5 ? frame_rate + 1 : frame_rate);
83
84 cis_data->pclk = vt_pix_clk_hz;
85 cis_data->max_fps = max_fps;
86 cis_data->frame_length_lines = pll_info_compact->frame_length_lines;
87 cis_data->line_length_pck = pll_info_compact->line_length_pck;
88 cis_data->line_readOut_time = sensor_cis_do_div64((u64)cis_data->line_length_pck * (u64)(1000 * 1000 * 1000), cis_data->pclk);
89 cis_data->rolling_shutter_skew = (cis_data->cur_height - 1) * cis_data->line_readOut_time;
90 cis_data->stream_on = false;
91
92 /* Frame valid time calcuration */
93 frame_valid_us = sensor_cis_do_div64((u64)cis_data->cur_height * (u64)cis_data->line_length_pck * (u64)(1000 * 1000), cis_data->pclk);
94 cis_data->frame_valid_us_time = (int)frame_valid_us;
95
96 dbg_sensor(1, "%s\n", __func__);
97 dbg_sensor(1, "Sensor size(%d x %d) setting: SUCCESS!\n",
98 cis_data->cur_width, cis_data->cur_height);
99 dbg_sensor(1, "Frame Valid(us): %d\n", frame_valid_us);
100 dbg_sensor(1, "rolling_shutter_skew: %lld\n", cis_data->rolling_shutter_skew);
101
102 dbg_sensor(1, "Fps: %d, max fps(%d)\n", frame_rate, cis_data->max_fps);
103 dbg_sensor(1, "min_frame_time(%d us)\n", cis_data->min_frame_us_time);
104 dbg_sensor(1, "Pixel rate(Mbps): %d\n", cis_data->pclk / 1000000);
105
106 /* Frame period calculation */
107 cis_data->frame_time = (cis_data->line_readOut_time * cis_data->cur_height / 1000);
108 cis_data->rolling_shutter_skew = (cis_data->cur_height - 1) * cis_data->line_readOut_time;
109
110 dbg_sensor(1, "[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__,
111 cis_data->frame_time, cis_data->rolling_shutter_skew);
112
113 /* Constant values */
114 cis_data->min_fine_integration_time = SENSOR_2X5SP_FINE_INTEGRATION_TIME_MIN;
115 cis_data->max_fine_integration_time = cis_data->cur_width;
116 cis_data->min_coarse_integration_time = SENSOR_2X5SP_COARSE_INTEGRATION_TIME_MIN;
117 cis_data->max_margin_coarse_integration_time = SENSOR_2X5SP_COARSE_INTEGRATION_TIME_MAX_MARGIN;
118}
119
120int sensor_2x5sp_cis_check_rev(struct v4l2_subdev *subdev)
121{
122 int ret = 0;
123 u8 rev = 0;
124 struct i2c_client *client;
125 struct fimc_is_cis *cis = NULL;
126
127 WARN_ON(!subdev);
128
129 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
130 WARN_ON(!cis);
131 WARN_ON(!cis->cis_data);
132
133 client = cis->client;
134 if (unlikely(!client)) {
135 err("client is NULL");
136 ret = -EINVAL;
137 return ret;
138 }
139
140 memset(cis->cis_data, 0, sizeof(cis_shared_data));
141 cis->rev_flag = false;
142
143 I2C_MUTEX_LOCK(cis->i2c_lock);
144
145 ret = fimc_is_sensor_read8(client, 0x0002, &rev);
146 if (ret < 0) {
147 cis->rev_flag = true;
148 ret = -EAGAIN;
149 } else {
150 cis->cis_data->cis_rev = rev;
151 pr_info("%s : Rev. 0x%X\n", __func__, rev);
152 }
153
154 I2C_MUTEX_UNLOCK(cis->i2c_lock);
155
156 return ret;
157}
158
159/* CIS OPS */
160int sensor_2x5sp_cis_init(struct v4l2_subdev *subdev)
161{
162 int ret = 0;
163 struct fimc_is_cis *cis;
164 u32 setfile_index = 0;
165 cis_setting_info setinfo;
166
167 setinfo.return_value = 0;
168
169 setinfo.param = NULL;
170
171 FIMC_BUG(!subdev);
172
173 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
174 if (!cis) {
175 err("cis is NULL");
176 ret = -EINVAL;
177 goto p_err;
178 }
179
180 FIMC_BUG(!cis->cis_data);
181 memset(cis->cis_data, 0, sizeof(cis_shared_data));
182
183 cis->cis_data->cur_width = SENSOR_2X5SP_MAX_WIDTH;
184 cis->cis_data->cur_height = SENSOR_2X5SP_MAX_HEIGHT;
185 cis->cis_data->low_expo_start = 33000;
186 cis->need_mode_change = false;
187
188 sensor_2x5sp_cis_data_calculation(sensor_2x5sp_pllinfos[setfile_index], cis->cis_data);
189
190 setinfo.return_value = 0;
191 CALL_CISOPS(cis, cis_get_min_exposure_time, subdev, &setinfo.return_value);
192 dbg_sensor(1, "[%s] min exposure time : %d\n", __func__, setinfo.return_value);
193 setinfo.return_value = 0;
194 CALL_CISOPS(cis, cis_get_max_exposure_time, subdev, &setinfo.return_value);
195 dbg_sensor(1, "[%s] max exposure time : %d\n", __func__, setinfo.return_value);
196 setinfo.return_value = 0;
197 CALL_CISOPS(cis, cis_get_min_analog_gain, subdev, &setinfo.return_value);
198 dbg_sensor(1, "[%s] min again : %d\n", __func__, setinfo.return_value);
199 setinfo.return_value = 0;
200 CALL_CISOPS(cis, cis_get_max_analog_gain, subdev, &setinfo.return_value);
201 dbg_sensor(1, "[%s] max again : %d\n", __func__, setinfo.return_value);
202 setinfo.return_value = 0;
203 CALL_CISOPS(cis, cis_get_min_digital_gain, subdev, &setinfo.return_value);
204 dbg_sensor(1, "[%s] min dgain : %d\n", __func__, setinfo.return_value);
205 setinfo.return_value = 0;
206 CALL_CISOPS(cis, cis_get_max_digital_gain, subdev, &setinfo.return_value);
207 dbg_sensor(1, "[%s] max dgain : %d\n", __func__, setinfo.return_value);
208
209#ifdef DEBUG_SENSOR_TIME
210 do_gettimeofday(&end);
211 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec));
212#endif
213
214p_err:
215 return ret;
216}
217
218int sensor_2x5sp_cis_log_status(struct v4l2_subdev *subdev)
219{
220 int ret = 0;
221 struct fimc_is_cis *cis;
222 struct i2c_client *client = NULL;
223 u8 data8 = 0;
224 u16 data16 = 0;
225
226 FIMC_BUG(!subdev);
227
228 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
229 if (!cis) {
230 err("cis is NULL");
231 ret = -ENODEV;
232 goto p_err;
233 }
234
235 client = cis->client;
236 if (unlikely(!client)) {
237 err("client is NULL");
238 ret = -ENODEV;
239 goto p_err;
240 }
241
242 pr_err("[SEN:DUMP] *******************************\n");
243 fimc_is_sensor_read16(client, 0x0000, &data16);
244 pr_err("[SEN:DUMP] model_id(%x)\n", data16);
245 fimc_is_sensor_read8(client, 0x0002, &data8);
246 pr_err("[SEN:DUMP] revision_number(%x)\n", data8);
247 fimc_is_sensor_read8(client, 0x0005, &data8);
248 pr_err("[SEN:DUMP] frame_count(%x)\n", data8);
249 fimc_is_sensor_read8(client, 0x0100, &data8);
250 pr_err("[SEN:DUMP] mode_select(%x)\n", data8);
251
252 sensor_cis_dump_registers(subdev, sensor_2x5sp_setfiles[0], sensor_2x5sp_setfile_sizes[0]);
253
254 pr_err("[SEN:DUMP] *******************************\n");
255
256p_err:
257 return ret;
258}
259
260#if USE_GROUP_PARAM_HOLD
261static int sensor_2x5sp_cis_group_param_hold_func(struct v4l2_subdev *subdev, unsigned int hold)
262{
263 int ret = 0;
264 struct fimc_is_cis *cis = NULL;
265 struct i2c_client *client = NULL;
266
267 FIMC_BUG(!subdev);
268
269 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
270
271 FIMC_BUG(!cis);
272 FIMC_BUG(!cis->cis_data);
273
274 client = cis->client;
275 if (unlikely(!client)) {
276 err("client is NULL");
277 ret = -EINVAL;
278 goto p_err;
279 }
280
281 if (hold == cis->cis_data->group_param_hold) {
282 pr_debug("already group_param_hold (%d)\n", cis->cis_data->group_param_hold);
283 goto p_err;
284 }
285
286 ret = fimc_is_sensor_write8(client, 0x0104, hold);
287 if (ret < 0)
288 goto p_err;
289
290 cis->cis_data->group_param_hold = hold;
291 ret = 1;
292p_err:
293 return ret;
294}
295#else
296static inline int sensor_2x5sp_cis_group_param_hold_func(struct v4l2_subdev *subdev, unsigned int hold)
297{ return 0; }
298#endif
299
300/* Input
301 * hold : true - hold, flase - no hold
302 * Output
303 * return: 0 - no effect(already hold or no hold)
304 * positive - setted by request
305 * negative - ERROR value
306 */
307int sensor_2x5sp_cis_group_param_hold(struct v4l2_subdev *subdev, bool hold)
308{
309 int ret = 0;
310 struct fimc_is_cis *cis = NULL;
311
312 FIMC_BUG(!subdev);
313
314 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
315
316 FIMC_BUG(!cis);
317 FIMC_BUG(!cis->cis_data);
318
319 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, hold);
320 if (ret < 0)
321 goto p_err;
322
323p_err:
324 return ret;
325}
326
327int sensor_2x5sp_cis_set_global_setting(struct v4l2_subdev *subdev)
328{
329 int ret = 0;
330 struct fimc_is_cis *cis = NULL;
331
332 FIMC_BUG(!subdev);
333
334 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
335 FIMC_BUG(!cis);
336
337 ret = sensor_cis_set_registers(subdev, sensor_2x5sp_global, sensor_2x5sp_global_size);
338
339 if (ret < 0) {
340 err("sensor_3p8sp_set_registers fail!!");
341 goto p_err;
342 }
343
344 dbg_sensor(1, "[%s] global setting done\n", __func__);
345
346p_err:
347 return ret;
348}
349
350int sensor_2x5sp_cis_mode_change(struct v4l2_subdev *subdev, u32 mode)
351{
352 int ret = 0;
353 struct fimc_is_cis *cis = NULL;
354
355 FIMC_BUG(!subdev);
356
357 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
358 FIMC_BUG(!cis);
359 FIMC_BUG(!cis->cis_data);
360
361 if (mode > sensor_2x5sp_max_setfile_num) {
362 err("invalid mode(%d)!!", mode);
363 ret = -EINVAL;
364 goto p_err;
365 }
366
367 sensor_2x5sp_cis_data_calculation(sensor_2x5sp_pllinfos[mode], cis->cis_data);
368
369 ret = sensor_cis_set_registers(subdev, sensor_2x5sp_setfiles[mode], sensor_2x5sp_setfile_sizes[mode]);
370 if (ret < 0) {
371 err("sensor_2x5sp_set_registers fail!!");
372 goto p_err;
373 }
374
375 cis->cis_data->frame_time = (cis->cis_data->line_readOut_time * cis->cis_data->cur_height / 1000);
376 cis->cis_data->rolling_shutter_skew = (cis->cis_data->cur_height - 1) * cis->cis_data->line_readOut_time;
377 dbg_sensor(1, "[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__,
378 cis->cis_data->frame_time, cis->cis_data->rolling_shutter_skew);
379
380 dbg_sensor(1, "[%s] mode changed(%d)\n", __func__, mode);
381
382p_err:
383 return ret;
384}
385
386/* Deprecated */
387int sensor_2x5sp_cis_set_size(struct v4l2_subdev *subdev, cis_shared_data *cis_data)
388{
389 return 0;
390}
391
392int sensor_2x5sp_cis_stream_on(struct v4l2_subdev *subdev)
393{
394 int ret = 0;
395 struct fimc_is_cis *cis;
396 struct i2c_client *client;
397 cis_shared_data *cis_data;
398
399#ifdef DEBUG_SENSOR_TIME
400 struct timeval st, end;
401
402 do_gettimeofday(&st);
403#endif
404
405 FIMC_BUG(!subdev);
406
407 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
408
409 FIMC_BUG(!cis);
410 FIMC_BUG(!cis->cis_data);
411
412 client = cis->client;
413 if (unlikely(!client)) {
414 err("client is NULL");
415 ret = -EINVAL;
416 goto p_err;
417 }
418
419 cis_data = cis->cis_data;
420
421 dbg_sensor(1, "[MOD:D:%d] %s\n", cis->id, __func__);
422
423 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
424 if (ret < 0)
425 err("group_param_hold_func failed at stream on");
426
427#ifdef DEBUG_2X5SP_PLL
428 {
429 u16 pll;
430
431 fimc_is_sensor_read16(client, 0x0300, &pll);
432 dbg_sensor(1, "______ vt_pix_clk_div(%x)\n", pll);
433 fimc_is_sensor_read16(client, 0x0302, &pll);
434 dbg_sensor(1, "______ vt_sys_clk_div(%x)\n", pll);
435 fimc_is_sensor_read16(client, 0x0304, &pll);
436 dbg_sensor(1, "______ pre_pll_clk_div(%x)\n", pll);
437 fimc_is_sensor_read16(client, 0x0306, &pll);
438 dbg_sensor(1, "______ pll_multiplier(%x)\n", pll);
439 fimc_is_sensor_read16(client, 0x0308, &pll);
440 dbg_sensor(1, "______ op_pix_clk_div(%x)\n", pll);
441 fimc_is_sensor_read16(client, 0x030a, &pll);
442 dbg_sensor(1, "______ op_sys_clk_div(%x)\n", pll);
443
444 fimc_is_sensor_read16(client, 0x030c, &pll);
445 dbg_sensor(1, "______ secnd_pre_pll_clk_div(%x)\n", pll);
446 fimc_is_sensor_read16(client, 0x030e, &pll);
447 dbg_sensor(1, "______ secnd_pll_multiplier(%x)\n", pll);
448 fimc_is_sensor_read16(client, 0x0340, &pll);
449 dbg_sensor(1, "______ frame_length_lines(%x)\n", pll);
450 fimc_is_sensor_read16(client, 0x0342, &pll);
451 dbg_sensor(1, "______ line_length_pck(%x)\n", pll);
452 }
453#endif
454
455 /* Sensor stream on */
456 fimc_is_sensor_write16(client, 0x6028, 0x4000);
457 fimc_is_sensor_write8(client, 0x0100, 0x01);
458
459 /* WDR */
460 if (fimc_is_vender_wdr_mode_on(cis_data))
461 fimc_is_sensor_write8(client, 0x021E, 0x01);
462 else
463 fimc_is_sensor_write8(client, 0x021E, 0x00);
464
465 cis_data->stream_on = true;
466
467#ifdef DEBUG_SENSOR_TIME
468 do_gettimeofday(&end);
469 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
470#endif
471
472p_err:
473 return ret;
474}
475
476int sensor_2x5sp_cis_stream_off(struct v4l2_subdev *subdev)
477{
478 int ret = 0;
479 struct fimc_is_cis *cis;
480 struct i2c_client *client;
481 cis_shared_data *cis_data;
482
483#ifdef DEBUG_SENSOR_TIME
484 struct timeval st, end;
485
486 do_gettimeofday(&st);
487#endif
488
489 FIMC_BUG(!subdev);
490
491 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
492
493 FIMC_BUG(!cis);
494 FIMC_BUG(!cis->cis_data);
495
496 client = cis->client;
497 if (unlikely(!client)) {
498 err("client is NULL");
499 ret = -EINVAL;
500 goto p_err;
501 }
502
503 cis_data = cis->cis_data;
504
505 dbg_sensor(1, "[MOD:D:%d] %s\n", cis->id, __func__);
506
507 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
508 if (ret < 0)
509 err("group_param_hold_func failed at stream off");
510
511 /* Sensor stream off */
512 fimc_is_sensor_write16(client, 0x6028, 0x4000);
513 fimc_is_sensor_write8(client, 0x0100, 0x00);
514
515 cis_data->stream_on = false;
516
517#ifdef DEBUG_SENSOR_TIME
518 do_gettimeofday(&end);
519 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
520#endif
521
522p_err:
523 return ret;
524}
525
526int sensor_2x5sp_cis_set_exposure_time(struct v4l2_subdev *subdev, struct ae_param *target_exposure)
527{
528 int ret = 0;
529 int hold = 0;
530 struct fimc_is_cis *cis;
531 struct i2c_client *client;
532 cis_shared_data *cis_data;
533
534 u32 vt_pic_clk_freq_mhz = 0;
535 u16 long_coarse_int = 0;
536 u16 short_coarse_int = 0;
537 u32 line_length_pck = 0;
538 u32 min_fine_int = 0;
539
540#ifdef DEBUG_SENSOR_TIME
541 struct timeval st, end;
542
543 do_gettimeofday(&st);
544#endif
545
546 FIMC_BUG(!subdev);
547 FIMC_BUG(!target_exposure);
548
549 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
550
551 FIMC_BUG(!cis);
552 FIMC_BUG(!cis->cis_data);
553
554 client = cis->client;
555 if (unlikely(!client)) {
556 err("client is NULL");
557 ret = -EINVAL;
558 goto p_err;
559 }
560
561 if ((target_exposure->long_val <= 0) || (target_exposure->short_val <= 0)) {
562 err("[%s] invalid target exposure(%d, %d)\n", __func__,
563 target_exposure->long_val, target_exposure->short_val);
564 ret = -EINVAL;
565 goto p_err;
566 }
567
568 cis_data = cis->cis_data;
569
570 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), target long(%d), short(%d)\n", cis->id, __func__,
571 cis_data->sen_vsync_count, target_exposure->long_val, target_exposure->short_val);
572
573 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
574 line_length_pck = cis_data->line_length_pck;
575 min_fine_int = cis_data->min_fine_integration_time;
576
577 long_coarse_int = ((target_exposure->long_val * vt_pic_clk_freq_mhz) - min_fine_int) / line_length_pck;
578 short_coarse_int = ((target_exposure->short_val * vt_pic_clk_freq_mhz) - min_fine_int) / line_length_pck;
579
580 if (long_coarse_int > cis_data->max_coarse_integration_time) {
581 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), long coarse(%d) max(%d)\n", cis->id, __func__,
582 cis_data->sen_vsync_count, long_coarse_int, cis_data->max_coarse_integration_time);
583 long_coarse_int = cis_data->max_coarse_integration_time;
584 }
585
586 if (short_coarse_int > cis_data->max_coarse_integration_time) {
587 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), short coarse(%d) max(%d)\n", cis->id, __func__,
588 cis_data->sen_vsync_count, short_coarse_int, cis_data->max_coarse_integration_time);
589 short_coarse_int = cis_data->max_coarse_integration_time;
590 }
591
592 if (long_coarse_int < cis_data->min_coarse_integration_time) {
593 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), long coarse(%d) min(%d)\n", cis->id, __func__,
594 cis_data->sen_vsync_count, long_coarse_int, cis_data->min_coarse_integration_time);
595 long_coarse_int = cis_data->min_coarse_integration_time;
596 }
597
598 if (short_coarse_int < cis_data->min_coarse_integration_time) {
599 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), short coarse(%d) min(%d)\n", cis->id, __func__,
600 cis_data->sen_vsync_count, short_coarse_int, cis_data->min_coarse_integration_time);
601 short_coarse_int = cis_data->min_coarse_integration_time;
602 }
603
604 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
605 if (hold < 0) {
606 ret = hold;
607 goto p_err;
608 }
609
610 /* Short exposure */
611 ret = fimc_is_sensor_write16(client, 0x0202, short_coarse_int);
612 if (ret < 0)
613 goto p_err;
614
615 /* Long exposure */
616 if (fimc_is_vender_wdr_mode_on(cis_data)) {
617 ret = fimc_is_sensor_write16(client, 0x0226, long_coarse_int);
618 if (ret < 0)
619 goto p_err;
620
621 /* TODO: medium coarse integration time: 0x022A */
622 }
623
624 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), vt_pic_clk_freq_mhz (%d), line_length_pck(%d), min_fine_int (%d)\n",
625 cis->id, __func__, cis_data->sen_vsync_count, vt_pic_clk_freq_mhz, line_length_pck, min_fine_int);
626 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), frame_length_lines(%#x), long_coarse_int %#x, short_coarse_int %#x\n",
627 cis->id, __func__, cis_data->sen_vsync_count, cis_data->frame_length_lines,
628 long_coarse_int, short_coarse_int);
629
630#ifdef DEBUG_SENSOR_TIME
631 do_gettimeofday(&end);
632 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
633#endif
634
635p_err:
636 if (hold > 0) {
637 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
638 if (hold < 0)
639 ret = hold;
640 }
641
642 return ret;
643}
644
645int sensor_2x5sp_cis_get_min_exposure_time(struct v4l2_subdev *subdev, u32 *min_expo)
646{
647 int ret = 0;
648 struct fimc_is_cis *cis = NULL;
649 cis_shared_data *cis_data = NULL;
650 u32 min_integration_time = 0;
651 u32 min_coarse = 0;
652 u32 min_fine = 0;
653 u32 vt_pic_clk_freq_mhz = 0;
654 u32 line_length_pck = 0;
655
656#ifdef DEBUG_SENSOR_TIME
657 struct timeval st, end;
658
659 do_gettimeofday(&st);
660#endif
661
662 FIMC_BUG(!subdev);
663 FIMC_BUG(!min_expo);
664
665 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
666
667 FIMC_BUG(!cis);
668 FIMC_BUG(!cis->cis_data);
669
670 cis_data = cis->cis_data;
671
672 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
673 if (vt_pic_clk_freq_mhz == 0) {
674 pr_err("[MOD:D:%d] %s, Invalid vt_pic_clk_freq_mhz(%d)\n", cis->id, __func__, vt_pic_clk_freq_mhz);
675 goto p_err;
676 }
677 line_length_pck = cis_data->line_length_pck;
678 min_coarse = cis_data->min_coarse_integration_time;
679 min_fine = cis_data->min_fine_integration_time;
680
681 min_integration_time = ((line_length_pck * min_coarse) + min_fine) / vt_pic_clk_freq_mhz;
682 *min_expo = min_integration_time;
683
684 dbg_sensor(1, "[%s] min integration time %d\n", __func__, min_integration_time);
685
686#ifdef DEBUG_SENSOR_TIME
687 do_gettimeofday(&end);
688 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
689#endif
690
691p_err:
692 return ret;
693}
694
695int sensor_2x5sp_cis_get_max_exposure_time(struct v4l2_subdev *subdev, u32 *max_expo)
696{
697 int ret = 0;
698 struct fimc_is_cis *cis;
699 cis_shared_data *cis_data;
700 u32 max_integration_time = 0;
701 u32 max_coarse_margin = 0;
702 u32 max_fine_margin = 0;
703 u32 max_coarse = 0;
704 u32 max_fine = 0;
705 u32 vt_pic_clk_freq_mhz = 0;
706 u32 line_length_pck = 0;
707 u32 frame_length_lines = 0;
708
709#ifdef DEBUG_SENSOR_TIME
710 struct timeval st, end;
711
712 do_gettimeofday(&st);
713#endif
714
715 FIMC_BUG(!subdev);
716 FIMC_BUG(!max_expo);
717
718 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
719
720 FIMC_BUG(!cis);
721 FIMC_BUG(!cis->cis_data);
722
723 cis_data = cis->cis_data;
724
725 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
726 if (vt_pic_clk_freq_mhz == 0) {
727 pr_err("[MOD:D:%d] %s, Invalid vt_pic_clk_freq_mhz(%d)\n", cis->id, __func__, vt_pic_clk_freq_mhz);
728 goto p_err;
729 }
730 line_length_pck = cis_data->line_length_pck;
731 frame_length_lines = cis_data->frame_length_lines;
732
733 max_coarse_margin = cis_data->max_margin_coarse_integration_time;
734 max_fine_margin = line_length_pck - cis_data->min_fine_integration_time;
735 max_coarse = frame_length_lines - max_coarse_margin;
736 max_fine = cis_data->max_fine_integration_time;
737
738 max_integration_time = ((line_length_pck * max_coarse) + max_fine) / vt_pic_clk_freq_mhz;
739
740 *max_expo = max_integration_time;
741
742 /* TODO: Is this values update here? */
743 cis_data->max_margin_fine_integration_time = max_fine_margin;
744 cis_data->max_coarse_integration_time = max_coarse;
745
746 dbg_sensor(1, "[%s] max integration time %d, max margin fine integration %d, max coarse integration %d\n",
747 __func__, max_integration_time, cis_data->max_margin_fine_integration_time,
748 cis_data->max_coarse_integration_time);
749
750#ifdef DEBUG_SENSOR_TIME
751 do_gettimeofday(&end);
752 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
753#endif
754
755p_err:
756 return ret;
757}
758
759int sensor_2x5sp_cis_adjust_frame_duration(struct v4l2_subdev *subdev,
760 u32 input_exposure_time,
761 u32 *target_duration)
762{
763 int ret = 0;
764 struct fimc_is_cis *cis;
765 cis_shared_data *cis_data;
766
767 u32 vt_pic_clk_freq_mhz = 0;
768 u32 line_length_pck = 0;
769 u32 frame_length_lines = 0;
770 u32 frame_duration = 0;
771
772#ifdef DEBUG_SENSOR_TIME
773 struct timeval st, end;
774
775 do_gettimeofday(&st);
776#endif
777
778 FIMC_BUG(!subdev);
779 FIMC_BUG(!target_duration);
780
781 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
782
783 FIMC_BUG(!cis);
784 FIMC_BUG(!cis->cis_data);
785
786 cis_data = cis->cis_data;
787
788 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
789 line_length_pck = cis_data->line_length_pck;
790 frame_length_lines = ((vt_pic_clk_freq_mhz * input_exposure_time) / line_length_pck);
791 frame_length_lines += cis_data->max_margin_coarse_integration_time;
792
793 frame_duration = (frame_length_lines * line_length_pck) / vt_pic_clk_freq_mhz;
794
795 dbg_sensor(1, "[%s](vsync cnt = %d) input exp(%d), adj duration, frame duraion(%d), min_frame_us(%d)\n",
796 __func__, cis_data->sen_vsync_count, input_exposure_time,
797 frame_duration, cis_data->min_frame_us_time);
798 dbg_sensor(1, "[%s](vsync cnt = %d) adj duration, frame duraion(%d), min_frame_us(%d)\n",
799 __func__, cis_data->sen_vsync_count, frame_duration, cis_data->min_frame_us_time);
800
801 *target_duration = MAX(frame_duration, cis_data->min_frame_us_time);
802
803#ifdef DEBUG_SENSOR_TIME
804 do_gettimeofday(&end);
805 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
806#endif
807
808 return ret;
809}
810
811int sensor_2x5sp_cis_set_frame_duration(struct v4l2_subdev *subdev, u32 frame_duration)
812{
813 int ret = 0;
814 int hold = 0;
815 struct fimc_is_cis *cis;
816 struct i2c_client *client;
817 cis_shared_data *cis_data;
818
819 u32 vt_pic_clk_freq_mhz = 0;
820 u32 line_length_pck = 0;
821 u16 frame_length_lines = 0;
822
823 u32 max_coarse_integration_time = 0;
824
825#ifdef DEBUG_SENSOR_TIME
826 struct timeval st, end;
827
828 do_gettimeofday(&st);
829#endif
830
831 FIMC_BUG(!subdev);
832
833 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
834
835 FIMC_BUG(!cis);
836 FIMC_BUG(!cis->cis_data);
837
838 client = cis->client;
839 if (unlikely(!client)) {
840 err("client is NULL");
841 ret = -EINVAL;
842 goto p_err;
843 }
844
845 cis_data = cis->cis_data;
846
847 if (frame_duration < cis_data->min_frame_us_time) {
848 dbg_sensor(1, "frame duration is less than min(%d)\n", frame_duration);
849 frame_duration = cis_data->min_frame_us_time;
850 }
851
852 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
853 line_length_pck = cis_data->line_length_pck;
854
855 frame_length_lines = (u16)((vt_pic_clk_freq_mhz * frame_duration) / line_length_pck);
856
857 dbg_sensor(1, "[MOD:D:%d] %s, vt_pic_clk_freq_mhz(%#x) frame_duration = %d us, "
858 KERN_CONT"(line_length_pck%#x), frame_length_lines(%#x)\n",
859 cis->id, __func__, vt_pic_clk_freq_mhz, frame_duration, line_length_pck, frame_length_lines);
860
861 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
862 if (hold < 0) {
863 ret = hold;
864 goto p_err;
865 }
866
867 ret = fimc_is_sensor_write16(client, 0x0340, frame_length_lines);
868 if (ret < 0)
869 goto p_err;
870
871 cis_data->cur_frame_us_time = frame_duration;
872 cis_data->frame_length_lines = frame_length_lines;
873
874 max_coarse_integration_time = cis_data->frame_length_lines - cis_data->max_margin_coarse_integration_time;
875 cis_data->max_coarse_integration_time = max_coarse_integration_time;
876
877#ifdef DEBUG_SENSOR_TIME
878 do_gettimeofday(&end);
879 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
880#endif
881
882p_err:
883 if (hold > 0) {
884 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
885 if (hold < 0)
886 ret = hold;
887 }
888
889 return ret;
890}
891
892int sensor_2x5sp_cis_set_frame_rate(struct v4l2_subdev *subdev, u32 min_fps)
893{
894 int ret = 0;
895 struct fimc_is_cis *cis;
896 cis_shared_data *cis_data;
897
898 u32 frame_duration = 0;
899
900#ifdef DEBUG_SENSOR_TIME
901 struct timeval st, end;
902
903 do_gettimeofday(&st);
904#endif
905
906 FIMC_BUG(!subdev);
907
908 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
909
910 FIMC_BUG(!cis);
911 FIMC_BUG(!cis->cis_data);
912
913 cis_data = cis->cis_data;
914
915 if (min_fps > cis_data->max_fps) {
916 err("[MOD:D:%d] %s, request FPS is too high(%d), set to max(%d)\n",
917 cis->id, __func__, min_fps, cis_data->max_fps);
918 min_fps = cis_data->max_fps;
919 }
920
921 if (min_fps == 0) {
922 err("[MOD:D:%d] %s, request FPS is 0, set to min FPS(1)\n",
923 cis->id, __func__);
924 min_fps = 1;
925 }
926
927 frame_duration = (1 * 1000 * 1000) / min_fps;
928
929 dbg_sensor(1, "[MOD:D:%d] %s, set FPS(%d), frame duration(%d)\n",
930 cis->id, __func__, min_fps, frame_duration);
931
932 ret = sensor_2x5sp_cis_set_frame_duration(subdev, frame_duration);
933 if (ret < 0) {
934 err("[MOD:D:%d] %s, set frame duration is fail(%d)\n",
935 cis->id, __func__, ret);
936 goto p_err;
937 }
938
939 cis_data->min_frame_us_time = frame_duration;
940
941#ifdef DEBUG_SENSOR_TIME
942 do_gettimeofday(&end);
943 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
944#endif
945
946p_err:
947
948 return ret;
949}
950
951int sensor_2x5sp_cis_adjust_analog_gain(struct v4l2_subdev *subdev, u32 input_again, u32 *target_permile)
952{
953 int ret = 0;
954 struct fimc_is_cis *cis;
955 cis_shared_data *cis_data;
956
957 u32 again_code = 0;
958 u32 again_permile = 0;
959
960#ifdef DEBUG_SENSOR_TIME
961 struct timeval st, end;
962
963 do_gettimeofday(&st);
964#endif
965
966 FIMC_BUG(!subdev);
967 FIMC_BUG(!target_permile);
968
969 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
970
971 FIMC_BUG(!cis);
972 FIMC_BUG(!cis->cis_data);
973
974 cis_data = cis->cis_data;
975
976 again_code = sensor_cis_calc_again_code(input_again);
977
978 if (again_code > cis_data->max_analog_gain[0])
979 again_code = cis_data->max_analog_gain[0];
980 else if (again_code < cis_data->min_analog_gain[0])
981 again_code = cis_data->min_analog_gain[0];
982
983 again_permile = sensor_cis_calc_again_permile(again_code);
984
985 dbg_sensor(1, "[%s] min again(%d), max(%d), input_again(%d), code(%d), permile(%d)\n", __func__,
986 cis_data->max_analog_gain[0],
987 cis_data->min_analog_gain[0],
988 input_again,
989 again_code,
990 again_permile);
991
992 *target_permile = again_permile;
993
994 return ret;
995}
996
997int sensor_2x5sp_cis_set_analog_gain(struct v4l2_subdev *subdev, struct ae_param *again)
998{
999 int ret = 0;
1000 int hold = 0;
1001 struct fimc_is_cis *cis;
1002 struct i2c_client *client;
1003
1004 u16 analog_gain = 0;
1005
1006#ifdef DEBUG_SENSOR_TIME
1007 struct timeval st, end;
1008
1009 do_gettimeofday(&st);
1010#endif
1011
1012 FIMC_BUG(!subdev);
1013 FIMC_BUG(!again);
1014
1015 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1016
1017 FIMC_BUG(!cis);
1018
1019 client = cis->client;
1020 if (unlikely(!client)) {
1021 err("client is NULL");
1022 ret = -EINVAL;
1023 goto p_err;
1024 }
1025
1026 analog_gain = (u16)sensor_cis_calc_again_code(again->val);
1027
1028 if (analog_gain < cis->cis_data->min_analog_gain[0])
1029 analog_gain = cis->cis_data->min_analog_gain[0];
1030
1031 if (analog_gain > cis->cis_data->max_analog_gain[0])
1032 analog_gain = cis->cis_data->max_analog_gain[0];
1033
1034 dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_again = %d us, analog_gain(%#x)\n",
1035 cis->id, __func__, cis->cis_data->sen_vsync_count, again->val, analog_gain);
1036
1037 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1038 if (hold < 0) {
1039 ret = hold;
1040 goto p_err;
1041 }
1042
1043 ret = fimc_is_sensor_write16(client, 0x0204, analog_gain);
1044 if (ret < 0)
1045 goto p_err;
1046
1047#ifdef DEBUG_SENSOR_TIME
1048 do_gettimeofday(&end);
1049 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1050#endif
1051
1052p_err:
1053 if (hold > 0) {
1054 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1055 if (hold < 0)
1056 ret = hold;
1057 }
1058
1059 return ret;
1060}
1061
1062int sensor_2x5sp_cis_get_analog_gain(struct v4l2_subdev *subdev, u32 *again)
1063{
1064 int ret = 0;
1065 int hold = 0;
1066 struct fimc_is_cis *cis;
1067 struct i2c_client *client;
1068
1069 u16 analog_gain = 0;
1070
1071#ifdef DEBUG_SENSOR_TIME
1072 struct timeval st, end;
1073
1074 do_gettimeofday(&st);
1075#endif
1076
1077 FIMC_BUG(!subdev);
1078 FIMC_BUG(!again);
1079
1080 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1081
1082 FIMC_BUG(!cis);
1083
1084 client = cis->client;
1085 if (unlikely(!client)) {
1086 err("client is NULL");
1087 ret = -EINVAL;
1088 goto p_err;
1089 }
1090
1091 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1092 if (hold < 0) {
1093 ret = hold;
1094 goto p_err;
1095 }
1096
1097 ret = fimc_is_sensor_read16(client, 0x0204, &analog_gain);
1098 if (ret < 0)
1099 goto p_err;
1100
1101 *again = sensor_cis_calc_again_permile(analog_gain);
1102
1103 dbg_sensor(1, "[MOD:D:%d] %s, cur_again = %d us, analog_gain(%#x)\n",
1104 cis->id, __func__, *again, analog_gain);
1105
1106#ifdef DEBUG_SENSOR_TIME
1107 do_gettimeofday(&end);
1108 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1109#endif
1110
1111p_err:
1112 if (hold > 0) {
1113 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1114 if (hold < 0)
1115 ret = hold;
1116 }
1117
1118 return ret;
1119}
1120
1121int sensor_2x5sp_cis_get_min_analog_gain(struct v4l2_subdev *subdev, u32 *min_again)
1122{
1123 int ret = 0;
1124 struct fimc_is_cis *cis;
1125 struct i2c_client *client;
1126 cis_shared_data *cis_data;
1127
1128 u16 read_value = 0;
1129
1130#ifdef DEBUG_SENSOR_TIME
1131 struct timeval st, end;
1132
1133 do_gettimeofday(&st);
1134#endif
1135
1136 FIMC_BUG(!subdev);
1137 FIMC_BUG(!min_again);
1138
1139 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1140
1141 FIMC_BUG(!cis);
1142 FIMC_BUG(!cis->cis_data);
1143
1144 client = cis->client;
1145 if (unlikely(!client)) {
1146 err("client is NULL");
1147 ret = -EINVAL;
1148 goto p_err;
1149 }
1150
1151 cis_data = cis->cis_data;
1152
1153 fimc_is_sensor_read16(client, 0x0084, &read_value);
1154
1155 cis_data->min_analog_gain[0] = read_value;
1156
1157 cis_data->min_analog_gain[1] = sensor_cis_calc_again_permile(read_value);
1158
1159 *min_again = cis_data->min_analog_gain[1];
1160
1161 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__, cis_data->min_analog_gain[0], cis_data->min_analog_gain[1]);
1162
1163#ifdef DEBUG_SENSOR_TIME
1164 do_gettimeofday(&end);
1165 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1166#endif
1167
1168p_err:
1169 return ret;
1170}
1171
1172int sensor_2x5sp_cis_get_max_analog_gain(struct v4l2_subdev *subdev, u32 *max_again)
1173{
1174 int ret = 0;
1175 struct fimc_is_cis *cis;
1176 struct i2c_client *client;
1177 cis_shared_data *cis_data;
1178
1179 u16 read_value = 0;
1180
1181#ifdef DEBUG_SENSOR_TIME
1182 struct timeval st, end;
1183
1184 do_gettimeofday(&st);
1185#endif
1186
1187 FIMC_BUG(!subdev);
1188 FIMC_BUG(!max_again);
1189
1190 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1191
1192 FIMC_BUG(!cis);
1193 FIMC_BUG(!cis->cis_data);
1194
1195 client = cis->client;
1196 if (unlikely(!client)) {
1197 err("client is NULL");
1198 ret = -EINVAL;
1199 goto p_err;
1200 }
1201
1202 cis_data = cis->cis_data;
1203
1204 fimc_is_sensor_read16(client, 0x0086, &read_value);
1205
1206 cis_data->max_analog_gain[0] = read_value;
1207
1208 cis_data->max_analog_gain[1] = sensor_cis_calc_again_permile(read_value);
1209
1210 *max_again = cis_data->max_analog_gain[1];
1211
1212 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__, cis_data->max_analog_gain[0], cis_data->max_analog_gain[1]);
1213
1214#ifdef DEBUG_SENSOR_TIME
1215 do_gettimeofday(&end);
1216 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1217#endif
1218
1219p_err:
1220 return ret;
1221}
1222
1223int sensor_2x5sp_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_param *dgain)
1224{
1225 int ret = 0;
1226 int hold = 0;
1227 struct fimc_is_cis *cis;
1228 struct i2c_client *client;
1229 cis_shared_data *cis_data;
1230
1231 u16 long_gain = 0;
1232 u16 short_gain = 0;
1233 u16 dgains[4] = {0};
1234
1235#ifdef DEBUG_SENSOR_TIME
1236 struct timeval st, end;
1237
1238 do_gettimeofday(&st);
1239#endif
1240
1241 FIMC_BUG(!subdev);
1242 FIMC_BUG(!dgain);
1243
1244 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1245
1246 FIMC_BUG(!cis);
1247 FIMC_BUG(!cis->cis_data);
1248
1249 client = cis->client;
1250 if (unlikely(!client)) {
1251 err("client is NULL");
1252 ret = -EINVAL;
1253 goto p_err;
1254 }
1255
1256 cis_data = cis->cis_data;
1257
1258 long_gain = (u16)sensor_cis_calc_dgain_code(dgain->long_val);
1259 short_gain = (u16)sensor_cis_calc_dgain_code(dgain->short_val);
1260
1261 if (long_gain < cis->cis_data->min_digital_gain[0])
1262 long_gain = cis->cis_data->min_digital_gain[0];
1263
1264 if (long_gain > cis->cis_data->max_digital_gain[0])
1265 long_gain = cis->cis_data->max_digital_gain[0];
1266
1267 if (short_gain < cis->cis_data->min_digital_gain[0])
1268 short_gain = cis->cis_data->min_digital_gain[0];
1269
1270 if (short_gain > cis->cis_data->max_digital_gain[0])
1271 short_gain = cis->cis_data->max_digital_gain[0];
1272
1273 dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_dgain = %d/%d us, long_gain(%#x), short_gain(%#x)\n",
1274 cis->id, __func__, cis->cis_data->sen_vsync_count, dgain->long_val,
1275 dgain->short_val, long_gain, short_gain);
1276
1277 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1278 if (hold < 0) {
1279 ret = hold;
1280 goto p_err;
1281 }
1282
1283 dgains[0] = dgains[1] = dgains[2] = dgains[3] = short_gain;
1284 /* Short digital gain */
1285 ret = fimc_is_sensor_write16_array(client, 0x020E, dgains, 4);
1286 if (ret < 0)
1287 goto p_err;
1288
1289 /* Long & medium digital gain */
1290 if (fimc_is_vender_wdr_mode_on(cis_data)) {
1291 ret = fimc_is_sensor_write16(client, 0x0230, long_gain);
1292 if (ret < 0)
1293 goto p_err;
1294
1295 /* TODO: middle_gain update, 0x0238 */
1296 }
1297
1298#ifdef DEBUG_SENSOR_TIME
1299 do_gettimeofday(&end);
1300 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1301#endif
1302
1303p_err:
1304 if (hold > 0) {
1305 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1306 if (hold < 0)
1307 ret = hold;
1308 }
1309
1310 return ret;
1311}
1312
1313int sensor_2x5sp_cis_get_digital_gain(struct v4l2_subdev *subdev, u32 *dgain)
1314{
1315 int ret = 0;
1316 int hold = 0;
1317 struct fimc_is_cis *cis;
1318 struct i2c_client *client;
1319
1320 u16 digital_gain = 0;
1321
1322#ifdef DEBUG_SENSOR_TIME
1323 struct timeval st, end;
1324
1325 do_gettimeofday(&st);
1326#endif
1327
1328 FIMC_BUG(!subdev);
1329 FIMC_BUG(!dgain);
1330
1331 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1332
1333 FIMC_BUG(!cis);
1334
1335 client = cis->client;
1336 if (unlikely(!client)) {
1337 err("client is NULL");
1338 ret = -EINVAL;
1339 goto p_err;
1340 }
1341
1342 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1343 if (hold < 0) {
1344 ret = hold;
1345 goto p_err;
1346 }
1347
1348 ret = fimc_is_sensor_read16(client, 0x020E, &digital_gain);
1349 if (ret < 0)
1350 goto p_err;
1351
1352 *dgain = sensor_cis_calc_dgain_permile(digital_gain);
1353
1354 dbg_sensor(1, "[MOD:D:%d] %s, cur_dgain = %d us, digital_gain(%#x)\n",
1355 cis->id, __func__, *dgain, digital_gain);
1356
1357#ifdef DEBUG_SENSOR_TIME
1358 do_gettimeofday(&end);
1359 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1360#endif
1361
1362p_err:
1363 if (hold > 0) {
1364 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1365 if (hold < 0)
1366 ret = hold;
1367 }
1368
1369 return ret;
1370}
1371
1372int sensor_2x5sp_cis_get_min_digital_gain(struct v4l2_subdev *subdev, u32 *min_dgain)
1373{
1374 int ret = 0;
1375 struct fimc_is_cis *cis;
1376 struct i2c_client *client;
1377 cis_shared_data *cis_data;
1378
1379 u16 read_value = 0;
1380
1381#ifdef DEBUG_SENSOR_TIME
1382 struct timeval st, end;
1383
1384 do_gettimeofday(&st);
1385#endif
1386
1387 FIMC_BUG(!subdev);
1388 FIMC_BUG(!min_dgain);
1389
1390 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1391
1392 FIMC_BUG(!cis);
1393 FIMC_BUG(!cis->cis_data);
1394
1395 client = cis->client;
1396 if (unlikely(!client)) {
1397 err("client is NULL");
1398 ret = -EINVAL;
1399 goto p_err;
1400 }
1401
1402 cis_data = cis->cis_data;
1403
1404 fimc_is_sensor_read16(client, 0x1084, &read_value);
1405
1406 cis_data->min_digital_gain[0] = read_value;
1407
1408 cis_data->min_digital_gain[1] = sensor_cis_calc_dgain_permile(read_value);
1409
1410 *min_dgain = cis_data->min_digital_gain[1];
1411
1412 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
1413 cis_data->min_digital_gain[0], cis_data->min_digital_gain[1]);
1414
1415#ifdef DEBUG_SENSOR_TIME
1416 do_gettimeofday(&end);
1417 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1418#endif
1419
1420p_err:
1421 return ret;
1422}
1423
1424int sensor_2x5sp_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max_dgain)
1425{
1426 int ret = 0;
1427 struct fimc_is_cis *cis;
1428 struct i2c_client *client;
1429 cis_shared_data *cis_data;
1430
1431 u16 read_value = 0;
1432
1433#ifdef DEBUG_SENSOR_TIME
1434 struct timeval st, end;
1435
1436 do_gettimeofday(&st);
1437#endif
1438
1439 FIMC_BUG(!subdev);
1440 FIMC_BUG(!max_dgain);
1441
1442 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1443
1444 FIMC_BUG(!cis);
1445 FIMC_BUG(!cis->cis_data);
1446
1447 client = cis->client;
1448 if (unlikely(!client)) {
1449 err("client is NULL");
1450 ret = -EINVAL;
1451 goto p_err;
1452 }
1453
1454 cis_data = cis->cis_data;
1455
1456 fimc_is_sensor_read16(client, 0x1086, &read_value);
1457
1458 cis_data->max_digital_gain[0] = read_value;
1459
1460 cis_data->max_digital_gain[1] = sensor_cis_calc_dgain_permile(read_value);
1461
1462 *max_dgain = cis_data->max_digital_gain[1];
1463
1464 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
1465 cis_data->max_digital_gain[0], cis_data->max_digital_gain[1]);
1466
1467#ifdef DEBUG_SENSOR_TIME
1468 do_gettimeofday(&end);
1469 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1470#endif
1471
1472p_err:
1473 return ret;
1474}
1475
1476static struct fimc_is_cis_ops cis_ops = {
1477 .cis_init = sensor_2x5sp_cis_init,
1478 .cis_log_status = sensor_2x5sp_cis_log_status,
1479 .cis_group_param_hold = sensor_2x5sp_cis_group_param_hold,
1480 .cis_set_global_setting = sensor_2x5sp_cis_set_global_setting,
1481 .cis_mode_change = sensor_2x5sp_cis_mode_change,
1482 .cis_set_size = sensor_2x5sp_cis_set_size,
1483 .cis_stream_on = sensor_2x5sp_cis_stream_on,
1484 .cis_stream_off = sensor_2x5sp_cis_stream_off,
1485 .cis_set_exposure_time = sensor_2x5sp_cis_set_exposure_time,
1486 .cis_get_min_exposure_time = sensor_2x5sp_cis_get_min_exposure_time,
1487 .cis_get_max_exposure_time = sensor_2x5sp_cis_get_max_exposure_time,
1488 .cis_adjust_frame_duration = sensor_2x5sp_cis_adjust_frame_duration,
1489 .cis_set_frame_duration = sensor_2x5sp_cis_set_frame_duration,
1490 .cis_set_frame_rate = sensor_2x5sp_cis_set_frame_rate,
1491 .cis_adjust_analog_gain = sensor_2x5sp_cis_adjust_analog_gain,
1492 .cis_set_analog_gain = sensor_2x5sp_cis_set_analog_gain,
1493 .cis_get_analog_gain = sensor_2x5sp_cis_get_analog_gain,
1494 .cis_get_min_analog_gain = sensor_2x5sp_cis_get_min_analog_gain,
1495 .cis_get_max_analog_gain = sensor_2x5sp_cis_get_max_analog_gain,
1496 .cis_set_digital_gain = sensor_2x5sp_cis_set_digital_gain,
1497 .cis_get_digital_gain = sensor_2x5sp_cis_get_digital_gain,
1498 .cis_get_min_digital_gain = sensor_2x5sp_cis_get_min_digital_gain,
1499 .cis_get_max_digital_gain = sensor_2x5sp_cis_get_max_digital_gain,
1500 .cis_compensate_gain_for_extremely_br = sensor_cis_compensate_gain_for_extremely_br,
1501 .cis_wait_streamoff = sensor_cis_wait_streamoff,
1502 .cis_wait_streamon = sensor_cis_wait_streamon,
1503 .cis_set_initial_exposure = sensor_cis_set_initial_exposure,
1504 .cis_check_rev = sensor_2x5sp_cis_check_rev,
40d7c17a 1505 .cis_factory_test = sensor_cis_factory_test,
197e9ada
WK
1506};
1507
1508static int cis_2x5sp_probe(struct i2c_client *client,
1509 const struct i2c_device_id *id)
1510{
1511 int ret = 0;
1512 struct fimc_is_core *core = NULL;
1513 struct v4l2_subdev *subdev_cis = NULL;
1514 struct fimc_is_cis *cis = NULL;
1515 struct fimc_is_device_sensor *device = NULL;
1516 struct fimc_is_device_sensor_peri *sensor_peri = NULL;
1517 u32 sensor_id = 0;
1518 char const *setfile;
1519 struct device *dev;
1520 struct device_node *dnode;
1521
1522 FIMC_BUG(!client);
1523 FIMC_BUG(!fimc_is_dev);
1524
1525 core = (struct fimc_is_core *)dev_get_drvdata(fimc_is_dev);
1526 if (!core) {
1527 probe_info("core device is not yet probed");
1528 return -EPROBE_DEFER;
1529 }
1530
1531 dev = &client->dev;
1532 dnode = dev->of_node;
1533
1534 ret = of_property_read_u32(dnode, "id", &sensor_id);
1535 if (ret) {
1536 err("sensor id read is fail(%d)", ret);
1537 goto p_err;
1538 }
1539
1540 probe_info("%s sensor id %d\n", __func__, sensor_id);
1541
1542 device = &core->sensor[sensor_id];
1543
1544 sensor_peri = find_peri_by_cis_id(device, SENSOR_NAME_S5K2X5SP);
1545 if (!sensor_peri) {
1546 probe_info("sensor peri is net yet probed");
1547 return -EPROBE_DEFER;
1548 }
1549
1550 cis = &sensor_peri->cis;
1551 if (!cis) {
1552 err("cis is NULL");
1553 ret = -ENOMEM;
1554 goto p_err;
1555 }
1556
1557 subdev_cis = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
1558 if (!subdev_cis) {
1559 probe_err("subdev_cis NULL");
1560 ret = -ENOMEM;
1561 goto p_err;
1562 }
1563 sensor_peri->subdev_cis = subdev_cis;
1564
1565 cis->id = SENSOR_NAME_S5K2X5SP;
1566 cis->subdev = subdev_cis;
1567 cis->device = 0;
1568 cis->client = client;
1569 sensor_peri->module->client = cis->client;
1570 cis->ctrl_delay = N_PLUS_TWO_FRAME;
1571
1572 cis->cis_data = kzalloc(sizeof(cis_shared_data), GFP_KERNEL);
1573 if (!cis->cis_data) {
1574 err("cis_data is NULL");
1575 ret = -ENOMEM;
1576 goto p_err;
1577 }
1578 cis->cis_ops = &cis_ops;
1579
1580 /* belows are depend on sensor cis. MUST check sensor spec */
1581 cis->bayer_order = OTF_INPUT_ORDER_BAYER_GR_BG;
1582
1583 if (of_property_read_bool(dnode, "sensor_f_number")) {
1584 ret = of_property_read_u32(dnode, "sensor_f_number", &cis->aperture_num);
1585 if (ret)
1586 warn("f-number read is fail(%d)", ret);
1587 } else {
1588 cis->aperture_num = F2_2;
1589 }
1590
1591 probe_info("%s f-number %d\n", __func__, cis->aperture_num);
1592
1593 cis->use_dgain = true;
1594 cis->hdr_ctrl_by_again = false;
1595
1596 ret = of_property_read_string(dnode, "setfile", &setfile);
1597 if (ret) {
1598 err("setfile index read fail(%d), take default setfile!!", ret);
1599 setfile = "default";
1600 }
1601
1602 if (strcmp(setfile, "default") == 0 ||
1603 strcmp(setfile, "setA") == 0) {
1604 probe_info("%s setfile_A\n", __func__);
1605 sensor_2x5sp_global = sensor_2x5sp_setfile_A_Global;
1606 sensor_2x5sp_global_size = ARRAY_SIZE(sensor_2x5sp_setfile_A_Global);
1607 sensor_2x5sp_setfiles = sensor_2x5sp_setfiles_A;
1608 sensor_2x5sp_setfile_sizes = sensor_2x5sp_setfile_A_sizes;
1609 sensor_2x5sp_pllinfos = sensor_2x5sp_pllinfos_A;
1610 sensor_2x5sp_max_setfile_num = ARRAY_SIZE(sensor_2x5sp_setfiles_A);
1611 } else {
1612 err("%s setfile index out of bound, take default (setfile_A)", __func__);
1613 sensor_2x5sp_global = sensor_2x5sp_setfile_A_Global;
1614 sensor_2x5sp_global_size = ARRAY_SIZE(sensor_2x5sp_setfile_A_Global);
1615 sensor_2x5sp_setfiles = sensor_2x5sp_setfiles_A;
1616 sensor_2x5sp_setfile_sizes = sensor_2x5sp_setfile_A_sizes;
1617 sensor_2x5sp_pllinfos = sensor_2x5sp_pllinfos_A;
1618 sensor_2x5sp_max_setfile_num = ARRAY_SIZE(sensor_2x5sp_setfiles_A);
1619 }
1620
1621 cis->use_initial_ae = of_property_read_bool(dnode, "use_initial_ae");
1622 probe_info("%s use initial_ae(%d)\n", __func__, cis->use_initial_ae);
1623
1624 v4l2_i2c_subdev_init(subdev_cis, client, &subdev_ops);
1625 v4l2_set_subdevdata(subdev_cis, cis);
1626 v4l2_set_subdev_hostdata(subdev_cis, device);
1627 snprintf(subdev_cis->name, V4L2_SUBDEV_NAME_SIZE, "cis-subdev.%d", cis->id);
1628
1629 probe_info("%s done\n", __func__);
1630
1631p_err:
1632 return ret;
1633}
1634
1635static const struct of_device_id sensor_cis_2x5sp_match[] = {
1636 {
1637 .compatible = "samsung,exynos5-fimc-is-cis-2x5sp",
1638 },
1639 {},
1640};
1641MODULE_DEVICE_TABLE(of, sensor_cis_2x5sp_match);
1642
1643static const struct i2c_device_id sensor_cis_2x5sp_idt[] = {
1644 { SENSOR_NAME, 0 },
1645 {},
1646};
1647
1648static struct i2c_driver sensor_cis_2x5sp_driver = {
1649 .probe = cis_2x5sp_probe,
1650 .driver = {
1651 .name = SENSOR_NAME,
1652 .owner = THIS_MODULE,
1653 .of_match_table = sensor_cis_2x5sp_match,
1654 .suppress_bind_attrs = true,
1655 },
1656 .id_table = sensor_cis_2x5sp_idt
1657};
1658
1659static int __init sensor_cis_2x5sp_init(void)
1660{
1661 int ret;
1662
1663 ret = i2c_add_driver(&sensor_cis_2x5sp_driver);
1664 if (ret)
1665 err("failed to add %s driver: %d\n",
1666 sensor_cis_2x5sp_driver.driver.name, ret);
1667
1668 return ret;
1669}
1670late_initcall_sync(sensor_cis_2x5sp_init);