summaryrefslogtreecommitdiff
path: root/drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
committerYuval Adam <_@yuv.al>2017-08-30 08:25:59 +0000
commit8e4bff4cab0ddac6060645b0715210484d02ff40 (patch)
tree3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c
Initial file dump from open source releaseHEADmaster
Diffstat (limited to 'drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c')
-rw-r--r--drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c537
1 files changed, 537 insertions, 0 deletions
diff --git a/drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c b/drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c
new file mode 100644
index 00000000..b0c4bd74
--- /dev/null
+++ b/drivers/media/sprd_isp/isp2.0/tshark2/src/isp_k_2d_lsc.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2012 Spreadtrum Communications Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/sprd_mm.h>
+#include <video/sprd_isp.h>
+#include <asm/cacheflush.h>
+#include <linux/delay.h>
+#include "isp_reg.h"
+#include "isp_drv.h"
+
+
+#define ISP_LSC_TIME_OUT_MAX 5
+#define ISP_LSC_BUF0 0
+#define ISP_LSC_BUF1 1
+
+#if 0
+#define CLIP(input,top, bottom) {if (input>top) input = top; if (input < bottom) input = bottom;}
+#define TABLE_LEN_128 128
+#define TABLE_LEN_96 96
+
+typedef struct lnc_bicubic_weight_t_64_tag
+{
+ int16_t w0;
+ int16_t w1;
+ int16_t w2;
+ int16_t w3;
+}LNC_BICUBIC_WEIGHT_TABLE_T;
+////////10bit precision//////////////////////////////////////
+static LNC_BICUBIC_WEIGHT_TABLE_T lnc_bicubic_weight_t_96_simple[] =
+{
+ {0, 1024, 0},
+ {-5,1024, 6},
+ {-10,1023, 12},
+ {-15,1022, 18},
+ {-20,1020, 25},
+ {-24,1017, 32},
+ {-28,1014, 40},
+ {-32,1011, 48},
+ {-36,1007, 56},
+ {-39,1003, 65},
+ {-43,998, 74},
+ {-46,993, 83},
+ {-49,987, 93},
+ {-52,981, 103},
+ {-54,974, 113},
+ {-57,967, 124},
+ {-59,960, 135},
+ {-61,952, 146},
+ {-63,944, 158},
+ {-65,936, 170},
+ {-67,927, 182},
+ {-68,918, 194},
+ {-70,908, 206},
+ {-71,898, 219},
+ {-72,888, 232},
+ {-73,878, 245},
+ {-74,867, 258},
+ {-74,856, 272},
+ {-75,844, 285},
+ {-75,833, 299},
+ {-76,821, 313},
+ {-76,809, 327},
+ {-76,796, 341},
+ {-76,784, 356},
+ {-76,771, 370},
+ {-75,758, 384},
+ {-75,745, 399},
+ {-75,732, 414},
+ {-74,718, 428},
+ {-73,704, 443},
+ {-73,691, 458},
+ {-72,677, 473},
+ {-71,663, 487},
+ {-70,648, 502},
+ {-69,634, 517},
+ {-68,620, 532},
+ {-67,605, 547},
+ {-65,591, 561},
+ {-64,576, 576},
+};
+
+static LNC_BICUBIC_WEIGHT_TABLE_T lnc_bicubic_weight_t_128_simple[] =
+{
+ {0, 1024, 0},
+ {-4, 1024, 4},
+ {-8, 1023, 8},
+ {-11, 1023, 13},
+ {-15, 1022, 18},
+ {-18, 1020, 23},
+ {-22, 1019, 28},
+ {-25, 1017, 34},
+ {-28, 1014, 40},
+ {-31, 1012, 46},
+ {-34, 1009, 52},
+ {-37, 1006, 58},
+ {-39, 1003, 65},
+ {-42, 999, 72},
+ {-44, 995, 78},
+ {-47, 991, 86},
+ {-49, 987, 93},
+ {-51, 982, 101},
+ {-53, 978, 108},
+ {-55, 973, 116},
+ {-57, 967, 124},
+ {-59, 962, 132},
+ {-60, 956, 141},
+ {-62, 950, 149},
+ {-63, 944, 158},
+ {-65, 938, 167},
+ {-66, 931, 176},
+ {-67, 925, 185},
+ {-68, 918, 194},
+ {-69, 910, 203},
+ {-70, 903, 213},
+ {-71, 896, 222},
+ {-72, 888, 232},
+ {-73, 880, 242},
+ {-73, 872, 252},
+ {-74, 864, 262},
+ {-74, 856, 272},
+ {-75, 847, 282},
+ {-75, 839, 292},
+ {-75, 830, 303},
+ {-76, 821, 313},
+ {-76, 812, 324},
+ {-76, 803, 334},
+ {-76, 793, 345},
+ {-76, 784, 356},
+ {-76, 774, 366},
+ {-76, 765, 377},
+ {-75, 755, 388},
+ {-75, 745, 399},
+ {-75, 735, 410},
+ {-74, 725, 421},
+ {-74, 715, 432},
+ {-73, 704, 443},
+ {-73, 694, 454},
+ {-72, 684, 465},
+ {-72, 673, 476},
+ {-71, 663, 487},
+ {-70, 652, 498},
+ {-69, 641, 510},
+ {-69, 631, 521},
+ {-68, 620, 532},
+ {-67, 609, 543},
+ {-66, 598, 554},
+ {-65, 587, 565},
+ {-64, 576, 576},
+};
+
+static uint16_t ISP_Cubic1D(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t u, uint16_t box)
+{
+ int32_t out_value;
+ uint16_t out_value_uint16_t;
+ int16_t w0, w1, w2, w3;
+ uint32_t out_value_tmp;
+ int16_t sub_tmp0;
+ int16_t sub_tmp1;
+ int16_t sub_tmp2;
+
+ if(box ==96)
+ {
+ //use simple table
+ if ( u < (TABLE_LEN_96/2 + 1) )
+ {
+ w0 = lnc_bicubic_weight_t_96_simple[u].w0 ;
+ w1 = lnc_bicubic_weight_t_96_simple[u].w1 ;
+ w2 = lnc_bicubic_weight_t_96_simple[u].w2 ;
+
+ sub_tmp0 = a-d;
+ sub_tmp1 = b-d;
+ sub_tmp2 = c-d;
+ out_value_tmp = ((uint32_t)d)<<10;
+ out_value = out_value_tmp + sub_tmp0 * w0 + sub_tmp1 * w1 + sub_tmp2 * w2;
+ }
+ else
+ {
+ w1 = lnc_bicubic_weight_t_96_simple[TABLE_LEN_96 - u].w2 ;
+ w2 = lnc_bicubic_weight_t_96_simple[TABLE_LEN_96 - u].w1 ;
+ w3 = lnc_bicubic_weight_t_96_simple[TABLE_LEN_96 - u].w0 ;
+
+ sub_tmp0 = b-a;
+ sub_tmp1 = c-a;
+ sub_tmp2 = d-a;
+ out_value_tmp = ((uint32_t)a)<<10;
+ out_value = out_value_tmp + sub_tmp0 * w1 + sub_tmp1 * w2 + sub_tmp2 * w3;
+ }
+
+ }
+ else
+ {
+ u = u * (TABLE_LEN_128 / box);
+
+ //use simple table
+ if ( u < (TABLE_LEN_128/2 + 1) )
+ {
+ w0 = lnc_bicubic_weight_t_128_simple[u].w0 ;
+ w1 = lnc_bicubic_weight_t_128_simple[u].w1 ;
+ w2 = lnc_bicubic_weight_t_128_simple[u].w2 ;
+
+ sub_tmp0 = a-d;
+ sub_tmp1 = b-d;
+ sub_tmp2 = c-d;
+ out_value_tmp = ((uint32_t)d)<<10;
+ out_value = out_value_tmp + sub_tmp0 * w0 + sub_tmp1 * w1 + sub_tmp2 * w2;
+ }
+ else
+ {
+ w1 = lnc_bicubic_weight_t_128_simple[TABLE_LEN_128 - u].w2 ;
+ w2 = lnc_bicubic_weight_t_128_simple[TABLE_LEN_128 - u].w1 ;
+ w3 = lnc_bicubic_weight_t_128_simple[TABLE_LEN_128 - u].w0 ;
+
+ sub_tmp0 = b-a;
+ sub_tmp1 = c-a;
+ sub_tmp2 = d-a;
+ out_value_tmp = ((uint32_t)a)<<10;
+ out_value = out_value_tmp + sub_tmp0 * w1 + sub_tmp1 * w2 + sub_tmp2 * w3;
+ }
+ }
+
+ //CLIP(out_value, 4095*1024*2, 1024*1024); // for LSC gain, 1024 = 1.0, 4095 = 4.0 ; 4095*2 is for boundary extension.
+ CLIP(out_value, 16383*1024, 1024*1024); // for LSC gain, 1024 = 1.0, 16383 = 16.0 ; 16383 is for boundary extension, 14 bit parameter is used.
+
+ out_value_uint16_t = (uint16_t)((out_value + 512) >> 10);
+
+ return out_value_uint16_t;
+}
+
+
+static int32_t ISP_GenerateQValues(uint32_t word_endian, uint32_t q_val[][5], unsigned long param_address, uint16_t grid_w, uint16_t grid_num, uint16_t u)
+{
+ uint8_t i;
+ uint16_t A0, B0, C0, D0;
+ uint16_t A1, B1, C1, D1;
+ uint32_t *addr = (uint32_t *)param_address;
+
+ if (param_address == 0x0 || grid_num == 0x0) {
+ printk("ISP_GenerateQValues param_address error addr=0x%lx grid_num=%d \n",param_address, grid_num);
+ return -1;
+ }
+
+ //printk("ISP_GenerateQValues:addr=%x grid_w=%d grid_num=%d u=%d \n",param_address,grid_w,grid_num,u);
+ #if 0
+ for (i = 0; i < 5; i++) {
+ A0 = (uint16_t)*(addr + i * 2) & 0xFFFF;
+ B0 = (uint16_t)*(addr + i * 2 + grid_w * 2) & 0xFFFF;
+ C0 = (uint16_t)*(addr + i * 2 + grid_w * 2 * 2) & 0xFFFF;
+ D0 = (uint16_t)*(addr + i * 2 + grid_w * 2 * 3) & 0xFFFF;
+ A1 = (uint16_t)(*(addr + i * 2) >> 16);
+ B1 = (uint16_t)(*(addr + i * 2 + grid_w * 2) >> 16);
+ C1 = (uint16_t)(*(addr + i * 2 + grid_w * 2 * 2) >> 16);
+ D1 = (uint16_t)(*(addr + i * 2 + grid_w * 2 * 3) >> 16);
+ q_val[0][i] = ISP_Cubic1D(A0, B0, C0, D0, u, grid_num);
+ q_val[1][i] = ISP_Cubic1D(A1, B1, C1, D1, u, grid_num);
+ }
+ #endif
+ #if 1
+ for (i = 0; i < 5; i++) {
+ if (1 == word_endian) { // ABCD = 1 word
+ A0 = *(addr + i * 2) >> 16; // AB
+ B0 = *(addr + i * 2 + grid_w * 2) >> 16; // AB
+ C0 = *(addr + i * 2 + grid_w * 2 * 2) >> 16; // AB
+ D0 = *(addr + i * 2 + grid_w * 2 * 3) >> 16; // AB
+ A1 = *(addr + i * 2) & 0xFFFF; // CD
+ B1 = *(addr + i * 2 + grid_w * 2) & 0xFFFF; // CD
+ C1 = *(addr + i * 2 + grid_w * 2 * 2) & 0xFFFF;// CD
+ D1 = *(addr + i * 2 + grid_w * 2 * 3) & 0xFFFF;// CD
+ } else if (2 == word_endian) { // CDAB = 1 word
+ A0 = *(addr + i * 2) & 0xFFFF;
+ B0 = *(addr + i * 2 + grid_w * 2) & 0xFFFF;
+ C0 = *(addr + i * 2 + grid_w * 2 * 2) & 0xFFFF;
+ D0 = *(addr + i * 2 + grid_w * 2 * 3) & 0xFFFF;
+ A1 = *(addr + i * 2) >> 16;
+ B1 = *(addr + i * 2 + grid_w * 2) >> 16;
+ C1 = *(addr + i * 2 + grid_w * 2 * 2) >> 16;
+ D1 = *(addr + i * 2 + grid_w * 2 * 3) >> 16;
+ } else if (0 == word_endian) { // DCBA = 1 word
+ A0 = ((*(addr + i * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2) >> 8) & 0x000000FF);
+ B0 = ((*(addr + i * 2 + grid_w * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2) >> 8) & 0x000000FF);
+ C0 = ((*(addr + i * 2 + grid_w * 2 * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2 * 2) >> 8) & 0x000000FF);
+ D0 = ((*(addr + i * 2 + grid_w * 2 * 3) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2 * 3) >> 8) & 0x000000FF);
+ A1 = ((*(addr + i * 2) << 8) & 0xFF000000) | ((*(addr + i * 2) >> 8) & 0x00FF0000);
+ B1 = ((*(addr + i * 2 + grid_w * 2) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2) >> 8) & 0x00FF0000);
+ C1 = ((*(addr + i * 2 + grid_w * 2 * 2) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2 * 2) >> 8) & 0x00FF0000);
+ D1 = ((*(addr + i * 2 + grid_w * 2 * 3) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2 * 3) >> 8) & 0x00FF0000);
+ } else if (3 == word_endian) { // BADC = 1 word
+ A0 = ((*(addr + i * 2) << 8) & 0xFF000000) | ((*(addr + i * 2) >> 8) & 0x00FF0000);
+ B0 = ((*(addr + i * 2 + grid_w * 2) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2) >> 8) & 0x00FF0000);
+ C0 = ((*(addr + i * 2 + grid_w * 2 * 2) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2 * 2) >> 8) & 0x00FF0000);
+ D0 = ((*(addr + i * 2 + grid_w * 2 * 3) << 8) & 0xFF000000) | ((*(addr + i * 2 + grid_w * 2 * 3) >> 8) & 0x00FF0000);
+ A1 = ((*(addr + i * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2) >> 8) & 0x000000FF);
+ B1 = ((*(addr + i * 2 + grid_w * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2) >> 8) & 0x000000FF);
+ C1 = ((*(addr + i * 2 + grid_w * 2 * 2) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2 * 2) >> 8) & 0x000000FF);
+ D1 = ((*(addr + i * 2 + grid_w * 2 * 3) << 8) & 0x0000FF00) | ((*(addr + i * 2 + grid_w * 2 * 3) >> 8) & 0x000000FF);
+ }
+ //printk("ISP_GenerateQValues: A0=%x B0=%x C0=%x D0=%x A1=%x B1=%x C1=%x D1=%x \n",A0,B0,C0,D0,A1,B1,C1,D1);
+ q_val[0][i] = ISP_Cubic1D(A0, B0, C0, D0, u, grid_num);
+ q_val[1][i] = ISP_Cubic1D(A1, B1, C1, D1, u, grid_num);
+ //printk("ISP_GenerateQValues: q_val[0][%d] = %d q_val[1][%d] = %d \n",i,q_val[0][i],i ,q_val[1][i] );
+ }
+ #endif
+
+ return 0;
+}
+#endif
+
+static int32_t isp_k_2d_lsc_param_load(struct isp_k_private *isp_private)
+{
+ int32_t ret = 0;
+ uint32_t time_out_cnt = 0;
+ uint32_t addr = 0, reg_value = 0;
+
+ if (ISP_LSC_BUF0 == isp_private->lsc_load_buf_id) {
+ isp_private->lsc_load_buf_id = ISP_LSC_BUF1;
+ } else {
+ isp_private->lsc_load_buf_id = ISP_LSC_BUF0;
+ }
+ REG_MWR(ISP_LENS_LOAD_BUF, BIT_0, isp_private->lsc_load_buf_id);
+ REG_WR(ISP_LENS_PARAM_ADDR, isp_private->lsc_buf_phys_addr);
+ REG_OWR(ISP_LENS_LOAD_EB, BIT_0);
+ REG_MWR(ISP_LENS_PARAM, BIT_1, isp_private->lsc_load_buf_id << 1);
+ isp_private->lsc_update_buf_id = isp_private->lsc_load_buf_id;
+
+ reg_value = REG_RD(ISP_INT_RAW0);
+
+ while ((0x00 == (reg_value & ISP_INT_EVT_LSC_LOAD))
+ && (time_out_cnt < ISP_LSC_TIME_OUT_MAX)) {
+ msleep(1);
+ reg_value = REG_RD(ISP_INT_RAW0);
+ time_out_cnt++;
+ }
+ if (time_out_cnt >= ISP_LSC_TIME_OUT_MAX) {
+ ret = -1;
+ printk("isp_k_2d_lsc_param_load: lsc load time out error.\n");
+ }
+ REG_OWR(ISP_INT_CLR0, ISP_INT_EVT_LSC_LOAD);
+
+ return ret;
+}
+
+static int32_t isp_k_2d_lsc_block(struct isp_io_param *param,
+ struct isp_k_private *isp_private)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ uint32_t i = 0;
+ //uint32_t qvalue_addr = ISP_LEN_BUF0_CH0;
+ struct isp_dev_2d_lsc_info lens_info;
+
+ memset(&lens_info, 0x00, sizeof(lens_info));
+
+ ret = copy_from_user((void *)&lens_info, param->property_param, sizeof(lens_info));
+ if (0 != ret) {
+ printk("isp_k_2d_lsc_block: copy error, ret=0x%x\n", (uint32_t)ret);
+ return -1;
+ }
+
+ val = ((lens_info.offset_y & 0xFFFF) << 16) | (lens_info.offset_x & 0xFFFF);
+ REG_WR(ISP_LENS_SLICE_POS, val);
+
+ val = lens_info.grid_pitch & 0x1FF;
+ REG_MWR(ISP_LENS_GRID_PITCH, 0x1FF, val);
+
+ val = (lens_info.grid_width & 0xFF) << 16;
+ REG_MWR(ISP_LENS_GRID_PITCH, 0xFF0000, val);
+
+ val = ((lens_info.grid_num_t & 0xFFFF) << 16) | ((lens_info.grid_y_num & 0xFF) << 8) | (lens_info.grid_x_num & 0xFF);
+ REG_WR(ISP_LENS_GRID_SIZE, val);
+
+ REG_MWR(ISP_LENS_LOAD_BUF, BIT_1, lens_info.load_chn_sel << 1);
+
+ REG_MWR(ISP_LENS_MISC, (BIT_1 | BIT_0), (lens_info.endian & 0x03));
+
+ val = ((lens_info.slice_size.height & 0xFFFF) << 16) | (lens_info.slice_size.width & 0xFFFF);
+ REG_WR(ISP_LENS_SLICE_SIZE, val);
+
+ val = ((lens_info.relative_y & 0xFF) << 8) | (lens_info.relative_x & 0xFF);
+ REG_WR(ISP_LENS_INIT_COOR, val);
+
+ /*ret = isp_k_2d_lsc_param_load(&src_buf, isp_private, &qvalue_addr);
+ REG_WR(ISP_LENS_PARAM_ADDR, qvalue_addr);
+ printk("isp_k_2d_lsc_block:qvalue_addr=%x grid_x_num=%d grid_width=%d relative_y=%d \n",qvalue_addr,(lens_info.grid_x_num & 0xFF),(lens_info.grid_width & 0xFF), (lens_info.relative_y & 0xFF)>>1);
+
+ ISP_GenerateQValues(1, lens_info.q_value, qvalue_addr, ((uint16_t)lens_info.grid_x_num & 0xFF) + 2,(lens_info.grid_width & 0xFF), (lens_info.relative_y & 0xFF)>>1);
+ */
+
+ ret = isp_k_2d_lsc_param_load(isp_private);
+ if (0 != ret) {
+ printk("isp_k_2d_lsc_block: lsc load para error, ret=0x%x\n", (uint32_t)ret);
+ REG_MWR(ISP_LENS_PARAM, BIT_0, ISP_BYPASS_EB);
+ return -1;
+ }
+
+ for (i = 0; i < 5; i++) {
+ val = ((lens_info.q_value[0][i] & 0x3FFF) << 16) | (lens_info.q_value[1][i] & 0x3FFF);
+ REG_WR(ISP_LENS_Q0_VALUE + i * 4, val);
+ }
+
+ REG_MWR(ISP_LENS_PARAM, BIT_0, lens_info.bypass);
+
+ return ret;
+
+}
+
+static int32_t isp_k_2d_lsc_param_update(struct isp_io_param *param,
+ struct isp_k_private *isp_private)
+{
+ int32_t ret = 0;
+
+ REG_MWR(ISP_LENS_PARAM, BIT_1, isp_private->lsc_update_buf_id << 1);
+
+ return ret;
+}
+
+static int32_t isp_k_2d_lsc_pos(struct isp_io_param *param)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ struct isp_img_offset offset = {0, 0};
+
+ ret = copy_from_user((void *)&offset, param->property_param, sizeof(offset));
+ if (0 != ret) {
+ printk("isp_k_lens_pos: copy error, ret=0x%x\n", (uint32_t)ret);
+ return -1;
+ }
+
+ val = ((offset.y & 0xFFFF) << 16) | (offset.x & 0xFFFF);
+
+ REG_WR(ISP_LENS_SLICE_POS, val);
+
+ return ret;
+}
+
+static int32_t isp_k_2d_lsc_grid_size(struct isp_io_param *param)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ uint32_t grid_total = 0;
+ struct isp_img_size size = {0, 0};
+
+ ret = copy_from_user((void *)&size, param->property_param, sizeof(size));
+ if (0 != ret) {
+ printk("isp_k_2d_lsc_grid_size: copy error, ret=0x%x\n", (uint32_t)ret);
+ return -1;
+ }
+
+ grid_total = (size.height + 2) * (size.width + 2);
+ val = ((grid_total & 0xFFFF) << 16) | ((size.height & 0xFF) << 8) | (size.width & 0xFF);
+ REG_WR(ISP_LENS_GRID_SIZE, val);
+
+ return ret;
+}
+
+static int32_t isp_k_2d_lsc_slice_size(struct isp_io_param *param)
+{
+ int32_t ret = 0;
+ uint32_t val = 0;
+ struct isp_img_size size = {0, 0};
+
+ ret = copy_from_user((void *)&size, param->property_param, sizeof(size));
+ if (0 != ret) {
+ printk("isp_k_2d_lsc_slice_size: copy error, ret=0x%x\n", (uint32_t)ret);
+ return -1;
+ }
+
+ val = ((size.height & 0xFFFF) << 16) | (size.width & 0xFFFF);
+
+ REG_WR(ISP_LENS_SLICE_SIZE, val);
+
+ return ret;
+}
+
+static int32_t isp_k_2d_lsc_transaddr(struct isp_io_param *param,
+ struct isp_k_private *isp_private)
+{
+ int32_t ret = 0;
+ struct isp_lsc_addr lsc_addr;
+
+ ret = copy_from_user((void *)&lsc_addr, param->property_param, sizeof(struct isp_lsc_addr));
+
+ isp_private->lsc_buf_phys_addr = lsc_addr.phys_addr;
+
+ printk("lsc phys addr 0x%x,\n",isp_private->lsc_buf_phys_addr);
+ return ret;
+}
+
+int32_t isp_k_cfg_2d_lsc(struct isp_io_param *param, struct isp_k_private *isp_private)
+{
+ int32_t ret = 0;
+
+ if (!param) {
+ printk("isp_k_cfg_2d_lsc: param is null error.\n");
+ return -1;
+ }
+
+ if (NULL == param->property_param) {
+ printk("isp_k_cfg_2d_lsc: property_param is null error.\n");
+ return -1;
+ }
+
+ switch(param->property) {
+ case ISP_PRO_2D_LSC_BLOCK:
+ ret = isp_k_2d_lsc_block(param, isp_private);
+ break;
+ case ISP_PRO_2D_LSC_PARAM_UPDATE:
+ ret = isp_k_2d_lsc_param_update(param, isp_private);
+ break;
+ case ISP_PRO_2D_LSC_POS:
+ ret = isp_k_2d_lsc_pos(param);
+ break;
+ case ISP_PRO_2D_LSC_GRID_SIZE:
+ ret = isp_k_2d_lsc_grid_size(param);
+ break;
+ case ISP_PRO_2D_LSC_SLICE_SIZE:
+ ret = isp_k_2d_lsc_slice_size(param);
+ break;
+ case ISP_PRO_2D_LSC_TRANSADDR:
+ ret = isp_k_2d_lsc_transaddr(param, isp_private);
+ break;
+ default:
+ printk("isp_k_cfg_2d_lsc: fail cmd id:%d, not supported.\n", param->property);
+ break;
+ }
+
+ return ret;
+}