[9610] fimc-is2: Buffer modification in case of otp data error at 2x5 module
[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"
3be33d59 41#include "fimc-is-cis-2x5sp-setB.h"
197e9ada
WK
42
43#include "fimc-is-helper-i2c.h"
44
45#define SENSOR_NAME "S5K2X5SP"
46/* #define DEBUG_2X5SP_PLL */
47
48static const struct v4l2_subdev_ops subdev_ops;
49
50static const u32 *sensor_2x5sp_global;
51static u32 sensor_2x5sp_global_size;
52static const u32 **sensor_2x5sp_setfiles;
53static const u32 *sensor_2x5sp_setfile_sizes;
329f08ab 54static const u32 *sensor_2x5sp_otp_initial;
55static u32 sensor_2x5sp_otp_initial_size;
197e9ada
WK
56static const struct sensor_pll_info_compact **sensor_2x5sp_pllinfos;
57static u32 sensor_2x5sp_max_setfile_num;
58
5bccf2ff
WK
59static const u32 *sensor_2x5sp_setfile_throttling;
60static const struct sensor_pll_info_compact *sensor_2x5sp_pllinfo_throttling;
61
197e9ada
WK
62static void sensor_2x5sp_cis_data_calculation(const struct sensor_pll_info_compact *pll_info_compact, cis_shared_data *cis_data)
63{
64 u32 vt_pix_clk_hz = 0;
65 u32 frame_rate = 0, max_fps = 0, frame_valid_us = 0;
66
67 FIMC_BUG_VOID(!pll_info_compact);
68
69 /* 1. get pclk value from pll info */
70 vt_pix_clk_hz = pll_info_compact->pclk;
71
72 dbg_sensor(1, "ext_clock(%d), mipi_datarate(%d), pclk(%d)\n",
73 pll_info_compact->ext_clk, pll_info_compact->mipi_datarate, pll_info_compact->pclk);
74
75 /* 2. the time of processing one frame calculation (us) */
76 cis_data->min_frame_us_time = (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck
77 / (vt_pix_clk_hz / (1000 * 1000)));
78 cis_data->cur_frame_us_time = cis_data->min_frame_us_time;
79
80 /* 3. FPS calculation */
81 frame_rate = vt_pix_clk_hz / (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck);
82 dbg_sensor(1, "frame_rate (%d) = vt_pix_clk_hz(%d) / "
83 KERN_CONT "(pll_info_compact->frame_length_lines(%d) * pll_info_compact->line_length_pck(%d))\n",
84 frame_rate, vt_pix_clk_hz, pll_info_compact->frame_length_lines, pll_info_compact->line_length_pck);
85
86 /* calculate max fps */
87 max_fps = (vt_pix_clk_hz * 10) / (pll_info_compact->frame_length_lines * pll_info_compact->line_length_pck);
88 max_fps = (max_fps % 10 >= 5 ? frame_rate + 1 : frame_rate);
89
90 cis_data->pclk = vt_pix_clk_hz;
91 cis_data->max_fps = max_fps;
92 cis_data->frame_length_lines = pll_info_compact->frame_length_lines;
93 cis_data->line_length_pck = pll_info_compact->line_length_pck;
94 cis_data->line_readOut_time = sensor_cis_do_div64((u64)cis_data->line_length_pck * (u64)(1000 * 1000 * 1000), cis_data->pclk);
95 cis_data->rolling_shutter_skew = (cis_data->cur_height - 1) * cis_data->line_readOut_time;
96 cis_data->stream_on = false;
97
98 /* Frame valid time calcuration */
99 frame_valid_us = sensor_cis_do_div64((u64)cis_data->cur_height * (u64)cis_data->line_length_pck * (u64)(1000 * 1000), cis_data->pclk);
100 cis_data->frame_valid_us_time = (int)frame_valid_us;
101
102 dbg_sensor(1, "%s\n", __func__);
103 dbg_sensor(1, "Sensor size(%d x %d) setting: SUCCESS!\n",
104 cis_data->cur_width, cis_data->cur_height);
105 dbg_sensor(1, "Frame Valid(us): %d\n", frame_valid_us);
106 dbg_sensor(1, "rolling_shutter_skew: %lld\n", cis_data->rolling_shutter_skew);
107
108 dbg_sensor(1, "Fps: %d, max fps(%d)\n", frame_rate, cis_data->max_fps);
109 dbg_sensor(1, "min_frame_time(%d us)\n", cis_data->min_frame_us_time);
110 dbg_sensor(1, "Pixel rate(Mbps): %d\n", cis_data->pclk / 1000000);
111
112 /* Frame period calculation */
113 cis_data->frame_time = (cis_data->line_readOut_time * cis_data->cur_height / 1000);
114 cis_data->rolling_shutter_skew = (cis_data->cur_height - 1) * cis_data->line_readOut_time;
115
116 dbg_sensor(1, "[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__,
117 cis_data->frame_time, cis_data->rolling_shutter_skew);
118
119 /* Constant values */
120 cis_data->min_fine_integration_time = SENSOR_2X5SP_FINE_INTEGRATION_TIME_MIN;
121 cis_data->max_fine_integration_time = cis_data->cur_width;
122 cis_data->min_coarse_integration_time = SENSOR_2X5SP_COARSE_INTEGRATION_TIME_MIN;
123 cis_data->max_margin_coarse_integration_time = SENSOR_2X5SP_COARSE_INTEGRATION_TIME_MAX_MARGIN;
124}
125
126int sensor_2x5sp_cis_check_rev(struct v4l2_subdev *subdev)
127{
128 int ret = 0;
129 u8 rev = 0;
130 struct i2c_client *client;
131 struct fimc_is_cis *cis = NULL;
132
133 WARN_ON(!subdev);
134
135 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
136 WARN_ON(!cis);
137 WARN_ON(!cis->cis_data);
138
139 client = cis->client;
140 if (unlikely(!client)) {
141 err("client is NULL");
09beb98f 142 return -EINVAL;
197e9ada
WK
143 }
144
145 memset(cis->cis_data, 0, sizeof(cis_shared_data));
146 cis->rev_flag = false;
147
148 I2C_MUTEX_LOCK(cis->i2c_lock);
149
150 ret = fimc_is_sensor_read8(client, 0x0002, &rev);
151 if (ret < 0) {
152 cis->rev_flag = true;
153 ret = -EAGAIN;
154 } else {
155 cis->cis_data->cis_rev = rev;
156 pr_info("%s : Rev. 0x%X\n", __func__, rev);
157 }
158
159 I2C_MUTEX_UNLOCK(cis->i2c_lock);
160
161 return ret;
162}
163
5f38b989 164int sensor_2x5sp_cis_otp_check_awb_ratio(char *unit, char *golden, char *limit)
165{
166 int ret = 0;
167
168 float r_g_min = (float)(limit[0]) / 1000;
169 float r_g_max = (float)(limit[1]) / 1000;
170 float b_g_min = (float)(limit[2]) / 1000;
171 float b_g_max = (float)(limit[3]) / 1000;
172
173 float rg = (float) ((unit[1]) | (unit[0] << 8)) / 16384;
174 float bg = (float) ((unit[3]) | (unit[2] << 8)) / 16384;
175
176 float golden_rg = (float) ((golden[1]) | (golden[0] << 8)) / 16384;
177 float golden_bg = (float) ((golden[3]) | (golden[2] << 8)) / 16384;
178
179 if (rg < (golden_rg - r_g_min) || rg > (golden_rg + r_g_max)) {
180 err("%s(): Final RG calibration factors out of range! rg=0x%x golden_rg=0x%x",
181 __func__, (unit[1] | unit[0] << 8), (golden[1] | golden[0] << 8));
182 ret = 1;
183 }
184
185 if (bg < (golden_bg - b_g_min) || bg > (golden_bg + b_g_max)) {
186 err("%s(): Final BG calibration factors out of range! bg=0x%x, golden_bg=0x%x",
187 __func__, (unit[3] | unit[2] << 8), (golden[3] | golden[2] << 8));
188 ret = 1;
189 }
190
191 return ret;
192}
193
329f08ab 194int sensor_2x5sp_cis_otp_check_crc(struct v4l2_subdev *subdev,
195 struct fimc_is_device_sensor *device, int group)
196{
197 int ret = 0;
198 u16 crc_value = 0;
199 u16 crc16 = 0;
200 char *check_buf = (char *)&device->otp_cal_buf[0][0];
201
202 switch (group) {
203 case OTP_GROUP_ONE:
204 /* OTP Group1 CRC check */
205 crc_value = ((device->otp_cal_buf[254][60] << 8) | (device->otp_cal_buf[254][61]));
36c94f81 206 crc16 = sensor_cis_otp_get_crc16(&check_buf[OTP_GRP1_AWB_CRC_START], OTP_GRP1_AWB_CRC_SIZE);
329f08ab 207 if (crc_value != crc16) {
ea1bca5e
DK
208 sensor_cis_otp_data_set(&check_buf[OTP_GRP1_AWB_CRC_START], "awb",
209 OTP_GRP1_AWB_CRC_SIZE, 0xff);
329f08ab 210 err("GR1: Error to AWB CRC16 : 0x%x, cal buffer CRC: 0x%x", crc16, crc_value);
211 ret = -EINVAL;
212 } else
213 info("GR1: AWB CRC16 : 0x%x, cal buffer CRC: 0x%x\n", crc16, crc_value);
214
215 crc_value = ((device->otp_cal_buf[254][62] << 8) | (device->otp_cal_buf[254][63]));
36c94f81 216 crc16 = sensor_cis_otp_get_crc16(&check_buf[OTP_GRP1_LSC_XTC_CRC_START], OTP_GRP1_LSC_XTC_CRC_SIZE);
329f08ab 217 if (crc_value != crc16) {
ea1bca5e
DK
218 sensor_cis_otp_data_set(&check_buf[OTP_GRP1_LSC_XTC_CRC_START], "lsc_xtc",
219 OTP_GRP1_LSC_XTC_CRC_SIZE, 0xff);
329f08ab 220 err("GR1: Error to LSC & XTC CRC16 : 0x%x, cal buffer CRC: 0x%x", crc16, crc_value);
221 ret = -EINVAL;
222 } else
223 info("GR1: LSC & XTC CRC16 : 0x%x, cal buffer CRC: 0x%x\n", crc16, crc_value);
224 break;
225 case OTP_GROUP_TWO:
226 /* OTP Group2 CRC check */
227 crc_value = ((device->otp_cal_buf[255][60] << 8) | (device->otp_cal_buf[255][61]));
36c94f81 228 crc16 = sensor_cis_otp_get_crc16(&check_buf[OTP_GRP2_AWB_CRC_START], OTP_GRP2_AWB_CRC_SIZE);
329f08ab 229 if (crc_value != crc16) {
ea1bca5e
DK
230 sensor_cis_otp_data_set(&check_buf[OTP_GRP2_AWB_CRC_START], "awb",
231 OTP_GRP2_AWB_CRC_SIZE, 0xff);
329f08ab 232 err("GR2: Error to AWB CRC16 : 0x%x, cal buffer CRC: 0x%x", crc16, crc_value);
233 ret = -EINVAL;
234 } else
235 info("GR2: AWB CRC16 : 0x%x, cal buffer CRC: 0x%x\n", crc16, crc_value);
236
237 crc_value = ((device->otp_cal_buf[255][62] << 8) | (device->otp_cal_buf[255][63]));
36c94f81 238 crc16 = sensor_cis_otp_get_crc16(&check_buf[OTP_GRP2_LSC_XTC_CRC_START], OTP_GRP2_LSC_XTC_CRC_SIZE);
329f08ab 239 if (crc_value != crc16) {
ea1bca5e
DK
240 sensor_cis_otp_data_set(&check_buf[OTP_GRP2_LSC_XTC_CRC_START], "lsc_xtc",
241 OTP_GRP2_LSC_XTC_CRC_SIZE, 0xff);
329f08ab 242 err("GR2: Error to LSC & XTC CRC16 : 0x%x, cal buffer CRC: 0x%x", crc16, crc_value);
243 ret = -EINVAL;
244 } else
245 info("GR2: LSC & XTC CRC16 : 0x%x, cal buffer CRC: 0x%x\n", crc16, crc_value);
5f38b989 246 break;
329f08ab 247 default:
248 err("invalid OTP group when crc check(%d), check map data", group);
249 break;
250 }
251
252 return ret;
253}
254
329f08ab 255static int sensor_2x5sp_cis_otp_check(struct fimc_is_device_sensor *device, int group)
256{
257 int ret = 0;
5f38b989 258 u16 group_flag = 0;
329f08ab 259
260 switch (group) {
261 case OTP_GROUP_ONE:
262 /* Group1 valid check */
5f38b989 263 group_flag = device->otp_cal_buf[254][0];
264 if (group_flag != OTP_DATA_VALID) {
265 err("error Group1 OTP data invalid(0x%x)", group_flag);
329f08ab 266 ret = -EINVAL;
5f38b989 267 } else {
268 ret = OTP_GROUP_ONE;
269 }
329f08ab 270
271 break;
272 case OTP_GROUP_TWO:
273 /* First check Group2 data valid */
5f38b989 274 group_flag = device->otp_cal_buf[255][0];
275 if (group_flag != OTP_DATA_VALID) {
276 err("error Group2 OTP data invalid(0x%x)", group_flag);
329f08ab 277 ret = -EINVAL;
278
5f38b989 279 } else {
280 ret = OTP_GROUP_TWO;
281 }
329f08ab 282
283 break;
284 default:
285 err("invalid OTP group when invalid check(%d), check map data", group);
286 break;
287 }
288
289 return ret;
290}
291
329f08ab 292int sensor_2x5sp_cis_otp_read(struct v4l2_subdev *subdev, struct fimc_is_device_sensor *device)
293{
294 int ret = 0;
295 struct fimc_is_cis *cis;
296 struct i2c_client *client;
f59c725f 297 u16 val = 1, page;
329f08ab 298 int i;
f59c725f 299 int retry;
329f08ab 300
301 FIMC_BUG(!subdev);
302
303 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
304 if (!cis) {
305 err("cis is NULL");
09beb98f 306 return -EINVAL;
329f08ab 307 }
308
309 client = cis->client;
310 if (unlikely(!client)) {
311 err("client is NULL");
09beb98f 312 return -ENODEV;
329f08ab 313 }
314
f59c725f 315 info("OTP read start\n");
329f08ab 316 dbg_sensor(1, "%s, 1. sensor initial setting", __func__);
329f08ab 317
09beb98f
WK
318 I2C_MUTEX_LOCK(cis->i2c_lock);
319
18c8b660
WK
320 /* Basic settings for OTP R/W */
321 fimc_is_sensor_write16(client, 0x6028, 0x4000);
322 fimc_is_sensor_write16(client, 0x6018, 0x0001);
323 fimc_is_sensor_write16(client, 0x7002, 0x020C);
324 fimc_is_sensor_write16(client, 0x6014, 0x0001);
325
326 usleep_range(3000, 3001);
327
328 fimc_is_sensor_write16(client, 0x0136, 0x1A00);
329 fimc_is_sensor_write16(client, 0x0300, 0x0003);
330 fimc_is_sensor_write16(client, 0x0302, 0x0001);
331 fimc_is_sensor_write16(client, 0x0304, 0x0004);
332 fimc_is_sensor_write16(client, 0x0306, 0x00DD);
333 fimc_is_sensor_write16(client, 0x030C, 0x0001);
334 fimc_is_sensor_write16(client, 0x0308, 0x0008);
335 fimc_is_sensor_write16(client, 0x030A, 0x0001);
336 fimc_is_sensor_write16(client, 0x030E, 0x0004);
337 fimc_is_sensor_write16(client, 0x0310, 0x014A);
338 fimc_is_sensor_write16(client, 0x0312, 0x0000);
339
329f08ab 340 dbg_sensor(1, "%s, 2. sensor stream on", __func__);
341 fimc_is_sensor_write16(client, 0x6028, 0x4000);
342 fimc_is_sensor_write8(client, 0x0100, 0x01);
343
18c8b660
WK
344 /* wait streamon */
345 CALL_CISOPS(cis, cis_wait_streamon, subdev);
329f08ab 346
347 dbg_sensor(1, "%s, 3. page select & read cal", __func__);
348 for (page = OTP_PAGE_START; page <= OTP_PAGE_END; page++) {
349 /* page select & read start */
350 fimc_is_sensor_write16(client, OTP_PAGE_SELECT, page);
351 fimc_is_sensor_write16(client, OTP_PAGE_CTRL, 0x0100);
352
353 /* wait 0x0A00 == 0 [0]: read completed with no errors */
f59c725f
WK
354 retry = 500;
355 while (retry > 0 && val) {
329f08ab 356 fimc_is_sensor_read16(client, OTP_PAGE_CTRL, &val);
357 if (val == 0)
358 break;
359
360 usleep_range(100, 100);
f59c725f 361 retry--;
329f08ab 362 }
363
f59c725f
WK
364 if (!retry)
365 err("%s: OTP page[%d] read fail with err(%d)\n",
366 __func__, page, val);
367
329f08ab 368 for (i = 0; i < OTP_PAGE_SIZE; i++) {
369 fimc_is_sensor_read8(client, OTP_PAGE_BASE + i, &device->otp_cal_buf[page][i]);
370 dbg_sensor(2, "cal: [%d][0x%x]: %x\n", page, OTP_PAGE_BASE + i, device->otp_cal_buf[page][i]);
371 }
372
373 /* make initial state */
374 fimc_is_sensor_write16(client, OTP_PAGE_CTRL, 0x0000);
375 }
376
377 fimc_is_sensor_write8(client, 0x0100, 0x00);
378 msleep(20);
f59c725f 379 info("OTP read end\n");
09beb98f
WK
380
381 I2C_MUTEX_UNLOCK(cis->i2c_lock);
329f08ab 382
383 return ret;
384}
385
386int sensor_2x5sp_cis_otp(struct v4l2_subdev *subdev, struct fimc_is_device_sensor *device)
387{
388 int ret = 0;
389 int i;
5f38b989 390 int otp_group = 0x0;
391 char *otp_buf = (char *)&device->otp_cal_buf[0][0];
329f08ab 392
36c94f81 393 ret = sensor_cis_otp_read_file(OTP_DATA_PATH, (void *)device->otp_cal_buf, OTP_PAGE_SIZE * 256);
329f08ab 394 if (ret) {
395 /* OTP data read */
396 ret = sensor_2x5sp_cis_otp_read(subdev, device);
397 if (ret < 0) {
ea1bca5e 398 sensor_cis_otp_data_set(&otp_buf[0], "all", OTP_PAGE_SIZE * 256, 0xff);
329f08ab 399 err("Don't read to 2x5 OTP data");
400 goto p_err;
401 }
402
329f08ab 403 /* Write to OTP data at file */
36c94f81 404 ret = sensor_cis_otp_write_file(OTP_DATA_PATH, (void *)device->otp_cal_buf, OTP_PAGE_SIZE * 256);
329f08ab 405 if (ret < 0) {
ea1bca5e 406 sensor_cis_otp_data_set(&otp_buf[0], "all", OTP_PAGE_SIZE * 256, 0xff);
329f08ab 407 err("2x5 OTP data don't file write");
408 goto p_err;
409 }
5f38b989 410 }
329f08ab 411
5f38b989 412 /* Need to first check GROUP2 */
413 for (i = OTP_GROUP_MAX - 1; i >= OTP_GROUP_ONE; i--) {
414 /* OTP valid check */
415 otp_group = sensor_2x5sp_cis_otp_check(device, i);
416 if (otp_group < 0) {
417 if (i == OTP_GROUP_ONE) {
ea1bca5e 418 sensor_cis_otp_data_set(&otp_buf[0], "all", OTP_PAGE_SIZE * 256, 0xff);
5f38b989 419 err("All OTP data are invalid, check module");
420 goto p_err;
421 } else {
422 continue;
329f08ab 423 }
5f38b989 424 } else {
425 break;
426 }
427 }
428
429 /* OTP CRC check */
430 ret = sensor_2x5sp_cis_otp_check_crc(subdev, device, otp_group);
431 if (ret < 0) {
432 err("All OTP data CRC check fail, check module");
433
434 device->cal_status[CAMERA_CRC_INDEX_AWB] = CRC_ERROR;
435 goto p_err;
436 } else {
437 err("%s: OTP group%d data availble\n", __func__, otp_group);
438
439 device->cal_status[CAMERA_CRC_INDEX_AWB] = CRC_NO_ERROR;
440
441 ret = sensor_2x5sp_cis_otp_check_awb_ratio(&otp_buf[(253 + otp_group) * OTP_PAGE_SIZE + OTP_AWB_UNIT_OFFSET],
442 &otp_buf[(253 + otp_group) * OTP_PAGE_SIZE + OTP_AWB_GOLDEN_OFFSET],
443 &otp_buf[(253 + otp_group) * OTP_PAGE_SIZE + OTP_AWB_LIMIT_OFFSET]);
444
445 if (ret) {
446 err("%s(): 2X5 OTP AWB Group%d ratio out of limit(%d)", __func__, otp_group, ret);
447 device->cal_status[CAMERA_CRC_INDEX_AWB] = LIMIT_FAILURE;
448 ret = -1;
329f08ab 449 }
450 }
451
452p_err:
453 return ret;
454}
455
197e9ada
WK
456/* CIS OPS */
457int sensor_2x5sp_cis_init(struct v4l2_subdev *subdev)
458{
459 int ret = 0;
460 struct fimc_is_cis *cis;
329f08ab 461 struct fimc_is_module_enum *module;
462 struct fimc_is_device_sensor *device = NULL;
197e9ada
WK
463 u32 setfile_index = 0;
464 cis_setting_info setinfo;
465
466 setinfo.return_value = 0;
467
468 setinfo.param = NULL;
469
470 FIMC_BUG(!subdev);
471
329f08ab 472 module = (struct fimc_is_module_enum *)v4l2_get_subdev_hostdata(subdev);
473
474 device = (struct fimc_is_device_sensor *)v4l2_get_subdev_hostdata(module->subdev);
475 if (!device) {
476 err("device sensor is NULL");
477 ret = -ENODEV;
478 goto p_err;
479 }
480
197e9ada
WK
481 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
482 if (!cis) {
483 err("cis is NULL");
484 ret = -EINVAL;
485 goto p_err;
486 }
487
488 FIMC_BUG(!cis->cis_data);
489 memset(cis->cis_data, 0, sizeof(cis_shared_data));
490
491 cis->cis_data->cur_width = SENSOR_2X5SP_MAX_WIDTH;
492 cis->cis_data->cur_height = SENSOR_2X5SP_MAX_HEIGHT;
493 cis->cis_data->low_expo_start = 33000;
494 cis->need_mode_change = false;
495
496 sensor_2x5sp_cis_data_calculation(sensor_2x5sp_pllinfos[setfile_index], cis->cis_data);
497
498 setinfo.return_value = 0;
499 CALL_CISOPS(cis, cis_get_min_exposure_time, subdev, &setinfo.return_value);
500 dbg_sensor(1, "[%s] min exposure time : %d\n", __func__, setinfo.return_value);
501 setinfo.return_value = 0;
502 CALL_CISOPS(cis, cis_get_max_exposure_time, subdev, &setinfo.return_value);
503 dbg_sensor(1, "[%s] max exposure time : %d\n", __func__, setinfo.return_value);
504 setinfo.return_value = 0;
505 CALL_CISOPS(cis, cis_get_min_analog_gain, subdev, &setinfo.return_value);
506 dbg_sensor(1, "[%s] min again : %d\n", __func__, setinfo.return_value);
507 setinfo.return_value = 0;
508 CALL_CISOPS(cis, cis_get_max_analog_gain, subdev, &setinfo.return_value);
509 dbg_sensor(1, "[%s] max again : %d\n", __func__, setinfo.return_value);
510 setinfo.return_value = 0;
511 CALL_CISOPS(cis, cis_get_min_digital_gain, subdev, &setinfo.return_value);
512 dbg_sensor(1, "[%s] min dgain : %d\n", __func__, setinfo.return_value);
513 setinfo.return_value = 0;
514 CALL_CISOPS(cis, cis_get_max_digital_gain, subdev, &setinfo.return_value);
515 dbg_sensor(1, "[%s] max dgain : %d\n", __func__, setinfo.return_value);
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
329f08ab 522 if (device->use_otp_cal) {
523 ret = sensor_2x5sp_cis_otp(subdev, device);
524 if (ret < 0) {
525 err("2x5sp OTP data have probelm, check module");
526 ret = 0;
527 }
528 }
529
197e9ada
WK
530p_err:
531 return ret;
532}
533
534int sensor_2x5sp_cis_log_status(struct v4l2_subdev *subdev)
535{
536 int ret = 0;
537 struct fimc_is_cis *cis;
538 struct i2c_client *client = NULL;
539 u8 data8 = 0;
540 u16 data16 = 0;
541
542 FIMC_BUG(!subdev);
543
544 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
545 if (!cis) {
546 err("cis is NULL");
09beb98f 547 return -ENODEV;
197e9ada
WK
548 }
549
550 client = cis->client;
551 if (unlikely(!client)) {
552 err("client is NULL");
09beb98f 553 return -ENODEV;
197e9ada
WK
554 }
555
09beb98f
WK
556 I2C_MUTEX_LOCK(cis->i2c_lock);
557
197e9ada
WK
558 pr_err("[SEN:DUMP] *******************************\n");
559 fimc_is_sensor_read16(client, 0x0000, &data16);
560 pr_err("[SEN:DUMP] model_id(%x)\n", data16);
561 fimc_is_sensor_read8(client, 0x0002, &data8);
562 pr_err("[SEN:DUMP] revision_number(%x)\n", data8);
563 fimc_is_sensor_read8(client, 0x0005, &data8);
564 pr_err("[SEN:DUMP] frame_count(%x)\n", data8);
565 fimc_is_sensor_read8(client, 0x0100, &data8);
566 pr_err("[SEN:DUMP] mode_select(%x)\n", data8);
567
568 sensor_cis_dump_registers(subdev, sensor_2x5sp_setfiles[0], sensor_2x5sp_setfile_sizes[0]);
569
09beb98f
WK
570 I2C_MUTEX_UNLOCK(cis->i2c_lock);
571
197e9ada
WK
572 pr_err("[SEN:DUMP] *******************************\n");
573
197e9ada
WK
574 return ret;
575}
576
577#if USE_GROUP_PARAM_HOLD
578static int sensor_2x5sp_cis_group_param_hold_func(struct v4l2_subdev *subdev, unsigned int hold)
579{
580 int ret = 0;
581 struct fimc_is_cis *cis = NULL;
582 struct i2c_client *client = NULL;
583
584 FIMC_BUG(!subdev);
585
586 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
587
588 FIMC_BUG(!cis);
589 FIMC_BUG(!cis->cis_data);
590
591 client = cis->client;
592 if (unlikely(!client)) {
593 err("client is NULL");
594 ret = -EINVAL;
595 goto p_err;
596 }
597
598 if (hold == cis->cis_data->group_param_hold) {
599 pr_debug("already group_param_hold (%d)\n", cis->cis_data->group_param_hold);
600 goto p_err;
601 }
602
603 ret = fimc_is_sensor_write8(client, 0x0104, hold);
604 if (ret < 0)
605 goto p_err;
606
607 cis->cis_data->group_param_hold = hold;
608 ret = 1;
609p_err:
610 return ret;
611}
612#else
613static inline int sensor_2x5sp_cis_group_param_hold_func(struct v4l2_subdev *subdev, unsigned int hold)
614{ return 0; }
615#endif
616
617/* Input
618 * hold : true - hold, flase - no hold
619 * Output
620 * return: 0 - no effect(already hold or no hold)
621 * positive - setted by request
622 * negative - ERROR value
623 */
624int sensor_2x5sp_cis_group_param_hold(struct v4l2_subdev *subdev, bool hold)
625{
626 int ret = 0;
627 struct fimc_is_cis *cis = NULL;
628
629 FIMC_BUG(!subdev);
630
631 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
632
633 FIMC_BUG(!cis);
634 FIMC_BUG(!cis->cis_data);
635
09beb98f
WK
636 I2C_MUTEX_LOCK(cis->i2c_lock);
637
197e9ada
WK
638 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, hold);
639 if (ret < 0)
640 goto p_err;
641
642p_err:
09beb98f
WK
643 I2C_MUTEX_UNLOCK(cis->i2c_lock);
644
197e9ada
WK
645 return ret;
646}
647
648int sensor_2x5sp_cis_set_global_setting(struct v4l2_subdev *subdev)
649{
650 int ret = 0;
651 struct fimc_is_cis *cis = NULL;
652
653 FIMC_BUG(!subdev);
654
655 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
656 FIMC_BUG(!cis);
657
09beb98f
WK
658 I2C_MUTEX_LOCK(cis->i2c_lock);
659
197e9ada
WK
660 ret = sensor_cis_set_registers(subdev, sensor_2x5sp_global, sensor_2x5sp_global_size);
661
662 if (ret < 0) {
663 err("sensor_3p8sp_set_registers fail!!");
664 goto p_err;
665 }
666
667 dbg_sensor(1, "[%s] global setting done\n", __func__);
668
669p_err:
09beb98f
WK
670 I2C_MUTEX_UNLOCK(cis->i2c_lock);
671
197e9ada
WK
672 return ret;
673}
674
675int sensor_2x5sp_cis_mode_change(struct v4l2_subdev *subdev, u32 mode)
676{
677 int ret = 0;
678 struct fimc_is_cis *cis = NULL;
679
680 FIMC_BUG(!subdev);
681
682 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
683 FIMC_BUG(!cis);
684 FIMC_BUG(!cis->cis_data);
685
686 if (mode > sensor_2x5sp_max_setfile_num) {
687 err("invalid mode(%d)!!", mode);
09beb98f 688 return -EINVAL;
197e9ada
WK
689 }
690
691 sensor_2x5sp_cis_data_calculation(sensor_2x5sp_pllinfos[mode], cis->cis_data);
692
09beb98f
WK
693 I2C_MUTEX_LOCK(cis->i2c_lock);
694
197e9ada
WK
695 ret = sensor_cis_set_registers(subdev, sensor_2x5sp_setfiles[mode], sensor_2x5sp_setfile_sizes[mode]);
696 if (ret < 0) {
697 err("sensor_2x5sp_set_registers fail!!");
698 goto p_err;
699 }
700
701 cis->cis_data->frame_time = (cis->cis_data->line_readOut_time * cis->cis_data->cur_height / 1000);
702 cis->cis_data->rolling_shutter_skew = (cis->cis_data->cur_height - 1) * cis->cis_data->line_readOut_time;
703 dbg_sensor(1, "[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__,
704 cis->cis_data->frame_time, cis->cis_data->rolling_shutter_skew);
705
706 dbg_sensor(1, "[%s] mode changed(%d)\n", __func__, mode);
707
708p_err:
09beb98f
WK
709 I2C_MUTEX_UNLOCK(cis->i2c_lock);
710
197e9ada
WK
711 return ret;
712}
713
5bccf2ff
WK
714int sensor_2x5sp_cis_mode_change_throttling(struct v4l2_subdev *subdev)
715{
716 int ret = 0;
717 struct fimc_is_cis *cis = NULL;
718
719 FIMC_BUG(!subdev);
720
721 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
722 FIMC_BUG(!cis);
723 FIMC_BUG(!cis->cis_data);
724
725 sensor_2x5sp_cis_data_calculation(sensor_2x5sp_pllinfo_throttling, cis->cis_data);
726
727 I2C_MUTEX_LOCK(cis->i2c_lock);
728
729 ret = sensor_cis_set_registers(subdev, sensor_2x5sp_setfile_throttling,
730 sizeof(sensor_2x5sp_setfile_throttling) / sizeof(sensor_2x5sp_setfile_throttling[0]));
731 if (ret < 0) {
732 err("sensor_gm1sp_set_registers fail!!");
733 goto p_err;
734 }
735
736 cis->cis_data->frame_time = (cis->cis_data->line_readOut_time * cis->cis_data->cur_height / 1000);
737 cis->cis_data->rolling_shutter_skew = (cis->cis_data->cur_height - 1) * cis->cis_data->line_readOut_time;
738 dbg_sensor(1, "[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__,
739 cis->cis_data->frame_time, cis->cis_data->rolling_shutter_skew);
740
741 dbg_sensor(1, "[%s] throttling mode changed\n", __func__);
742
743p_err:
744 I2C_MUTEX_UNLOCK(cis->i2c_lock);
745
746 return ret;
747}
748
197e9ada
WK
749/* Deprecated */
750int sensor_2x5sp_cis_set_size(struct v4l2_subdev *subdev, cis_shared_data *cis_data)
751{
752 return 0;
753}
754
755int sensor_2x5sp_cis_stream_on(struct v4l2_subdev *subdev)
756{
757 int ret = 0;
758 struct fimc_is_cis *cis;
759 struct i2c_client *client;
760 cis_shared_data *cis_data;
761
762#ifdef DEBUG_SENSOR_TIME
763 struct timeval st, end;
764
765 do_gettimeofday(&st);
766#endif
767
768 FIMC_BUG(!subdev);
769
770 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
771
772 FIMC_BUG(!cis);
773 FIMC_BUG(!cis->cis_data);
774
775 client = cis->client;
776 if (unlikely(!client)) {
777 err("client is NULL");
09beb98f 778 return -EINVAL;
197e9ada
WK
779 }
780
781 cis_data = cis->cis_data;
782
783 dbg_sensor(1, "[MOD:D:%d] %s\n", cis->id, __func__);
784
09beb98f
WK
785 I2C_MUTEX_LOCK(cis->i2c_lock);
786
197e9ada
WK
787 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
788 if (ret < 0)
789 err("group_param_hold_func failed at stream on");
790
791#ifdef DEBUG_2X5SP_PLL
792 {
793 u16 pll;
794
795 fimc_is_sensor_read16(client, 0x0300, &pll);
796 dbg_sensor(1, "______ vt_pix_clk_div(%x)\n", pll);
797 fimc_is_sensor_read16(client, 0x0302, &pll);
798 dbg_sensor(1, "______ vt_sys_clk_div(%x)\n", pll);
799 fimc_is_sensor_read16(client, 0x0304, &pll);
800 dbg_sensor(1, "______ pre_pll_clk_div(%x)\n", pll);
801 fimc_is_sensor_read16(client, 0x0306, &pll);
802 dbg_sensor(1, "______ pll_multiplier(%x)\n", pll);
803 fimc_is_sensor_read16(client, 0x0308, &pll);
804 dbg_sensor(1, "______ op_pix_clk_div(%x)\n", pll);
805 fimc_is_sensor_read16(client, 0x030a, &pll);
806 dbg_sensor(1, "______ op_sys_clk_div(%x)\n", pll);
807
808 fimc_is_sensor_read16(client, 0x030c, &pll);
809 dbg_sensor(1, "______ secnd_pre_pll_clk_div(%x)\n", pll);
810 fimc_is_sensor_read16(client, 0x030e, &pll);
811 dbg_sensor(1, "______ secnd_pll_multiplier(%x)\n", pll);
812 fimc_is_sensor_read16(client, 0x0340, &pll);
813 dbg_sensor(1, "______ frame_length_lines(%x)\n", pll);
814 fimc_is_sensor_read16(client, 0x0342, &pll);
815 dbg_sensor(1, "______ line_length_pck(%x)\n", pll);
816 }
817#endif
818
819 /* Sensor stream on */
820 fimc_is_sensor_write16(client, 0x6028, 0x4000);
821 fimc_is_sensor_write8(client, 0x0100, 0x01);
822
197e9ada
WK
823 cis_data->stream_on = true;
824
825#ifdef DEBUG_SENSOR_TIME
826 do_gettimeofday(&end);
827 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
828#endif
829
09beb98f
WK
830 I2C_MUTEX_UNLOCK(cis->i2c_lock);
831
197e9ada
WK
832 return ret;
833}
834
835int sensor_2x5sp_cis_stream_off(struct v4l2_subdev *subdev)
836{
837 int ret = 0;
838 struct fimc_is_cis *cis;
839 struct i2c_client *client;
840 cis_shared_data *cis_data;
841
842#ifdef DEBUG_SENSOR_TIME
843 struct timeval st, end;
844
845 do_gettimeofday(&st);
846#endif
847
848 FIMC_BUG(!subdev);
849
850 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
851
852 FIMC_BUG(!cis);
853 FIMC_BUG(!cis->cis_data);
854
855 client = cis->client;
856 if (unlikely(!client)) {
857 err("client is NULL");
09beb98f 858 return -EINVAL;
197e9ada
WK
859 }
860
861 cis_data = cis->cis_data;
862
863 dbg_sensor(1, "[MOD:D:%d] %s\n", cis->id, __func__);
864
09beb98f
WK
865 I2C_MUTEX_LOCK(cis->i2c_lock);
866
197e9ada
WK
867 ret = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
868 if (ret < 0)
869 err("group_param_hold_func failed at stream off");
870
197e9ada 871 fimc_is_sensor_write16(client, 0x6028, 0x4000);
53a66096
WK
872
873 /* during LEC mode, clear 0x0BCC before stream off for next frame
874 * After cancelled, restore value
875 */
876 if (cis->long_term_mode.sen_strm_off_on_enable)
877 fimc_is_sensor_write8(client, 0x0BCC, 0);
878 else
879 fimc_is_sensor_write8(client, 0x0BCC, 0x1);
880
881 /* Sensor stream off */
197e9ada
WK
882 fimc_is_sensor_write8(client, 0x0100, 0x00);
883
884 cis_data->stream_on = false;
885
886#ifdef DEBUG_SENSOR_TIME
887 do_gettimeofday(&end);
888 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
889#endif
890
09beb98f
WK
891 I2C_MUTEX_UNLOCK(cis->i2c_lock);
892
197e9ada
WK
893 return ret;
894}
895
896int sensor_2x5sp_cis_set_exposure_time(struct v4l2_subdev *subdev, struct ae_param *target_exposure)
897{
898 int ret = 0;
899 int hold = 0;
900 struct fimc_is_cis *cis;
901 struct i2c_client *client;
902 cis_shared_data *cis_data;
903
904 u32 vt_pic_clk_freq_mhz = 0;
905 u16 long_coarse_int = 0;
906 u16 short_coarse_int = 0;
a7ba7b0a 907 u16 middle_coarse_int = 0;
197e9ada
WK
908 u32 line_length_pck = 0;
909 u32 min_fine_int = 0;
a0ed8db4
WK
910 u64 numerator;
911 u8 lte_shifter;
7f59bf56 912 u32 multiple_ratio = 1;
197e9ada
WK
913#ifdef DEBUG_SENSOR_TIME
914 struct timeval st, end;
915
916 do_gettimeofday(&st);
917#endif
918
919 FIMC_BUG(!subdev);
920 FIMC_BUG(!target_exposure);
921
922 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
923
924 FIMC_BUG(!cis);
925 FIMC_BUG(!cis->cis_data);
926
927 client = cis->client;
928 if (unlikely(!client)) {
929 err("client is NULL");
09beb98f 930 return -EINVAL;
197e9ada
WK
931 }
932
933 if ((target_exposure->long_val <= 0) || (target_exposure->short_val <= 0)) {
934 err("[%s] invalid target exposure(%d, %d)\n", __func__,
935 target_exposure->long_val, target_exposure->short_val);
09beb98f 936 return -EINVAL;
197e9ada
WK
937 }
938
939 cis_data = cis->cis_data;
940
a7ba7b0a
WK
941 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), target long(%d), short(%d), middle(%d)\n", cis->id, __func__,
942 cis_data->sen_vsync_count,
943 target_exposure->long_val, target_exposure->short_val, target_exposure->middle_val);
197e9ada
WK
944
945 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
946 line_length_pck = cis_data->line_length_pck;
947 min_fine_int = cis_data->min_fine_integration_time;
948
a0ed8db4
WK
949 lte_shifter = cis->long_term_mode.sen_strm_off_on_enable ?
950 GET_2X5SP_LTE_SHIFT_CNT(target_exposure->long_val) : 0;
951
7f59bf56
DK
952 /* In 24M remosaic mode, set 4 times of exposure val */
953 if (cis_data->sens_config_index_cur == SENSOR_2X5SP_5760X4320_24FPS) {
954 multiple_ratio = 4;
955 dbg_sensor(1, "[mod:d:%d] %s, Set 4 times of coarse_int for 24M mode\n", cis->id, __func__);
956 }
957
958 numerator = (u64)cis_data->pclk * target_exposure->long_val * multiple_ratio;
a0ed8db4
WK
959 long_coarse_int = (numerator - min_fine_int)
960 /(1000 * 1000) / line_length_pck / (1 << lte_shifter);
7f59bf56 961 numerator = (u64)cis_data->pclk * target_exposure->short_val * multiple_ratio;
a0ed8db4
WK
962 short_coarse_int = (numerator - min_fine_int)
963 /(1000 * 1000) / line_length_pck / (1 << lte_shifter);
7f59bf56 964 numerator = (u64)cis_data->pclk * target_exposure->middle_val * multiple_ratio;
a0ed8db4
WK
965 middle_coarse_int = (numerator - min_fine_int)
966 /(1000 * 1000) / line_length_pck / (1 << lte_shifter);
197e9ada 967
17c5351c
WK
968 /* 4FDSUM mode should be set half of coarse integration */
969 if (cis_data->sens_config_index_cur == SENSOR_2X5SP_2880X2160_30FPS
970 || cis_data->sens_config_index_cur == SENSOR_2X5SP_1920X1080_120FPS
971 || cis_data->sens_config_index_cur == SENSOR_2X5SP_1280X720_240FPS) {
972 long_coarse_int /= 2;
973 short_coarse_int /= 2;
974 middle_coarse_int /= 2;
975 }
976
197e9ada
WK
977 if (long_coarse_int > cis_data->max_coarse_integration_time) {
978 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), long coarse(%d) max(%d)\n", cis->id, __func__,
979 cis_data->sen_vsync_count, long_coarse_int, cis_data->max_coarse_integration_time);
980 long_coarse_int = cis_data->max_coarse_integration_time;
981 }
982
983 if (short_coarse_int > cis_data->max_coarse_integration_time) {
984 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), short coarse(%d) max(%d)\n", cis->id, __func__,
985 cis_data->sen_vsync_count, short_coarse_int, cis_data->max_coarse_integration_time);
986 short_coarse_int = cis_data->max_coarse_integration_time;
987 }
988
a7ba7b0a
WK
989 if (middle_coarse_int > cis_data->max_coarse_integration_time) {
990 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), middle coarse(%d) max(%d)\n", cis->id, __func__,
991 cis_data->sen_vsync_count, middle_coarse_int, cis_data->max_coarse_integration_time);
992 middle_coarse_int = cis_data->max_coarse_integration_time;
993 }
994
197e9ada
WK
995 if (long_coarse_int < cis_data->min_coarse_integration_time) {
996 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), long coarse(%d) min(%d)\n", cis->id, __func__,
997 cis_data->sen_vsync_count, long_coarse_int, cis_data->min_coarse_integration_time);
998 long_coarse_int = cis_data->min_coarse_integration_time;
999 }
1000
1001 if (short_coarse_int < cis_data->min_coarse_integration_time) {
1002 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), short coarse(%d) min(%d)\n", cis->id, __func__,
1003 cis_data->sen_vsync_count, short_coarse_int, cis_data->min_coarse_integration_time);
1004 short_coarse_int = cis_data->min_coarse_integration_time;
1005 }
1006
a7ba7b0a
WK
1007 if (middle_coarse_int < cis_data->min_coarse_integration_time) {
1008 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), middle coarse(%d) min(%d)\n", cis->id, __func__,
1009 cis_data->sen_vsync_count, middle_coarse_int, cis_data->min_coarse_integration_time);
1010 middle_coarse_int = cis_data->min_coarse_integration_time;
1011 }
1012
09beb98f
WK
1013 I2C_MUTEX_LOCK(cis->i2c_lock);
1014
197e9ada
WK
1015 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1016 if (hold < 0) {
1017 ret = hold;
1018 goto p_err;
1019 }
1020
1021 /* Short exposure */
1022 ret = fimc_is_sensor_write16(client, 0x0202, short_coarse_int);
1023 if (ret < 0)
1024 goto p_err;
1025
1026 /* Long exposure */
a7ba7b0a 1027 if (cis_data->is_data.wdr_mode != CAMERA_WDR_OFF) {
197e9ada
WK
1028 ret = fimc_is_sensor_write16(client, 0x0226, long_coarse_int);
1029 if (ret < 0)
1030 goto p_err;
1031
a7ba7b0a
WK
1032 ret = fimc_is_sensor_write16(client, 0x022C, middle_coarse_int);
1033 if (ret < 0)
1034 goto p_err;
197e9ada
WK
1035 }
1036
1037 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",
1038 cis->id, __func__, cis_data->sen_vsync_count, vt_pic_clk_freq_mhz, line_length_pck, min_fine_int);
a7ba7b0a 1039 dbg_sensor(1, "[MOD:D:%d] %s, vsync_cnt(%d), frame_length_lines(%#x), coarse_int (L:%#x, S:%#x, M:%#x)\n",
197e9ada 1040 cis->id, __func__, cis_data->sen_vsync_count, cis_data->frame_length_lines,
a7ba7b0a 1041 long_coarse_int, short_coarse_int, middle_coarse_int);
197e9ada
WK
1042
1043#ifdef DEBUG_SENSOR_TIME
1044 do_gettimeofday(&end);
1045 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1046#endif
1047
1048p_err:
1049 if (hold > 0) {
1050 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1051 if (hold < 0)
1052 ret = hold;
1053 }
1054
09beb98f
WK
1055 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1056
197e9ada
WK
1057 return ret;
1058}
1059
1060int sensor_2x5sp_cis_get_min_exposure_time(struct v4l2_subdev *subdev, u32 *min_expo)
1061{
1062 int ret = 0;
1063 struct fimc_is_cis *cis = NULL;
1064 cis_shared_data *cis_data = NULL;
1065 u32 min_integration_time = 0;
1066 u32 min_coarse = 0;
1067 u32 min_fine = 0;
1068 u32 vt_pic_clk_freq_mhz = 0;
1069 u32 line_length_pck = 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(!min_expo);
1079
1080 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1081
1082 FIMC_BUG(!cis);
1083 FIMC_BUG(!cis->cis_data);
1084
1085 cis_data = cis->cis_data;
1086
1087 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
1088 if (vt_pic_clk_freq_mhz == 0) {
1089 pr_err("[MOD:D:%d] %s, Invalid vt_pic_clk_freq_mhz(%d)\n", cis->id, __func__, vt_pic_clk_freq_mhz);
1090 goto p_err;
1091 }
1092 line_length_pck = cis_data->line_length_pck;
1093 min_coarse = cis_data->min_coarse_integration_time;
1094 min_fine = cis_data->min_fine_integration_time;
1095
1096 min_integration_time = ((line_length_pck * min_coarse) + min_fine) / vt_pic_clk_freq_mhz;
1097 *min_expo = min_integration_time;
1098
1099 dbg_sensor(1, "[%s] min integration time %d\n", __func__, min_integration_time);
1100
1101#ifdef DEBUG_SENSOR_TIME
1102 do_gettimeofday(&end);
1103 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1104#endif
1105
1106p_err:
1107 return ret;
1108}
1109
1110int sensor_2x5sp_cis_get_max_exposure_time(struct v4l2_subdev *subdev, u32 *max_expo)
1111{
1112 int ret = 0;
1113 struct fimc_is_cis *cis;
1114 cis_shared_data *cis_data;
1115 u32 max_integration_time = 0;
1116 u32 max_coarse_margin = 0;
1117 u32 max_fine_margin = 0;
1118 u32 max_coarse = 0;
1119 u32 max_fine = 0;
1120 u32 vt_pic_clk_freq_mhz = 0;
1121 u32 line_length_pck = 0;
1122 u32 frame_length_lines = 0;
7f59bf56 1123 u32 multiple_ratio = 1;
197e9ada
WK
1124
1125#ifdef DEBUG_SENSOR_TIME
1126 struct timeval st, end;
1127
1128 do_gettimeofday(&st);
1129#endif
1130
1131 FIMC_BUG(!subdev);
1132 FIMC_BUG(!max_expo);
1133
1134 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1135
1136 FIMC_BUG(!cis);
1137 FIMC_BUG(!cis->cis_data);
1138
1139 cis_data = cis->cis_data;
1140
1141 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
1142 if (vt_pic_clk_freq_mhz == 0) {
1143 pr_err("[MOD:D:%d] %s, Invalid vt_pic_clk_freq_mhz(%d)\n", cis->id, __func__, vt_pic_clk_freq_mhz);
1144 goto p_err;
1145 }
1146 line_length_pck = cis_data->line_length_pck;
1147 frame_length_lines = cis_data->frame_length_lines;
1148
1149 max_coarse_margin = cis_data->max_margin_coarse_integration_time;
1150 max_fine_margin = line_length_pck - cis_data->min_fine_integration_time;
1151 max_coarse = frame_length_lines - max_coarse_margin;
1152 max_fine = cis_data->max_fine_integration_time;
1153
1154 max_integration_time = ((line_length_pck * max_coarse) + max_fine) / vt_pic_clk_freq_mhz;
1155
1156 *max_expo = max_integration_time;
1157
7f59bf56
DK
1158 /* In 24M remosaic mode, set 4 times of max_coarse_integration_time */
1159 if (cis_data->sens_config_index_cur == SENSOR_2X5SP_5760X4320_24FPS) {
1160 multiple_ratio = 4;
1161 dbg_sensor(1, "[mod:d:%d] %s, Set 4 times of coarse_int for 24M mode\n", cis->id, __func__);
1162 }
1163
197e9ada
WK
1164 /* TODO: Is this values update here? */
1165 cis_data->max_margin_fine_integration_time = max_fine_margin;
7f59bf56 1166 cis_data->max_coarse_integration_time = max_coarse * multiple_ratio;
197e9ada
WK
1167
1168 dbg_sensor(1, "[%s] max integration time %d, max margin fine integration %d, max coarse integration %d\n",
1169 __func__, max_integration_time, cis_data->max_margin_fine_integration_time,
1170 cis_data->max_coarse_integration_time);
1171
1172#ifdef DEBUG_SENSOR_TIME
1173 do_gettimeofday(&end);
1174 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1175#endif
1176
1177p_err:
1178 return ret;
1179}
1180
1181int sensor_2x5sp_cis_adjust_frame_duration(struct v4l2_subdev *subdev,
1182 u32 input_exposure_time,
1183 u32 *target_duration)
1184{
1185 int ret = 0;
1186 struct fimc_is_cis *cis;
1187 cis_shared_data *cis_data;
1188
1189 u32 vt_pic_clk_freq_mhz = 0;
1190 u32 line_length_pck = 0;
1191 u32 frame_length_lines = 0;
1192 u32 frame_duration = 0;
a0ed8db4
WK
1193 u64 numerator;
1194 u8 lte_shifter;
5c7e3798 1195 u32 multiple_ratio = 1;
197e9ada
WK
1196
1197#ifdef DEBUG_SENSOR_TIME
1198 struct timeval st, end;
1199
1200 do_gettimeofday(&st);
1201#endif
1202
1203 FIMC_BUG(!subdev);
1204 FIMC_BUG(!target_duration);
1205
1206 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1207
1208 FIMC_BUG(!cis);
1209 FIMC_BUG(!cis->cis_data);
1210
1211 cis_data = cis->cis_data;
1212
a0ed8db4
WK
1213 lte_shifter = cis->long_term_mode.sen_strm_off_on_enable ?
1214 GET_2X5SP_LTE_SHIFT_CNT(input_exposure_time) : 0;
1215
5c7e3798
WK
1216 /* In 24M remosaic mode, set 4 times of frame_length_lines */
1217 if (cis_data->sens_config_index_cur == SENSOR_2X5SP_5760X4320_24FPS) {
1218 multiple_ratio = 4;
1219 dbg_sensor(1, "[mod:d:%d] %s, Set 4 times of coarse_int for 24M mode\n", cis->id, __func__);
1220 }
1221
197e9ada
WK
1222 vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000);
1223 line_length_pck = cis_data->line_length_pck;
5c7e3798 1224 numerator = (u64)cis_data->pclk * input_exposure_time * multiple_ratio;
a0ed8db4 1225 frame_length_lines = (u16)((numerator / (1000 * 1000))/ line_length_pck / (1 << lte_shifter));
197e9ada
WK
1226 frame_length_lines += cis_data->max_margin_coarse_integration_time;
1227
a0ed8db4
WK
1228 numerator = (u64)frame_length_lines * line_length_pck;
1229 frame_duration = (numerator << lte_shifter) / vt_pic_clk_freq_mhz;
197e9ada
WK
1230
1231 dbg_sensor(1, "[%s](vsync cnt = %d) input exp(%d), adj duration, frame duraion(%d), min_frame_us(%d)\n",
1232 __func__, cis_data->sen_vsync_count, input_exposure_time,
1233 frame_duration, cis_data->min_frame_us_time);
1234 dbg_sensor(1, "[%s](vsync cnt = %d) adj duration, frame duraion(%d), min_frame_us(%d)\n",
1235 __func__, cis_data->sen_vsync_count, frame_duration, cis_data->min_frame_us_time);
1236
1237 *target_duration = MAX(frame_duration, cis_data->min_frame_us_time);
1238
1239#ifdef DEBUG_SENSOR_TIME
1240 do_gettimeofday(&end);
1241 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1242#endif
1243
1244 return ret;
1245}
1246
1247int sensor_2x5sp_cis_set_frame_duration(struct v4l2_subdev *subdev, u32 frame_duration)
1248{
1249 int ret = 0;
1250 int hold = 0;
1251 struct fimc_is_cis *cis;
1252 struct i2c_client *client;
1253 cis_shared_data *cis_data;
1254
197e9ada
WK
1255 u32 line_length_pck = 0;
1256 u16 frame_length_lines = 0;
e3b80891 1257 u64 numerator;
197e9ada 1258 u32 max_coarse_integration_time = 0;
a0ed8db4 1259 u8 lte_shifter;
197e9ada
WK
1260
1261#ifdef DEBUG_SENSOR_TIME
1262 struct timeval st, end;
1263
1264 do_gettimeofday(&st);
1265#endif
1266
1267 FIMC_BUG(!subdev);
1268
1269 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1270
1271 FIMC_BUG(!cis);
1272 FIMC_BUG(!cis->cis_data);
1273
1274 client = cis->client;
1275 if (unlikely(!client)) {
1276 err("client is NULL");
09beb98f 1277 return -EINVAL;
197e9ada
WK
1278 }
1279
1280 cis_data = cis->cis_data;
1281
1282 if (frame_duration < cis_data->min_frame_us_time) {
1283 dbg_sensor(1, "frame duration is less than min(%d)\n", frame_duration);
1284 frame_duration = cis_data->min_frame_us_time;
1285 }
1286
a0ed8db4
WK
1287 lte_shifter = cis->long_term_mode.sen_strm_off_on_enable ?
1288 GET_2X5SP_LTE_SHIFT_CNT(frame_duration) : 0;
1289
c5c9f207 1290 line_length_pck = cis_data->line_length_pck;
5c7e3798 1291 numerator = (u64)cis_data->pclk * frame_duration;
a0ed8db4 1292 frame_length_lines = (u16)((numerator / line_length_pck) / (1000 * 1000) / (1 << lte_shifter));
c5c9f207 1293
e3b80891
WK
1294 dbg_sensor(1, "[MOD:D:%d] %s, vt_pic_clk(%#x) frame_duration = %d us,"
1295 KERN_CONT "(line_length_pck%#x), frame_length_lines(%#x)\n",
1296 cis->id, __func__, cis_data->pclk, frame_duration, line_length_pck, frame_length_lines);
197e9ada 1297
09beb98f
WK
1298 I2C_MUTEX_LOCK(cis->i2c_lock);
1299
197e9ada
WK
1300 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1301 if (hold < 0) {
1302 ret = hold;
1303 goto p_err;
1304 }
1305
1306 ret = fimc_is_sensor_write16(client, 0x0340, frame_length_lines);
1307 if (ret < 0)
1308 goto p_err;
1309
1310 cis_data->cur_frame_us_time = frame_duration;
1311 cis_data->frame_length_lines = frame_length_lines;
1312
1313 max_coarse_integration_time = cis_data->frame_length_lines - cis_data->max_margin_coarse_integration_time;
1314 cis_data->max_coarse_integration_time = max_coarse_integration_time;
1315
1316#ifdef DEBUG_SENSOR_TIME
1317 do_gettimeofday(&end);
1318 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1319#endif
1320
1321p_err:
1322 if (hold > 0) {
1323 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1324 if (hold < 0)
1325 ret = hold;
1326 }
1327
09beb98f
WK
1328 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1329
197e9ada
WK
1330 return ret;
1331}
1332
1333int sensor_2x5sp_cis_set_frame_rate(struct v4l2_subdev *subdev, u32 min_fps)
1334{
1335 int ret = 0;
1336 struct fimc_is_cis *cis;
1337 cis_shared_data *cis_data;
1338
1339 u32 frame_duration = 0;
1340
1341#ifdef DEBUG_SENSOR_TIME
1342 struct timeval st, end;
1343
1344 do_gettimeofday(&st);
1345#endif
1346
1347 FIMC_BUG(!subdev);
1348
1349 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1350
1351 FIMC_BUG(!cis);
1352 FIMC_BUG(!cis->cis_data);
1353
1354 cis_data = cis->cis_data;
1355
1356 if (min_fps > cis_data->max_fps) {
1357 err("[MOD:D:%d] %s, request FPS is too high(%d), set to max(%d)\n",
1358 cis->id, __func__, min_fps, cis_data->max_fps);
1359 min_fps = cis_data->max_fps;
1360 }
1361
1362 if (min_fps == 0) {
1363 err("[MOD:D:%d] %s, request FPS is 0, set to min FPS(1)\n",
1364 cis->id, __func__);
1365 min_fps = 1;
1366 }
1367
1368 frame_duration = (1 * 1000 * 1000) / min_fps;
1369
1370 dbg_sensor(1, "[MOD:D:%d] %s, set FPS(%d), frame duration(%d)\n",
1371 cis->id, __func__, min_fps, frame_duration);
1372
1373 ret = sensor_2x5sp_cis_set_frame_duration(subdev, frame_duration);
1374 if (ret < 0) {
1375 err("[MOD:D:%d] %s, set frame duration is fail(%d)\n",
1376 cis->id, __func__, ret);
1377 goto p_err;
1378 }
1379
1380 cis_data->min_frame_us_time = frame_duration;
1381
1382#ifdef DEBUG_SENSOR_TIME
1383 do_gettimeofday(&end);
1384 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1385#endif
1386
1387p_err:
1388
1389 return ret;
1390}
1391
1392int sensor_2x5sp_cis_adjust_analog_gain(struct v4l2_subdev *subdev, u32 input_again, u32 *target_permile)
1393{
1394 int ret = 0;
1395 struct fimc_is_cis *cis;
1396 cis_shared_data *cis_data;
1397
1398 u32 again_code = 0;
1399 u32 again_permile = 0;
1400
1401#ifdef DEBUG_SENSOR_TIME
1402 struct timeval st, end;
1403
1404 do_gettimeofday(&st);
1405#endif
1406
1407 FIMC_BUG(!subdev);
1408 FIMC_BUG(!target_permile);
1409
1410 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1411
1412 FIMC_BUG(!cis);
1413 FIMC_BUG(!cis->cis_data);
1414
1415 cis_data = cis->cis_data;
1416
1417 again_code = sensor_cis_calc_again_code(input_again);
1418
1419 if (again_code > cis_data->max_analog_gain[0])
1420 again_code = cis_data->max_analog_gain[0];
1421 else if (again_code < cis_data->min_analog_gain[0])
1422 again_code = cis_data->min_analog_gain[0];
1423
1424 again_permile = sensor_cis_calc_again_permile(again_code);
1425
1426 dbg_sensor(1, "[%s] min again(%d), max(%d), input_again(%d), code(%d), permile(%d)\n", __func__,
1427 cis_data->max_analog_gain[0],
1428 cis_data->min_analog_gain[0],
1429 input_again,
1430 again_code,
1431 again_permile);
1432
1433 *target_permile = again_permile;
1434
1435 return ret;
1436}
1437
1438int sensor_2x5sp_cis_set_analog_gain(struct v4l2_subdev *subdev, struct ae_param *again)
1439{
1440 int ret = 0;
1441 int hold = 0;
1442 struct fimc_is_cis *cis;
1443 struct i2c_client *client;
1444
1445 u16 analog_gain = 0;
1446
1447#ifdef DEBUG_SENSOR_TIME
1448 struct timeval st, end;
1449
1450 do_gettimeofday(&st);
1451#endif
1452
1453 FIMC_BUG(!subdev);
1454 FIMC_BUG(!again);
1455
1456 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1457
1458 FIMC_BUG(!cis);
1459
1460 client = cis->client;
1461 if (unlikely(!client)) {
1462 err("client is NULL");
09beb98f 1463 return -EINVAL;
197e9ada
WK
1464 }
1465
1466 analog_gain = (u16)sensor_cis_calc_again_code(again->val);
1467
1468 if (analog_gain < cis->cis_data->min_analog_gain[0])
1469 analog_gain = cis->cis_data->min_analog_gain[0];
1470
1471 if (analog_gain > cis->cis_data->max_analog_gain[0])
1472 analog_gain = cis->cis_data->max_analog_gain[0];
1473
1474 dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_again = %d us, analog_gain(%#x)\n",
a7ba7b0a 1475 cis->id, __func__, cis->cis_data->sen_vsync_count, again->long_val, analog_gain);
197e9ada 1476
09beb98f
WK
1477 I2C_MUTEX_LOCK(cis->i2c_lock);
1478
197e9ada
WK
1479 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1480 if (hold < 0) {
1481 ret = hold;
1482 goto p_err;
1483 }
1484
1485 ret = fimc_is_sensor_write16(client, 0x0204, analog_gain);
1486 if (ret < 0)
1487 goto p_err;
1488
1489#ifdef DEBUG_SENSOR_TIME
1490 do_gettimeofday(&end);
1491 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1492#endif
1493
1494p_err:
1495 if (hold > 0) {
1496 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1497 if (hold < 0)
1498 ret = hold;
1499 }
1500
09beb98f
WK
1501 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1502
197e9ada
WK
1503 return ret;
1504}
1505
1506int sensor_2x5sp_cis_get_analog_gain(struct v4l2_subdev *subdev, u32 *again)
1507{
1508 int ret = 0;
1509 int hold = 0;
1510 struct fimc_is_cis *cis;
1511 struct i2c_client *client;
1512
1513 u16 analog_gain = 0;
1514
1515#ifdef DEBUG_SENSOR_TIME
1516 struct timeval st, end;
1517
1518 do_gettimeofday(&st);
1519#endif
1520
1521 FIMC_BUG(!subdev);
1522 FIMC_BUG(!again);
1523
1524 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1525
1526 FIMC_BUG(!cis);
1527
1528 client = cis->client;
1529 if (unlikely(!client)) {
1530 err("client is NULL");
09beb98f 1531 return -EINVAL;
197e9ada
WK
1532 }
1533
09beb98f
WK
1534 I2C_MUTEX_LOCK(cis->i2c_lock);
1535
197e9ada
WK
1536 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1537 if (hold < 0) {
1538 ret = hold;
1539 goto p_err;
1540 }
1541
1542 ret = fimc_is_sensor_read16(client, 0x0204, &analog_gain);
1543 if (ret < 0)
1544 goto p_err;
1545
1546 *again = sensor_cis_calc_again_permile(analog_gain);
1547
1548 dbg_sensor(1, "[MOD:D:%d] %s, cur_again = %d us, analog_gain(%#x)\n",
1549 cis->id, __func__, *again, analog_gain);
1550
1551#ifdef DEBUG_SENSOR_TIME
1552 do_gettimeofday(&end);
1553 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1554#endif
1555
1556p_err:
1557 if (hold > 0) {
1558 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1559 if (hold < 0)
1560 ret = hold;
1561 }
1562
09beb98f
WK
1563 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1564
197e9ada
WK
1565 return ret;
1566}
1567
1568int sensor_2x5sp_cis_get_min_analog_gain(struct v4l2_subdev *subdev, u32 *min_again)
1569{
1570 int ret = 0;
1571 struct fimc_is_cis *cis;
1572 struct i2c_client *client;
1573 cis_shared_data *cis_data;
1574
197e9ada
WK
1575#ifdef DEBUG_SENSOR_TIME
1576 struct timeval st, end;
1577
1578 do_gettimeofday(&st);
1579#endif
1580
1581 FIMC_BUG(!subdev);
1582 FIMC_BUG(!min_again);
1583
1584 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1585
1586 FIMC_BUG(!cis);
1587 FIMC_BUG(!cis->cis_data);
1588
1589 client = cis->client;
1590 if (unlikely(!client)) {
1591 err("client is NULL");
09beb98f 1592 return -EINVAL;
197e9ada
WK
1593 }
1594
1595 cis_data = cis->cis_data;
79a463ed 1596 cis_data->min_analog_gain[0] = 0x20;
1597 cis_data->min_analog_gain[1] = sensor_cis_calc_again_permile(cis_data->min_analog_gain[0]);
197e9ada
WK
1598
1599 *min_again = cis_data->min_analog_gain[1];
1600
1601 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__, cis_data->min_analog_gain[0], cis_data->min_analog_gain[1]);
1602
1603#ifdef DEBUG_SENSOR_TIME
1604 do_gettimeofday(&end);
1605 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1606#endif
1607
197e9ada
WK
1608 return ret;
1609}
1610
1611int sensor_2x5sp_cis_get_max_analog_gain(struct v4l2_subdev *subdev, u32 *max_again)
1612{
1613 int ret = 0;
1614 struct fimc_is_cis *cis;
1615 struct i2c_client *client;
1616 cis_shared_data *cis_data;
1617
197e9ada
WK
1618#ifdef DEBUG_SENSOR_TIME
1619 struct timeval st, end;
1620
1621 do_gettimeofday(&st);
1622#endif
1623
1624 FIMC_BUG(!subdev);
1625 FIMC_BUG(!max_again);
1626
1627 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1628
1629 FIMC_BUG(!cis);
1630 FIMC_BUG(!cis->cis_data);
1631
1632 client = cis->client;
1633 if (unlikely(!client)) {
1634 err("client is NULL");
09beb98f 1635 return -EINVAL;
197e9ada
WK
1636 }
1637
1638 cis_data = cis->cis_data;
79a463ed 1639 cis_data->max_analog_gain[0] = 0x200;
1640 cis_data->max_analog_gain[1] = sensor_cis_calc_again_permile(cis_data->max_analog_gain[0]);
197e9ada
WK
1641
1642 *max_again = cis_data->max_analog_gain[1];
1643
1644 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__, cis_data->max_analog_gain[0], cis_data->max_analog_gain[1]);
1645
1646#ifdef DEBUG_SENSOR_TIME
1647 do_gettimeofday(&end);
1648 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1649#endif
1650
197e9ada
WK
1651 return ret;
1652}
1653
1654int sensor_2x5sp_cis_set_digital_gain(struct v4l2_subdev *subdev, struct ae_param *dgain)
1655{
1656 int ret = 0;
1657 int hold = 0;
1658 struct fimc_is_cis *cis;
1659 struct i2c_client *client;
1660 cis_shared_data *cis_data;
1661
1662 u16 long_gain = 0;
1663 u16 short_gain = 0;
a7ba7b0a 1664 u16 middle_gain = 0;
197e9ada
WK
1665 u16 dgains[4] = {0};
1666
1667#ifdef DEBUG_SENSOR_TIME
1668 struct timeval st, end;
1669
1670 do_gettimeofday(&st);
1671#endif
1672
1673 FIMC_BUG(!subdev);
1674 FIMC_BUG(!dgain);
1675
1676 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1677
1678 FIMC_BUG(!cis);
1679 FIMC_BUG(!cis->cis_data);
1680
1681 client = cis->client;
1682 if (unlikely(!client)) {
1683 err("client is NULL");
09beb98f 1684 return -EINVAL;
197e9ada
WK
1685 }
1686
1687 cis_data = cis->cis_data;
1688
1689 long_gain = (u16)sensor_cis_calc_dgain_code(dgain->long_val);
1690 short_gain = (u16)sensor_cis_calc_dgain_code(dgain->short_val);
a7ba7b0a 1691 middle_gain = (u16)sensor_cis_calc_dgain_code(dgain->middle_val);
197e9ada
WK
1692
1693 if (long_gain < cis->cis_data->min_digital_gain[0])
1694 long_gain = cis->cis_data->min_digital_gain[0];
1695
1696 if (long_gain > cis->cis_data->max_digital_gain[0])
1697 long_gain = cis->cis_data->max_digital_gain[0];
1698
1699 if (short_gain < cis->cis_data->min_digital_gain[0])
1700 short_gain = cis->cis_data->min_digital_gain[0];
1701
1702 if (short_gain > cis->cis_data->max_digital_gain[0])
1703 short_gain = cis->cis_data->max_digital_gain[0];
1704
a7ba7b0a
WK
1705 if (middle_gain < cis->cis_data->min_digital_gain[0])
1706 middle_gain = cis->cis_data->min_digital_gain[0];
1707
1708 if (middle_gain > cis->cis_data->max_digital_gain[0])
1709 middle_gain = cis->cis_data->max_digital_gain[0];
1710
1711 dbg_sensor(1, "[MOD:D:%d] %s(vsync cnt = %d), input_dgain = %d/%d/%d us, gain(L:%#x, S:%#x, M:%#x)\n",
197e9ada 1712 cis->id, __func__, cis->cis_data->sen_vsync_count, dgain->long_val,
a7ba7b0a 1713 dgain->short_val, dgain->middle_val, long_gain, short_gain, middle_gain);
197e9ada 1714
09beb98f
WK
1715 I2C_MUTEX_LOCK(cis->i2c_lock);
1716
197e9ada
WK
1717 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1718 if (hold < 0) {
1719 ret = hold;
1720 goto p_err;
1721 }
1722
1723 dgains[0] = dgains[1] = dgains[2] = dgains[3] = short_gain;
1724 /* Short digital gain */
1725 ret = fimc_is_sensor_write16_array(client, 0x020E, dgains, 4);
1726 if (ret < 0)
1727 goto p_err;
1728
1729 /* Long & medium digital gain */
a7ba7b0a
WK
1730 if (cis_data->is_data.wdr_mode != CAMERA_WDR_OFF) {
1731 dgains[0] = dgains[1] = dgains[2] = dgains[3] = long_gain;
1732 /* long digital gain */
1733 ret = fimc_is_sensor_write16_array(client, 0x0230, dgains, 4);
1734 if (ret < 0)
1735 goto p_err;
1736 dgains[0] = dgains[1] = dgains[2] = dgains[3] = middle_gain;
1737 /* middle digital gain */
1738 ret = fimc_is_sensor_write16_array(client, 0x0238, dgains, 4);
197e9ada
WK
1739 if (ret < 0)
1740 goto p_err;
197e9ada
WK
1741 }
1742
1743#ifdef DEBUG_SENSOR_TIME
1744 do_gettimeofday(&end);
1745 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1746#endif
1747
1748p_err:
1749 if (hold > 0) {
1750 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1751 if (hold < 0)
1752 ret = hold;
1753 }
1754
09beb98f
WK
1755 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1756
197e9ada
WK
1757 return ret;
1758}
1759
1760int sensor_2x5sp_cis_get_digital_gain(struct v4l2_subdev *subdev, u32 *dgain)
1761{
1762 int ret = 0;
1763 int hold = 0;
1764 struct fimc_is_cis *cis;
1765 struct i2c_client *client;
1766
1767 u16 digital_gain = 0;
1768
1769#ifdef DEBUG_SENSOR_TIME
1770 struct timeval st, end;
1771
1772 do_gettimeofday(&st);
1773#endif
1774
1775 FIMC_BUG(!subdev);
1776 FIMC_BUG(!dgain);
1777
1778 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1779
1780 FIMC_BUG(!cis);
1781
1782 client = cis->client;
1783 if (unlikely(!client)) {
1784 err("client is NULL");
09beb98f 1785 return -EINVAL;
197e9ada
WK
1786 }
1787
09beb98f
WK
1788 I2C_MUTEX_LOCK(cis->i2c_lock);
1789
197e9ada
WK
1790 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1791 if (hold < 0) {
1792 ret = hold;
1793 goto p_err;
1794 }
1795
1796 ret = fimc_is_sensor_read16(client, 0x020E, &digital_gain);
1797 if (ret < 0)
1798 goto p_err;
1799
1800 *dgain = sensor_cis_calc_dgain_permile(digital_gain);
1801
1802 dbg_sensor(1, "[MOD:D:%d] %s, cur_dgain = %d us, digital_gain(%#x)\n",
1803 cis->id, __func__, *dgain, digital_gain);
1804
1805#ifdef DEBUG_SENSOR_TIME
1806 do_gettimeofday(&end);
1807 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1808#endif
1809
1810p_err:
1811 if (hold > 0) {
1812 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1813 if (hold < 0)
1814 ret = hold;
1815 }
1816
09beb98f
WK
1817 I2C_MUTEX_UNLOCK(cis->i2c_lock);
1818
197e9ada
WK
1819 return ret;
1820}
1821
1822int sensor_2x5sp_cis_get_min_digital_gain(struct v4l2_subdev *subdev, u32 *min_dgain)
1823{
1824 int ret = 0;
1825 struct fimc_is_cis *cis;
1826 struct i2c_client *client;
1827 cis_shared_data *cis_data;
1828
197e9ada
WK
1829#ifdef DEBUG_SENSOR_TIME
1830 struct timeval st, end;
1831
1832 do_gettimeofday(&st);
1833#endif
1834
1835 FIMC_BUG(!subdev);
1836 FIMC_BUG(!min_dgain);
1837
1838 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1839
1840 FIMC_BUG(!cis);
1841 FIMC_BUG(!cis->cis_data);
1842
1843 client = cis->client;
1844 if (unlikely(!client)) {
1845 err("client is NULL");
09beb98f 1846 return -EINVAL;
197e9ada
WK
1847 }
1848
1849 cis_data = cis->cis_data;
79a463ed 1850 cis_data->min_digital_gain[0] = 0x100;
1851 cis_data->min_digital_gain[1] = sensor_cis_calc_dgain_permile(cis_data->min_digital_gain[0]);
197e9ada
WK
1852
1853 *min_dgain = cis_data->min_digital_gain[1];
1854
1855 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
1856 cis_data->min_digital_gain[0], cis_data->min_digital_gain[1]);
1857
1858#ifdef DEBUG_SENSOR_TIME
1859 do_gettimeofday(&end);
1860 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1861#endif
1862
197e9ada
WK
1863 return ret;
1864}
1865
1866int sensor_2x5sp_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max_dgain)
1867{
1868 int ret = 0;
1869 struct fimc_is_cis *cis;
1870 struct i2c_client *client;
1871 cis_shared_data *cis_data;
1872
197e9ada
WK
1873#ifdef DEBUG_SENSOR_TIME
1874 struct timeval st, end;
1875
1876 do_gettimeofday(&st);
1877#endif
1878
1879 FIMC_BUG(!subdev);
1880 FIMC_BUG(!max_dgain);
1881
1882 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1883
1884 FIMC_BUG(!cis);
1885 FIMC_BUG(!cis->cis_data);
1886
1887 client = cis->client;
1888 if (unlikely(!client)) {
1889 err("client is NULL");
09beb98f 1890 return -EINVAL;
197e9ada
WK
1891 }
1892
1893 cis_data = cis->cis_data;
79a463ed 1894 cis_data->max_digital_gain[0] = 0x8000;
1895 cis_data->max_digital_gain[1] = sensor_cis_calc_dgain_permile(cis_data->max_digital_gain[0]);
197e9ada
WK
1896
1897 *max_dgain = cis_data->max_digital_gain[1];
1898
1899 dbg_sensor(1, "[%s] code %d, permile %d\n", __func__,
1900 cis_data->max_digital_gain[0], cis_data->max_digital_gain[1]);
1901
1902#ifdef DEBUG_SENSOR_TIME
1903 do_gettimeofday(&end);
1904 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec));
1905#endif
1906
197e9ada
WK
1907 return ret;
1908}
1909
898d3c6c
WK
1910int sensor_2x5sp_cis_set_wb_gain(struct v4l2_subdev *subdev, struct wb_gains wb_gains)
1911{
1912 int ret = 0;
1913 int hold = 0;
1914 struct fimc_is_cis *cis;
1915 struct i2c_client *client;
1916 u16 abs_gains[4] = {0, }; /* [0]=gr, [1]=r, [2]=b, [3]=gb */
1917
1918#ifdef DEBUG_SENSOR_TIME
1919 struct timeval st, end;
1920
1921 do_gettimeofday(&st);
1922#endif
1923
1924 BUG_ON(!subdev);
1925
1926 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
1927
1928 BUG_ON(!cis);
1929 BUG_ON(!cis->cis_data);
1930
1931 if (!cis->use_wb_gain)
1932 return ret;
1933
1934 client = cis->client;
1935 if (unlikely(!client)) {
1936 err("client is NULL");
09beb98f 1937 return -EINVAL;
898d3c6c
WK
1938 }
1939
1940 dbg_sensor(1, "[SEN:%d]%s:DDK vlaue: wb_gain_gr(%d), wb_gain_r(%d), wb_gain_b(%d)\n",
1941 cis->id, __func__, wb_gains.gr, wb_gains.r, wb_gains.b, wb_gains.gb);
1942
1943 if (wb_gains.gr == 0 || wb_gains.r == 0 || wb_gains.b == 0 || wb_gains.gb == 0)
1944 return ret;
1945
1946 abs_gains[0] = (u16)((wb_gains.r / 4) & 0xFFFF);
1947 abs_gains[1] = (u16)((wb_gains.gr / 4) & 0xFFFF);
1948 abs_gains[2] = (u16)((wb_gains.b / 4) & 0xFFFF);
1949
1950 dbg_sensor(1, "[SEN:%d]%s, abs_gain_r(0x%4X), abs_gain_gr(0x%4X), abs_gain_b(0x%4X)\n",
1951 cis->id, __func__, abs_gains[0], abs_gains[1], abs_gains[2]);
1952
1953 I2C_MUTEX_LOCK(cis->i2c_lock);
09beb98f 1954
898d3c6c
WK
1955 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
1956 if (hold < 0) {
1957 ret = hold;
1958 goto p_err;
1959 }
1960
1961 /* 0x40000D12 ~ 0x400000D16: api_rw_color_temperature_absolute_gain_red/green/blue */
1962 ret = fimc_is_sensor_write16(client, 0x6028, 0x4000);
1963 ret |= fimc_is_sensor_write16_array(client, 0x0D12, abs_gains, 3);
1964 if (ret < 0)
1965 goto p_err;
1966
1967#ifdef DEBUG_SENSOR_TIME
1968 do_gettimeofday(&end);
1969 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec));
1970#endif
1971
1972p_err:
1973 if (hold > 0) {
1974 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
1975 if (hold < 0)
1976 ret = hold;
1977 }
09beb98f 1978
898d3c6c 1979 I2C_MUTEX_UNLOCK(cis->i2c_lock);
09beb98f 1980
898d3c6c
WK
1981 return ret;
1982}
1983
a7ba7b0a
WK
1984int sensor_2x5sp_cis_set_3hdr_roi(struct v4l2_subdev *subdev, struct roi_setting_t roi_control)
1985{
1986 int ret = 0;
1987 int hold = 0;
1988 struct fimc_is_cis *cis;
1989 struct i2c_client *client;
1990 u16 roi_val[4];
1991#ifdef DEBUG_SENSOR_TIME
1992 struct timeval st, end;
1993
1994 do_gettimeofday(&st);
1995#endif
1996
1997 BUG_ON(!subdev);
1998
1999 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
2000
2001 BUG_ON(!cis);
2002 BUG_ON(!cis->cis_data);
2003
2004 if (!cis->use_3hdr)
2005 return ret;
2006
2007 client = cis->client;
2008 if (unlikely(!client)) {
2009 err("client is NULL");
09beb98f 2010 return -EINVAL;
a7ba7b0a
WK
2011 }
2012
2013 dbg_sensor(1, "%s: [MOD:%d] roi_control (start_x:%d, start_y:%d, end_x:%d, end_y:%d)\n",
2014 __func__, cis->id,
2015 roi_control.roi_start_x, roi_control.roi_start_y,
2016 roi_control.roi_end_x, roi_control.roi_end_y);
2017
2018 I2C_MUTEX_LOCK(cis->i2c_lock);
09beb98f 2019
a7ba7b0a
WK
2020 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
2021 if (hold < 0) {
2022 ret = hold;
2023 goto p_err;
2024 }
2025
2026 /* 0x2000_XXXX */
2027 ret = fimc_is_sensor_write16(client, 0x6028, 0x2000);
2028 if (ret < 0)
2029 goto p_err;
2030
2031 /* t_isp_rgby_hist_mem_cfg_active_window_percent_14bit */
2032 roi_val[0] = roi_control.roi_start_x; /* 0x20004B26: top_left_x */
2033 roi_val[1] = roi_control.roi_start_y; /* 0x20004B28: top_left_y */
2034 roi_val[2] = roi_control.roi_end_x; /* 0x20004B2A: bot_right_x */
2035 roi_val[3] = roi_control.roi_end_y; /* 0x20004B2C: bot_right_y */
2036
2037 ret = fimc_is_sensor_write16_array(client, 0x4B26, roi_val, 4);
2038 if (ret < 0)
2039 goto p_err;
2040
2041 /* t_isp_rgby_hist_grid_grid & thstat_grid_area */
2042 roi_val[0] = roi_control.roi_end_x - roi_control.roi_start_x; /* 0x20004BEE & 0x20004E44: width */
2043 roi_val[1] = roi_control.roi_end_y - roi_control.roi_start_y; /* 0x20004BF0 & 0x20004E46: height */
2044 roi_val[2] = (roi_control.roi_start_x + roi_control.roi_end_x) / 2; /* center_x */
2045 roi_val[3] = (roi_control.roi_start_y + roi_control.roi_end_y) / 2; /* center_y */
2046
2047 ret = fimc_is_sensor_write16_array(client, 0x4BEE, roi_val, 4);
2048 if (ret < 0)
2049 goto p_err;
2050
2051 ret = fimc_is_sensor_write16_array(client, 0x4E44, roi_val, 2);
2052 if (ret < 0)
2053 goto p_err;
2054
2055 /* restore 0x4000_XXXX */
2056 ret = fimc_is_sensor_write16(client, 0x6028, 0x4000);
2057 if (ret < 0)
2058 goto p_err;
2059
2060#ifdef DEBUG_SENSOR_TIME
2061 do_gettimeofday(&end);
2062 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec));
2063#endif
2064
2065p_err:
2066 if (hold > 0) {
2067 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
2068 if (hold < 0)
2069 ret = hold;
2070 }
09beb98f 2071
a7ba7b0a 2072 I2C_MUTEX_UNLOCK(cis->i2c_lock);
09beb98f 2073
a7ba7b0a
WK
2074 return ret;
2075}
2076
2077int sensor_2x5sp_cis_set_3hdr_stat(struct v4l2_subdev *subdev, bool streaming, void *data)
2078{
2079 int ret = 0;
2080 int hold = 0;
2081 struct fimc_is_cis *cis;
2082 struct i2c_client *client;
2083 u16 weight[3];
2084 u16 low_gate_thr, high_gate_thr;
2085 struct roi_setting_t y_sum_roi;
2086 struct sensor_lsi_3hdr_stat_control_mode_change mode_change_stat;
2087 struct sensor_lsi_3hdr_stat_control_per_frame per_frame_stat;
2088#ifdef DEBUG_SENSOR_TIME
2089 struct timeval st, end;
2090
2091 do_gettimeofday(&st);
2092#endif
2093
2094 FIMC_BUG(!subdev);
2095 FIMC_BUG(!data);
2096
2097 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
2098
2099 BUG_ON(!cis);
2100 BUG_ON(!cis->cis_data);
2101
2102 if (!cis->use_3hdr)
2103 return ret;
2104
2105 client = cis->client;
2106 if (unlikely(!client)) {
2107 err("client is NULL");
09beb98f 2108 return -EINVAL;
a7ba7b0a
WK
2109 }
2110
2111 I2C_MUTEX_LOCK(cis->i2c_lock);
09beb98f 2112
a7ba7b0a
WK
2113 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x01);
2114 if (hold < 0) {
2115 ret = hold;
2116 goto p_err;
2117 }
2118
2119 if (streaming) {
2120 per_frame_stat = *(struct sensor_lsi_3hdr_stat_control_per_frame *)data;
2121
2122 weight[0] = per_frame_stat.r_weight;
2123 weight[1] = per_frame_stat.g_weight;
2124 weight[2] = per_frame_stat.b_weight;
2125 } else {
2126 mode_change_stat = *(struct sensor_lsi_3hdr_stat_control_mode_change *)data;
2127
2128 weight[0] = mode_change_stat.r_weight;
2129 weight[1] = mode_change_stat.g_weight;
2130 weight[2] = mode_change_stat.b_weight;
2131
2132 low_gate_thr = mode_change_stat.low_gate_thr;
2133 high_gate_thr = mode_change_stat.high_gate_thr;
2134
2135 y_sum_roi = mode_change_stat.y_sum_roi;
2136 }
2137
2138 ret = fimc_is_sensor_write16(client, 0x6028, 0x2000);
2139 if (ret < 0)
2140 goto p_err;
2141
2142 /* t_isp_rgby_hist_short_exp_weight */
2143 ret = fimc_is_sensor_write16_array(client, 0x4BBC, weight, 3);
2144 if (ret < 0)
2145 goto p_err;
2146
2147 /* t_isp_rgby_hist_long_exp_weight */
2148 ret = fimc_is_sensor_write16_array(client, 0x4BCA, weight, 3);
2149 if (ret < 0)
2150 goto p_err;
2151
2152 /* t_isp_rgby_hist_medium_exp_weight */
2153 ret = fimc_is_sensor_write16_array(client, 0x4BD8, weight, 3);
2154 if (ret < 0)
2155 goto p_err;
2156
2157 /* t_isp_rgby_hist_mixed_exp_weight */
2158 ret = fimc_is_sensor_write16_array(client, 0x4BE6, weight, 3);
2159 if (ret < 0)
2160 goto p_err;
2161
2162 /* t_isp_drc_thstat_rgb_weights */
2163 ret = fimc_is_sensor_write16_array(client, 0x4E2C, weight, 3);
2164 if (ret < 0)
2165 goto p_err;
2166
2167 if (!streaming) {
2168 /* t_isp_drc_thstat_u_low_tresh_red */
2169 ret = fimc_is_sensor_write16(client, 0x4E1A, low_gate_thr);
2170 if (ret < 0)
2171 goto p_err;
2172 /* t_isp_drc_thstat_u_high_tresh_red */
2173 ret = fimc_is_sensor_write16(client, 0x4E1C, high_gate_thr);
2174 if (ret < 0)
2175 goto p_err;
2176
2177 /* t_isp_drc_thstat_u_low_tresh_green */
2178 ret = fimc_is_sensor_write16(client, 0x4E1E, low_gate_thr);
2179 if (ret < 0)
2180 goto p_err;
2181
2182 /* t_isp_drc_thstat_u_high_tresh_green */
2183 ret = fimc_is_sensor_write16(client, 0x4E20, high_gate_thr);
2184 if (ret < 0)
2185 goto p_err;
2186
2187 /* t_isp_drc_thstat_u_low_tresh_blue */
2188 ret = fimc_is_sensor_write16(client, 0x4E22, low_gate_thr);
2189 if (ret < 0)
2190 goto p_err;
2191
2192 /* t_isp_drc_thstat_u_high_tresh_blue */
2193 ret = fimc_is_sensor_write16(client, 0x4E24, high_gate_thr);
2194 if (ret < 0)
2195 goto p_err;
2196
2197 /* t_isp_y_sum_top_left_x */
2198 ret = fimc_is_sensor_write16(client, 0x4E04, y_sum_roi.roi_start_x);
2199 if (ret < 0)
2200 goto p_err;
2201 ret = fimc_is_sensor_write16(client, 0x4E06, y_sum_roi.roi_start_y);
2202 if (ret < 0)
2203 goto p_err;
ff7a010e
WK
2204 } else {
2205 /* update 3hdr motion stat */
2206 ret = fimc_is_sensor_write16(client, 0x6028, 0x2001);
2207 if (ret < 0)
2208 goto p_err;
2209
2210 ret |= fimc_is_sensor_write16(client, 0x602A, 0x29D8);
2211 ret |= fimc_is_sensor_write16(client, 0x6F12,
2212 (u16)per_frame_stat.motion_indication);
2213
2214 ret |= fimc_is_sensor_write16(client, 0x602A, 0x2A52);
2215 ret |= fimc_is_sensor_write16(client, 0x6F12,
2216 (u16)per_frame_stat.motion_high_end_ty2ty1);
2217 ret |= fimc_is_sensor_write16(client, 0x6F12,
2218 (u16)per_frame_stat.motion_high_end_ty3ty2);
2219 ret |= fimc_is_sensor_write16(client, 0x6F12,
2220 (u16)per_frame_stat.motion_high_start_ty2ty1);
2221 ret |= fimc_is_sensor_write16(client, 0x6F12,
2222 (u16)per_frame_stat.motion_high_start_ty3ty2);
2223 ret |= fimc_is_sensor_write16(client, 0x6F12,
2224 (u16)per_frame_stat.motion_low_end_ty2ty1);
2225 ret |= fimc_is_sensor_write16(client, 0x6F12,
2226 (u16)per_frame_stat.motion_low_end_ty3ty2);
2227 ret |= fimc_is_sensor_write16(client, 0x6F12,
2228 (u16)per_frame_stat.motion_low_start_ty2ty1);
2229 ret |= fimc_is_sensor_write16(client, 0x6F12,
2230 (u16)per_frame_stat.motion_low_start_ty3ty2);
2231
2232 dbg_sensor(2, "[%s] motion idc(%d) high21(e:%d, s:%d), low21(e:%d, s:%d)\n",
2233 __func__,
2234 (u16)per_frame_stat.motion_indication,
2235 (u16)per_frame_stat.motion_high_end_ty2ty1,
2236 (u16)per_frame_stat.motion_high_start_ty2ty1,
2237 (u16)per_frame_stat.motion_low_end_ty2ty1,
2238 (u16)per_frame_stat.motion_low_start_ty2ty1);
2239 dbg_sensor(2, "[%s] motion high32(e:%d, s:%d), low32(e:%d, s:%d)\n",
2240 __func__,
2241 (u16)per_frame_stat.motion_high_end_ty3ty2,
2242 (u16)per_frame_stat.motion_high_start_ty3ty2,
2243 (u16)per_frame_stat.motion_low_end_ty3ty2,
2244 (u16)per_frame_stat.motion_low_start_ty3ty2);
2245
2246 ret |= fimc_is_sensor_write16(client, 0x602A, 0x2A68);
2247 ret |= fimc_is_sensor_write16(client, 0x6F12,
2248 (u16)per_frame_stat.decision_thresh_override);
2249 ret |= fimc_is_sensor_write16(client, 0x6F12,
2250 (u16)per_frame_stat.motion_abs_high_ty3ty2);
2251 ret |= fimc_is_sensor_write16(client, 0x6F12,
2252 (u16)per_frame_stat.motion_abs_low_ty3ty2);
2253 ret |= fimc_is_sensor_write16(client, 0x6F12,
2254 (u16)per_frame_stat.motion_abs_high_ty2ty1);
2255 ret |= fimc_is_sensor_write16(client, 0x6F12,
2256 (u16)per_frame_stat.motion_abs_low_ty2ty1);
2257
2258 dbg_sensor(2, "[%s] motion DTO(%d), abs(h32:%d, l32:%d), abs(h21:%d, l21:%d)\n",
2259 __func__,
2260 (u16)per_frame_stat.decision_thresh_override,
2261 (u16)per_frame_stat.motion_abs_high_ty3ty2,
2262 (u16)per_frame_stat.motion_abs_low_ty3ty2,
2263 (u16)per_frame_stat.motion_abs_high_ty2ty1,
2264 (u16)per_frame_stat.motion_abs_low_ty2ty1);
a7ba7b0a
WK
2265 }
2266
2267 /* restore 0x4000_XXXX */
2268 ret = fimc_is_sensor_write16(client, 0x6028, 0x4000);
2269 if (ret < 0)
2270 goto p_err;
2271
2272#ifdef DEBUG_SENSOR_TIME
2273 do_gettimeofday(&end);
2274 dbg_sensor(1, "[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec));
2275#endif
2276
2277p_err:
2278 if (hold > 0) {
2279 hold = sensor_2x5sp_cis_group_param_hold_func(subdev, 0x00);
2280 if (hold < 0)
2281 ret = hold;
2282 }
09beb98f 2283
a7ba7b0a 2284 I2C_MUTEX_UNLOCK(cis->i2c_lock);
09beb98f 2285
a7ba7b0a
WK
2286 return ret;
2287}
2288
2289void sensor_2x5sp_cis_check_wdr_mode(struct v4l2_subdev *subdev, u32 mode_idx)
2290{
2291 struct fimc_is_cis *cis;
2292
2293 FIMC_BUG_VOID(!subdev);
2294
2295 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
2296
2297 FIMC_BUG_VOID(!cis);
2298 FIMC_BUG_VOID(!cis->cis_data);
2299
2300 /* check wdr mode */
2301 if (mode_idx == SENSOR_2X5SP_2880X2160_30FPS_3DHDR)
2302 cis->cis_data->is_data.wdr_enable = true;
2303 else
2304 cis->cis_data->is_data.wdr_enable = false;
2305
2306 dbg_sensor(1, "[%s] wdr_enable: %d\n", __func__,
2307 cis->cis_data->is_data.wdr_enable);
2308}
2309
a0ed8db4
WK
2310int sensor_2x5sp_cis_long_term_exposure(struct v4l2_subdev *subdev)
2311{
2312 int ret = 0;
2313 struct fimc_is_cis *cis;
2314 struct fimc_is_long_term_expo_mode *lte_mode;
2315 u8 shift_count;
2316
2317 WARN_ON(!subdev);
2318
2319 cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev);
2320 lte_mode = &cis->long_term_mode;
2321
2322 I2C_MUTEX_LOCK(cis->i2c_lock);
2323 /* LTE mode or normal mode set */
2324 if (lte_mode->sen_strm_off_on_enable) {
2325 shift_count = GET_2X5SP_LTE_SHIFT_CNT(lte_mode->expo[0]);
2326 ret |= fimc_is_sensor_write16(cis->client, 0xFCFC, 0x4000);
2327 ret |= fimc_is_sensor_write8(cis->client, 0x0702, shift_count);
2328 ret |= fimc_is_sensor_write8(cis->client, 0x0704, shift_count);
2329 } else {
2330 ret |= fimc_is_sensor_write16(cis->client, 0xFCFC, 0x4000);
2331 ret |= fimc_is_sensor_write8(cis->client, 0x0702, 0);
2332 ret |= fimc_is_sensor_write8(cis->client, 0x0704, 0);
2333 }
2334
2335 I2C_MUTEX_UNLOCK(cis->i2c_lock);
2336
2337 info("%s enable(%d)", __func__, lte_mode->sen_strm_off_on_enable);
2338
2339 if (ret < 0) {
2340 pr_err("ERR[%s]: LTE register setting fail\n", __func__);
2341 return ret;
2342 }
2343
2344 return ret;
2345}
2346
197e9ada
WK
2347static struct fimc_is_cis_ops cis_ops = {
2348 .cis_init = sensor_2x5sp_cis_init,
2349 .cis_log_status = sensor_2x5sp_cis_log_status,
2350 .cis_group_param_hold = sensor_2x5sp_cis_group_param_hold,
2351 .cis_set_global_setting = sensor_2x5sp_cis_set_global_setting,
2352 .cis_mode_change = sensor_2x5sp_cis_mode_change,
2353 .cis_set_size = sensor_2x5sp_cis_set_size,
2354 .cis_stream_on = sensor_2x5sp_cis_stream_on,
2355 .cis_stream_off = sensor_2x5sp_cis_stream_off,
2356 .cis_set_exposure_time = sensor_2x5sp_cis_set_exposure_time,
2357 .cis_get_min_exposure_time = sensor_2x5sp_cis_get_min_exposure_time,
2358 .cis_get_max_exposure_time = sensor_2x5sp_cis_get_max_exposure_time,
2359 .cis_adjust_frame_duration = sensor_2x5sp_cis_adjust_frame_duration,
2360 .cis_set_frame_duration = sensor_2x5sp_cis_set_frame_duration,
2361 .cis_set_frame_rate = sensor_2x5sp_cis_set_frame_rate,
2362 .cis_adjust_analog_gain = sensor_2x5sp_cis_adjust_analog_gain,
2363 .cis_set_analog_gain = sensor_2x5sp_cis_set_analog_gain,
2364 .cis_get_analog_gain = sensor_2x5sp_cis_get_analog_gain,
2365 .cis_get_min_analog_gain = sensor_2x5sp_cis_get_min_analog_gain,
2366 .cis_get_max_analog_gain = sensor_2x5sp_cis_get_max_analog_gain,
2367 .cis_set_digital_gain = sensor_2x5sp_cis_set_digital_gain,
2368 .cis_get_digital_gain = sensor_2x5sp_cis_get_digital_gain,
2369 .cis_get_min_digital_gain = sensor_2x5sp_cis_get_min_digital_gain,
2370 .cis_get_max_digital_gain = sensor_2x5sp_cis_get_max_digital_gain,
2371 .cis_compensate_gain_for_extremely_br = sensor_cis_compensate_gain_for_extremely_br,
2372 .cis_wait_streamoff = sensor_cis_wait_streamoff,
2373 .cis_wait_streamon = sensor_cis_wait_streamon,
2374 .cis_set_initial_exposure = sensor_cis_set_initial_exposure,
2375 .cis_check_rev = sensor_2x5sp_cis_check_rev,
40d7c17a 2376 .cis_factory_test = sensor_cis_factory_test,
898d3c6c 2377 .cis_set_wb_gains = sensor_2x5sp_cis_set_wb_gain,
a7ba7b0a
WK
2378 .cis_set_roi_stat = sensor_2x5sp_cis_set_3hdr_roi,
2379 .cis_set_3hdr_stat = sensor_2x5sp_cis_set_3hdr_stat,
2380 .cis_check_wdr_mode = sensor_2x5sp_cis_check_wdr_mode,
a0ed8db4 2381 .cis_set_long_term_exposure = sensor_2x5sp_cis_long_term_exposure,
5bccf2ff 2382 .cis_mode_change_throttling = sensor_2x5sp_cis_mode_change_throttling,
197e9ada
WK
2383};
2384
2385static int cis_2x5sp_probe(struct i2c_client *client,
2386 const struct i2c_device_id *id)
2387{
329f08ab 2388 int ret = 0, i;
197e9ada
WK
2389 struct fimc_is_core *core = NULL;
2390 struct v4l2_subdev *subdev_cis = NULL;
2391 struct fimc_is_cis *cis = NULL;
2392 struct fimc_is_device_sensor *device = NULL;
2393 struct fimc_is_device_sensor_peri *sensor_peri = NULL;
2394 u32 sensor_id = 0;
2395 char const *setfile;
2396 struct device *dev;
2397 struct device_node *dnode;
2398
2399 FIMC_BUG(!client);
2400 FIMC_BUG(!fimc_is_dev);
2401
2402 core = (struct fimc_is_core *)dev_get_drvdata(fimc_is_dev);
2403 if (!core) {
2404 probe_info("core device is not yet probed");
2405 return -EPROBE_DEFER;
2406 }
2407
2408 dev = &client->dev;
2409 dnode = dev->of_node;
2410
2411 ret = of_property_read_u32(dnode, "id", &sensor_id);
2412 if (ret) {
2413 err("sensor id read is fail(%d)", ret);
2414 goto p_err;
2415 }
2416
2417 probe_info("%s sensor id %d\n", __func__, sensor_id);
2418
2419 device = &core->sensor[sensor_id];
2420
2421 sensor_peri = find_peri_by_cis_id(device, SENSOR_NAME_S5K2X5SP);
2422 if (!sensor_peri) {
2423 probe_info("sensor peri is net yet probed");
2424 return -EPROBE_DEFER;
2425 }
2426
2427 cis = &sensor_peri->cis;
2428 if (!cis) {
2429 err("cis is NULL");
2430 ret = -ENOMEM;
2431 goto p_err;
2432 }
2433
2434 subdev_cis = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
2435 if (!subdev_cis) {
2436 probe_err("subdev_cis NULL");
2437 ret = -ENOMEM;
2438 goto p_err;
2439 }
2440 sensor_peri->subdev_cis = subdev_cis;
2441
2442 cis->id = SENSOR_NAME_S5K2X5SP;
2443 cis->subdev = subdev_cis;
2444 cis->device = 0;
2445 cis->client = client;
2446 sensor_peri->module->client = cis->client;
2447 cis->ctrl_delay = N_PLUS_TWO_FRAME;
2448
2449 cis->cis_data = kzalloc(sizeof(cis_shared_data), GFP_KERNEL);
2450 if (!cis->cis_data) {
2451 err("cis_data is NULL");
2452 ret = -ENOMEM;
2453 goto p_err;
2454 }
2455 cis->cis_ops = &cis_ops;
2456
2457 /* belows are depend on sensor cis. MUST check sensor spec */
2458 cis->bayer_order = OTF_INPUT_ORDER_BAYER_GR_BG;
2459
2460 if (of_property_read_bool(dnode, "sensor_f_number")) {
2461 ret = of_property_read_u32(dnode, "sensor_f_number", &cis->aperture_num);
2462 if (ret)
2463 warn("f-number read is fail(%d)", ret);
2464 } else {
2465 cis->aperture_num = F2_2;
2466 }
2467
2468 probe_info("%s f-number %d\n", __func__, cis->aperture_num);
2469
2470 cis->use_dgain = true;
2471 cis->hdr_ctrl_by_again = false;
898d3c6c 2472 cis->use_wb_gain = true;
a7ba7b0a 2473 cis->use_3hdr = true;
197e9ada
WK
2474
2475 ret = of_property_read_string(dnode, "setfile", &setfile);
2476 if (ret) {
2477 err("setfile index read fail(%d), take default setfile!!", ret);
2478 setfile = "default";
2479 }
2480
2481 if (strcmp(setfile, "default") == 0 ||
2482 strcmp(setfile, "setA") == 0) {
2483 probe_info("%s setfile_A\n", __func__);
2484 sensor_2x5sp_global = sensor_2x5sp_setfile_A_Global;
2485 sensor_2x5sp_global_size = ARRAY_SIZE(sensor_2x5sp_setfile_A_Global);
2486 sensor_2x5sp_setfiles = sensor_2x5sp_setfiles_A;
2487 sensor_2x5sp_setfile_sizes = sensor_2x5sp_setfile_A_sizes;
329f08ab 2488 sensor_2x5sp_otp_initial = sensor_2x5sp_setfiles_A_otp_initial;
2489 sensor_2x5sp_otp_initial_size = ARRAY_SIZE(sensor_2x5sp_setfiles_A_otp_initial);
197e9ada
WK
2490 sensor_2x5sp_pllinfos = sensor_2x5sp_pllinfos_A;
2491 sensor_2x5sp_max_setfile_num = ARRAY_SIZE(sensor_2x5sp_setfiles_A);
3be33d59
WK
2492 } else if (strcmp(setfile, "setB") == 0) {
2493 probe_info("%s setfile_B\n", __func__);
2494 sensor_2x5sp_global = sensor_2x5sp_setfile_B_Global;
2495 sensor_2x5sp_global_size = ARRAY_SIZE(sensor_2x5sp_setfile_B_Global);
2496 sensor_2x5sp_setfiles = sensor_2x5sp_setfiles_B;
2497 sensor_2x5sp_setfile_sizes = sensor_2x5sp_setfile_B_sizes;
329f08ab 2498 sensor_2x5sp_otp_initial = sensor_2x5sp_setfiles_A_otp_initial;
2499 sensor_2x5sp_otp_initial_size = ARRAY_SIZE(sensor_2x5sp_setfiles_A_otp_initial);
3be33d59
WK
2500 sensor_2x5sp_pllinfos = sensor_2x5sp_pllinfos_B;
2501 sensor_2x5sp_max_setfile_num = ARRAY_SIZE(sensor_2x5sp_setfiles_B);
5bccf2ff
WK
2502
2503 /* throttling setting */
2504 sensor_2x5sp_setfile_throttling = sensor_2x5sp_setfile_B_2880x2160_15fps;
2505 sensor_2x5sp_pllinfo_throttling = &sensor_2x5sp_pllinfo_B_2880x2160_15fps;
197e9ada
WK
2506 } else {
2507 err("%s setfile index out of bound, take default (setfile_A)", __func__);
2508 sensor_2x5sp_global = sensor_2x5sp_setfile_A_Global;
2509 sensor_2x5sp_global_size = ARRAY_SIZE(sensor_2x5sp_setfile_A_Global);
2510 sensor_2x5sp_setfiles = sensor_2x5sp_setfiles_A;
2511 sensor_2x5sp_setfile_sizes = sensor_2x5sp_setfile_A_sizes;
2512 sensor_2x5sp_pllinfos = sensor_2x5sp_pllinfos_A;
2513 sensor_2x5sp_max_setfile_num = ARRAY_SIZE(sensor_2x5sp_setfiles_A);
2514 }
2515
2516 cis->use_initial_ae = of_property_read_bool(dnode, "use_initial_ae");
2517 probe_info("%s use initial_ae(%d)\n", __func__, cis->use_initial_ae);
2518
329f08ab 2519 device->use_otp_cal = of_property_read_bool(dnode, "use_otp_cal");
2520 probe_info("%s use otp_cal(%d)\n", __func__, device->use_otp_cal);
2521
2522 for (i = 0; i < CAMERA_CRC_INDEX_MAX; i++)
2523 device->cal_status[i] = CRC_NO_ERROR;
2524
197e9ada
WK
2525 v4l2_i2c_subdev_init(subdev_cis, client, &subdev_ops);
2526 v4l2_set_subdevdata(subdev_cis, cis);
2527 v4l2_set_subdev_hostdata(subdev_cis, device);
2528 snprintf(subdev_cis->name, V4L2_SUBDEV_NAME_SIZE, "cis-subdev.%d", cis->id);
2529
2530 probe_info("%s done\n", __func__);
2531
2532p_err:
2533 return ret;
2534}
2535
2536static const struct of_device_id sensor_cis_2x5sp_match[] = {
2537 {
2538 .compatible = "samsung,exynos5-fimc-is-cis-2x5sp",
2539 },
2540 {},
2541};
2542MODULE_DEVICE_TABLE(of, sensor_cis_2x5sp_match);
2543
2544static const struct i2c_device_id sensor_cis_2x5sp_idt[] = {
2545 { SENSOR_NAME, 0 },
2546 {},
2547};
2548
2549static struct i2c_driver sensor_cis_2x5sp_driver = {
2550 .probe = cis_2x5sp_probe,
2551 .driver = {
2552 .name = SENSOR_NAME,
2553 .owner = THIS_MODULE,
2554 .of_match_table = sensor_cis_2x5sp_match,
2555 .suppress_bind_attrs = true,
2556 },
2557 .id_table = sensor_cis_2x5sp_idt
2558};
2559
2560static int __init sensor_cis_2x5sp_init(void)
2561{
2562 int ret;
2563
2564 ret = i2c_add_driver(&sensor_cis_2x5sp_driver);
2565 if (ret)
2566 err("failed to add %s driver: %d\n",
2567 sensor_cis_2x5sp_driver.driver.name, ret);
2568
2569 return ret;
2570}
2571late_initcall_sync(sensor_cis_2x5sp_init);