tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / media / sprd_isp / isp2.0 / tshark2 / src / isp_k_yiq_afm.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/uaccess.h>
15 #include <linux/sprd_mm.h>
16 #include <video/sprd_isp.h>
17 #include "isp_reg.h"
18
19 #define ISP_AFM_WIN_NUM_V1  25
20
21 static int32_t isp_k_yiq_afm_block(struct isp_io_param *param)
22 {
23         int32_t ret = 0;
24         uint32_t val = 0;
25         uint32_t i = 0;
26         int max_num = ISP_AFM_WIN_NUM_V1;
27         struct isp_dev_yiq_afm_info_v1 afm_info;
28
29         memset(&afm_info, 0x00, sizeof(afm_info));
30
31         ret = copy_from_user((void *)&afm_info, param->property_param, sizeof(afm_info));
32         if (0 != ret) {
33                 printk("isp_k_yiq_afm_block: copy error, ret=0x%x\n", (uint32_t)ret);
34                 return -1;
35         }
36
37         REG_MWR(ISP_YIQ_AFM_PARAM, BIT_6, afm_info.mode << 6);
38
39         REG_MWR(ISP_COMMON_3A_CTRL0, BIT_0, afm_info.source_pos);
40
41         REG_MWR(ISP_YIQ_AFM_PARAM, 0x1F<<1, (afm_info.shift << 1));
42
43         REG_MWR(ISP_YIQ_AFM_PARAM, 0xF<<7, (afm_info.skip_num << 7));
44
45         REG_MWR(ISP_YIQ_AFM_PARAM, BIT_11, afm_info.skip_num_clear << 11);
46
47         REG_MWR(ISP_YIQ_AFM_PARAM, 0x7<<13, (afm_info.format << 13));
48
49         REG_MWR(ISP_YIQ_AFM_PARAM, BIT_16, afm_info.iir_bypass << 16);
50
51         for (i = 0; i < max_num; i++) {
52                 val = ((afm_info.coord[i].start_y <<16) & 0xffff0000)
53                                 | (afm_info.coord[i].start_x & 0xffff);
54                 REG_WR((ISP_YIQ_AFM_WIN_RANGE0 + 4*2*i), val);
55
56                 val = ((afm_info.coord[i].end_y <<16) & 0xffff0000)
57                         | (afm_info.coord[i].end_x & 0xffff);
58                 REG_WR((ISP_YIQ_AFM_WIN_RANGE0 + 4*(2*i+1)), val);
59         }
60
61         for (i = 0; i < 10; i+= 2) {
62                 val = (afm_info.IIR_c[i] & 0xFFF) | ((afm_info.IIR_c[i + 1] & 0xFFF) << 16);
63                 REG_WR(ISP_YIQ_AFM_COEF0_1 + (i / 2) * 4, val);
64         }
65         val = afm_info.IIR_c[10] & 0xFFF;
66         REG_WR(ISP_YIQ_AFM_COEF10, val);
67
68         REG_MWR(ISP_YIQ_AFM_PARAM, BIT_0, afm_info.bypass);
69
70         return ret;
71
72 }
73
74 static int32_t isp_k_yiq_afm_statistic(struct isp_io_param *param)
75 {
76         int32_t ret = 0;
77         int i = 0;
78         int max_item = ISP_AFM_WIN_NUM_V1*4;
79         struct isp_yiq_afm_statistic item;
80
81         memset(&item, 0, sizeof(struct isp_yiq_afm_statistic));
82         for (i = 0; i < max_item; i++) {
83                 item.val[i] = REG_RD((ISP_YIQ_AFM_LAPLACE0 + 4*i));
84         }
85         ret = copy_to_user(param->property_param, (void*)&item, sizeof(item));
86         if (0 != ret) {
87                 ret = -1;
88                 printk("isp_k_yiq_afm_statistic: copy_to_user error, ret = 0x%x\n", (uint32_t)ret);
89         }
90
91         return ret;
92 }
93
94 static int32_t isp_k_yiq_afm_slice_size(struct isp_io_param *param)
95 {
96         int32_t ret = 0;
97         uint32_t val = 0;
98         struct isp_img_size slice_size= {0, 0};
99
100         ret = copy_from_user((void *)&slice_size, param->property_param, sizeof(slice_size));
101         if (0 != ret) {
102                 printk("isp_k_ae_skip_num: copy_from_user error, ret = 0x%x\n", (uint32_t)ret);
103                 return -1;
104         }
105
106         val = (slice_size.width&  0xFFFF) | ((slice_size.height&  0xFFFF) << 16);
107         REG_WR( ISP_YIQ_AFM_SLICE_SIZE, val);
108
109
110         return ret;
111 }
112
113 static int32_t isp_k_yiq_afm_win(struct isp_io_param *param)
114 {
115         int32_t ret = 0;
116         int i = 0;
117         int max_num = ISP_AFM_WIN_NUM_V1;
118         struct isp_coord coord[ISP_AFM_WIN_NUM_V1];
119         uint32_t val = 0;
120
121
122         memset(coord, 0, sizeof(coord));
123         ret = copy_from_user((void *)&coord, param->property_param, sizeof(coord));
124         if (0 != ret) {
125                 printk("isp_k_yiq_afm_win: read copy_from_user error, ret = 0x%x\n", (uint32_t)ret);
126                 return -1;
127         }
128
129         for (i = 0; i < max_num; i++) {
130                 val = ((coord[i].start_y <<16) & 0xffff0000)
131                                 | (coord[i].start_x & 0xffff);
132                 REG_WR((ISP_YIQ_AFM_WIN_RANGE0 + 4*2*i), val);
133
134                 val = ((coord[i].end_y <<16) & 0xffff0000)
135                         | (coord[i].end_x & 0xffff);
136                 REG_WR((ISP_YIQ_AFM_WIN_RANGE0 + 4*(2*i+1)), val);
137         }
138
139         return ret;
140 }
141
142 static int32_t isp_k_yiq_afm_win_num(struct isp_io_param *param)
143 {
144         int32_t ret = 0;
145         uint32_t num = ISP_AFM_WIN_NUM_V1;
146
147         ret = copy_to_user(param->property_param, (void*)&num, sizeof(num));
148         if (0 != ret) {
149                 ret = -1;
150                 printk("isp_k_yiq_afm_win_num: copy_to_user error, ret = 0x%x\n", (uint32_t)ret);
151         }
152
153         return ret;
154 }
155
156
157 int32_t isp_k_cfg_yiq_afm(struct isp_io_param *param)
158 {
159         int32_t ret = 0;
160
161         if (!param) {
162                 printk("isp_k_cfg_afm: param is null error.\n");
163                 return -1;
164         }
165
166         if (NULL == param->property_param) {
167                 printk("isp_k_cfg_afm: property_param is null error.\n");
168                 return -1;
169         }
170
171         switch (param->property) {
172         case ISP_PRO_YIQ_AFM_BLOCK:
173                 ret = isp_k_yiq_afm_block(param);
174                 break;
175         case ISP_PRO_YIQ_AFM_SLICE_SIZE:
176                 ret = isp_k_yiq_afm_slice_size(param);
177                 break;
178         case ISP_PRO_YIQ_AFM_STATISTIC:
179                 ret = isp_k_yiq_afm_statistic(param);
180                 break;
181         case ISP_PRO_YIQ_AFM_WIN_NUM:
182                 ret = isp_k_yiq_afm_win_num(param);
183                 break;
184         case ISP_PRO_YIQ_AFM_WIN:
185                 ret = isp_k_yiq_afm_win(param);
186                 break;
187         default:
188                 printk("isp_k_cfg_yiq_afm: fail cmd id:%d, not supported.\n", param->property);
189                 break;
190         }
191
192         return ret;
193 }