Commit | Line | Data |
---|---|---|
bae1155c JC |
1 | // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
2 | /* | |
3 | * Rockchip ISP1 Driver - Params subdevice | |
4 | * | |
5 | * Copyright (C) 2017 Rockchip Electronics Co., Ltd. | |
6 | */ | |
7 | ||
8 | #include <media/v4l2-common.h> | |
9 | #include <media/v4l2-event.h> | |
10 | #include <media/v4l2-ioctl.h> | |
11 | #include <media/videobuf2-core.h> | |
12 | #include <media/videobuf2-vmalloc.h> /* for ISP params */ | |
13 | ||
14 | #include "rkisp1-common.h" | |
15 | ||
16 | #define RKISP1_PARAMS_DEV_NAME RKISP1_DRIVER_NAME "_params" | |
17 | ||
18 | #define RKISP1_ISP_PARAMS_REQ_BUFS_MIN 2 | |
19 | #define RKISP1_ISP_PARAMS_REQ_BUFS_MAX 8 | |
20 | ||
21 | #define RKISP1_ISP_DPCC_LINE_THRESH(n) \ | |
22 | (RKISP1_CIF_ISP_DPCC_LINE_THRESH_1 + 0x14 * (n)) | |
23 | #define RKISP1_ISP_DPCC_LINE_MAD_FAC(n) \ | |
24 | (RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_1 + 0x14 * (n)) | |
25 | #define RKISP1_ISP_DPCC_PG_FAC(n) \ | |
26 | (RKISP1_CIF_ISP_DPCC_PG_FAC_1 + 0x14 * (n)) | |
27 | #define RKISP1_ISP_DPCC_RND_THRESH(n) \ | |
28 | (RKISP1_CIF_ISP_DPCC_RND_THRESH_1 + 0x14 * (n)) | |
29 | #define RKISP1_ISP_DPCC_RG_FAC(n) \ | |
30 | (RKISP1_CIF_ISP_DPCC_RG_FAC_1 + 0x14 * (n)) | |
31 | #define RKISP1_ISP_CC_COEFF(n) \ | |
32 | (RKISP1_CIF_ISP_CC_COEFF_0 + (n) * 4) | |
33 | ||
34 | static inline void | |
35 | rkisp1_param_set_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) | |
36 | { | |
37 | u32 val; | |
38 | ||
39 | val = rkisp1_read(params->rkisp1, reg); | |
40 | rkisp1_write(params->rkisp1, val | bit_mask, reg); | |
41 | } | |
42 | ||
43 | static inline void | |
44 | rkisp1_param_clear_bits(struct rkisp1_params *params, u32 reg, u32 bit_mask) | |
45 | { | |
46 | u32 val; | |
47 | ||
48 | val = rkisp1_read(params->rkisp1, reg); | |
49 | rkisp1_write(params->rkisp1, val & ~bit_mask, reg); | |
50 | } | |
51 | ||
52 | /* ISP BP interface function */ | |
53 | static void rkisp1_dpcc_config(struct rkisp1_params *params, | |
54 | const struct rkisp1_cif_isp_dpcc_config *arg) | |
55 | { | |
56 | unsigned int i; | |
57 | u32 mode; | |
58 | ||
59 | /* avoid to override the old enable value */ | |
60 | mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DPCC_MODE); | |
61 | mode &= RKISP1_CIF_ISP_DPCC_ENA; | |
62 | mode |= arg->mode & ~RKISP1_CIF_ISP_DPCC_ENA; | |
63 | rkisp1_write(params->rkisp1, mode, RKISP1_CIF_ISP_DPCC_MODE); | |
64 | rkisp1_write(params->rkisp1, arg->output_mode, | |
65 | RKISP1_CIF_ISP_DPCC_OUTPUT_MODE); | |
66 | rkisp1_write(params->rkisp1, arg->set_use, | |
67 | RKISP1_CIF_ISP_DPCC_SET_USE); | |
68 | ||
69 | rkisp1_write(params->rkisp1, arg->methods[0].method, | |
70 | RKISP1_CIF_ISP_DPCC_METHODS_SET_1); | |
71 | rkisp1_write(params->rkisp1, arg->methods[1].method, | |
72 | RKISP1_CIF_ISP_DPCC_METHODS_SET_2); | |
73 | rkisp1_write(params->rkisp1, arg->methods[2].method, | |
74 | RKISP1_CIF_ISP_DPCC_METHODS_SET_3); | |
75 | for (i = 0; i < RKISP1_CIF_ISP_DPCC_METHODS_MAX; i++) { | |
76 | rkisp1_write(params->rkisp1, arg->methods[i].line_thresh, | |
77 | RKISP1_ISP_DPCC_LINE_THRESH(i)); | |
78 | rkisp1_write(params->rkisp1, arg->methods[i].line_mad_fac, | |
79 | RKISP1_ISP_DPCC_LINE_MAD_FAC(i)); | |
80 | rkisp1_write(params->rkisp1, arg->methods[i].pg_fac, | |
81 | RKISP1_ISP_DPCC_PG_FAC(i)); | |
82 | rkisp1_write(params->rkisp1, arg->methods[i].rnd_thresh, | |
83 | RKISP1_ISP_DPCC_RND_THRESH(i)); | |
84 | rkisp1_write(params->rkisp1, arg->methods[i].rg_fac, | |
85 | RKISP1_ISP_DPCC_RG_FAC(i)); | |
86 | } | |
87 | ||
88 | rkisp1_write(params->rkisp1, arg->rnd_offs, | |
89 | RKISP1_CIF_ISP_DPCC_RND_OFFS); | |
90 | rkisp1_write(params->rkisp1, arg->ro_limits, | |
91 | RKISP1_CIF_ISP_DPCC_RO_LIMITS); | |
92 | } | |
93 | ||
94 | /* ISP black level subtraction interface function */ | |
95 | static void rkisp1_bls_config(struct rkisp1_params *params, | |
96 | const struct rkisp1_cif_isp_bls_config *arg) | |
97 | { | |
98 | /* avoid to override the old enable value */ | |
99 | u32 new_control; | |
100 | ||
101 | new_control = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_BLS_CTRL); | |
102 | new_control &= RKISP1_CIF_ISP_BLS_ENA; | |
103 | /* fixed subtraction values */ | |
104 | if (!arg->enable_auto) { | |
105 | const struct rkisp1_cif_isp_bls_fixed_val *pval = | |
106 | &arg->fixed_val; | |
107 | ||
108 | switch (params->raw_type) { | |
109 | case RKISP1_RAW_BGGR: | |
110 | rkisp1_write(params->rkisp1, | |
111 | pval->r, RKISP1_CIF_ISP_BLS_D_FIXED); | |
112 | rkisp1_write(params->rkisp1, | |
113 | pval->gr, RKISP1_CIF_ISP_BLS_C_FIXED); | |
114 | rkisp1_write(params->rkisp1, | |
115 | pval->gb, RKISP1_CIF_ISP_BLS_B_FIXED); | |
116 | rkisp1_write(params->rkisp1, | |
117 | pval->b, RKISP1_CIF_ISP_BLS_A_FIXED); | |
118 | break; | |
119 | case RKISP1_RAW_GBRG: | |
120 | rkisp1_write(params->rkisp1, | |
121 | pval->r, RKISP1_CIF_ISP_BLS_C_FIXED); | |
122 | rkisp1_write(params->rkisp1, | |
123 | pval->gr, RKISP1_CIF_ISP_BLS_D_FIXED); | |
124 | rkisp1_write(params->rkisp1, | |
125 | pval->gb, RKISP1_CIF_ISP_BLS_A_FIXED); | |
126 | rkisp1_write(params->rkisp1, | |
127 | pval->b, RKISP1_CIF_ISP_BLS_B_FIXED); | |
128 | break; | |
129 | case RKISP1_RAW_GRBG: | |
130 | rkisp1_write(params->rkisp1, | |
131 | pval->r, RKISP1_CIF_ISP_BLS_B_FIXED); | |
132 | rkisp1_write(params->rkisp1, | |
133 | pval->gr, RKISP1_CIF_ISP_BLS_A_FIXED); | |
134 | rkisp1_write(params->rkisp1, | |
135 | pval->gb, RKISP1_CIF_ISP_BLS_D_FIXED); | |
136 | rkisp1_write(params->rkisp1, | |
137 | pval->b, RKISP1_CIF_ISP_BLS_C_FIXED); | |
138 | break; | |
139 | case RKISP1_RAW_RGGB: | |
140 | rkisp1_write(params->rkisp1, | |
141 | pval->r, RKISP1_CIF_ISP_BLS_A_FIXED); | |
142 | rkisp1_write(params->rkisp1, | |
143 | pval->gr, RKISP1_CIF_ISP_BLS_B_FIXED); | |
144 | rkisp1_write(params->rkisp1, | |
145 | pval->gb, RKISP1_CIF_ISP_BLS_C_FIXED); | |
146 | rkisp1_write(params->rkisp1, | |
147 | pval->b, RKISP1_CIF_ISP_BLS_D_FIXED); | |
148 | break; | |
149 | default: | |
150 | break; | |
151 | } | |
152 | ||
153 | } else { | |
154 | if (arg->en_windows & BIT(1)) { | |
155 | rkisp1_write(params->rkisp1, arg->bls_window2.h_offs, | |
156 | RKISP1_CIF_ISP_BLS_H2_START); | |
157 | rkisp1_write(params->rkisp1, arg->bls_window2.h_size, | |
158 | RKISP1_CIF_ISP_BLS_H2_STOP); | |
159 | rkisp1_write(params->rkisp1, arg->bls_window2.v_offs, | |
160 | RKISP1_CIF_ISP_BLS_V2_START); | |
161 | rkisp1_write(params->rkisp1, arg->bls_window2.v_size, | |
162 | RKISP1_CIF_ISP_BLS_V2_STOP); | |
163 | new_control |= RKISP1_CIF_ISP_BLS_WINDOW_2; | |
164 | } | |
165 | ||
166 | if (arg->en_windows & BIT(0)) { | |
167 | rkisp1_write(params->rkisp1, arg->bls_window1.h_offs, | |
168 | RKISP1_CIF_ISP_BLS_H1_START); | |
169 | rkisp1_write(params->rkisp1, arg->bls_window1.h_size, | |
170 | RKISP1_CIF_ISP_BLS_H1_STOP); | |
171 | rkisp1_write(params->rkisp1, arg->bls_window1.v_offs, | |
172 | RKISP1_CIF_ISP_BLS_V1_START); | |
173 | rkisp1_write(params->rkisp1, arg->bls_window1.v_size, | |
174 | RKISP1_CIF_ISP_BLS_V1_STOP); | |
175 | new_control |= RKISP1_CIF_ISP_BLS_WINDOW_1; | |
176 | } | |
177 | ||
178 | rkisp1_write(params->rkisp1, arg->bls_samples, | |
179 | RKISP1_CIF_ISP_BLS_SAMPLES); | |
180 | ||
181 | new_control |= RKISP1_CIF_ISP_BLS_MODE_MEASURED; | |
182 | } | |
183 | rkisp1_write(params->rkisp1, new_control, RKISP1_CIF_ISP_BLS_CTRL); | |
184 | } | |
185 | ||
186 | /* ISP LS correction interface function */ | |
187 | static void | |
188 | rkisp1_lsc_correct_matrix_config(struct rkisp1_params *params, | |
189 | const struct rkisp1_cif_isp_lsc_config *pconfig) | |
190 | { | |
191 | unsigned int isp_lsc_status, sram_addr, isp_lsc_table_sel, i, j, data; | |
192 | ||
193 | isp_lsc_status = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_STATUS); | |
194 | ||
195 | /* RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153 = ( 17 * 18 ) >> 1 */ | |
196 | sram_addr = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? | |
197 | RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_0 : | |
198 | RKISP1_CIF_ISP_LSC_TABLE_ADDRESS_153; | |
199 | rkisp1_write(params->rkisp1, sram_addr, | |
200 | RKISP1_CIF_ISP_LSC_R_TABLE_ADDR); | |
201 | rkisp1_write(params->rkisp1, sram_addr, | |
202 | RKISP1_CIF_ISP_LSC_GR_TABLE_ADDR); | |
203 | rkisp1_write(params->rkisp1, sram_addr, | |
204 | RKISP1_CIF_ISP_LSC_GB_TABLE_ADDR); | |
205 | rkisp1_write(params->rkisp1, sram_addr, | |
206 | RKISP1_CIF_ISP_LSC_B_TABLE_ADDR); | |
207 | ||
208 | /* program data tables (table size is 9 * 17 = 153) */ | |
209 | for (i = 0; | |
210 | i < RKISP1_CIF_ISP_LSC_SECTORS_MAX * RKISP1_CIF_ISP_LSC_SECTORS_MAX; | |
211 | i += RKISP1_CIF_ISP_LSC_SECTORS_MAX) { | |
212 | /* | |
213 | * 17 sectors with 2 values in one DWORD = 9 | |
214 | * DWORDs (2nd value of last DWORD unused) | |
215 | */ | |
216 | for (j = 0; j < RKISP1_CIF_ISP_LSC_SECTORS_MAX - 1; j += 2) { | |
217 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i + j], | |
218 | pconfig->r_data_tbl[i + j + 1]); | |
219 | rkisp1_write(params->rkisp1, data, | |
220 | RKISP1_CIF_ISP_LSC_R_TABLE_DATA); | |
221 | ||
222 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i + j], | |
223 | pconfig->gr_data_tbl[i + j + 1]); | |
224 | rkisp1_write(params->rkisp1, data, | |
225 | RKISP1_CIF_ISP_LSC_GR_TABLE_DATA); | |
226 | ||
227 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i + j], | |
228 | pconfig->gb_data_tbl[i + j + 1]); | |
229 | rkisp1_write(params->rkisp1, data, | |
230 | RKISP1_CIF_ISP_LSC_GB_TABLE_DATA); | |
231 | ||
232 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i + j], | |
233 | pconfig->b_data_tbl[i + j + 1]); | |
234 | rkisp1_write(params->rkisp1, data, | |
235 | RKISP1_CIF_ISP_LSC_B_TABLE_DATA); | |
236 | } | |
237 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->r_data_tbl[i + j], 0); | |
238 | rkisp1_write(params->rkisp1, data, | |
239 | RKISP1_CIF_ISP_LSC_R_TABLE_DATA); | |
240 | ||
241 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gr_data_tbl[i + j], 0); | |
242 | rkisp1_write(params->rkisp1, data, | |
243 | RKISP1_CIF_ISP_LSC_GR_TABLE_DATA); | |
244 | ||
245 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->gb_data_tbl[i + j], 0); | |
246 | rkisp1_write(params->rkisp1, data, | |
247 | RKISP1_CIF_ISP_LSC_GB_TABLE_DATA); | |
248 | ||
249 | data = RKISP1_CIF_ISP_LSC_TABLE_DATA(pconfig->b_data_tbl[i + j], 0); | |
250 | rkisp1_write(params->rkisp1, data, | |
251 | RKISP1_CIF_ISP_LSC_B_TABLE_DATA); | |
252 | } | |
253 | isp_lsc_table_sel = (isp_lsc_status & RKISP1_CIF_ISP_LSC_ACTIVE_TABLE) ? | |
254 | RKISP1_CIF_ISP_LSC_TABLE_0 : | |
255 | RKISP1_CIF_ISP_LSC_TABLE_1; | |
256 | rkisp1_write(params->rkisp1, isp_lsc_table_sel, | |
257 | RKISP1_CIF_ISP_LSC_TABLE_SEL); | |
258 | } | |
259 | ||
260 | static void rkisp1_lsc_config(struct rkisp1_params *params, | |
261 | const struct rkisp1_cif_isp_lsc_config *arg) | |
262 | { | |
263 | unsigned int i, data; | |
264 | u32 lsc_ctrl; | |
265 | ||
266 | /* To config must be off , store the current status firstly */ | |
267 | lsc_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_LSC_CTRL); | |
268 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, | |
269 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
270 | rkisp1_lsc_correct_matrix_config(params, arg); | |
271 | ||
272 | for (i = 0; i < 4; i++) { | |
273 | /* program x size tables */ | |
274 | data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_size_tbl[i * 2], | |
275 | arg->x_size_tbl[i * 2 + 1]); | |
276 | rkisp1_write(params->rkisp1, data, | |
277 | RKISP1_CIF_ISP_LSC_XSIZE_01 + i * 4); | |
278 | ||
279 | /* program x grad tables */ | |
280 | data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->x_grad_tbl[i * 2], | |
281 | arg->x_grad_tbl[i * 2 + 1]); | |
282 | rkisp1_write(params->rkisp1, data, | |
283 | RKISP1_CIF_ISP_LSC_XGRAD_01 + i * 4); | |
284 | ||
285 | /* program y size tables */ | |
286 | data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_size_tbl[i * 2], | |
287 | arg->y_size_tbl[i * 2 + 1]); | |
288 | rkisp1_write(params->rkisp1, data, | |
289 | RKISP1_CIF_ISP_LSC_YSIZE_01 + i * 4); | |
290 | ||
291 | /* program y grad tables */ | |
292 | data = RKISP1_CIF_ISP_LSC_SECT_SIZE(arg->y_grad_tbl[i * 2], | |
293 | arg->y_grad_tbl[i * 2 + 1]); | |
294 | rkisp1_write(params->rkisp1, data, | |
295 | RKISP1_CIF_ISP_LSC_YGRAD_01 + i * 4); | |
296 | } | |
297 | ||
298 | /* restore the lsc ctrl status */ | |
299 | if (lsc_ctrl & RKISP1_CIF_ISP_LSC_CTRL_ENA) { | |
300 | rkisp1_param_set_bits(params, | |
301 | RKISP1_CIF_ISP_LSC_CTRL, | |
302 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
303 | } else { | |
304 | rkisp1_param_clear_bits(params, | |
305 | RKISP1_CIF_ISP_LSC_CTRL, | |
306 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
307 | } | |
308 | } | |
309 | ||
310 | /* ISP Filtering function */ | |
311 | static void rkisp1_flt_config(struct rkisp1_params *params, | |
312 | const struct rkisp1_cif_isp_flt_config *arg) | |
313 | { | |
314 | u32 filt_mode; | |
315 | ||
316 | rkisp1_write(params->rkisp1, | |
317 | arg->thresh_bl0, RKISP1_CIF_ISP_FILT_THRESH_BL0); | |
318 | rkisp1_write(params->rkisp1, | |
319 | arg->thresh_bl1, RKISP1_CIF_ISP_FILT_THRESH_BL1); | |
320 | rkisp1_write(params->rkisp1, | |
321 | arg->thresh_sh0, RKISP1_CIF_ISP_FILT_THRESH_SH0); | |
322 | rkisp1_write(params->rkisp1, | |
323 | arg->thresh_sh1, RKISP1_CIF_ISP_FILT_THRESH_SH1); | |
324 | rkisp1_write(params->rkisp1, arg->fac_bl0, RKISP1_CIF_ISP_FILT_FAC_BL0); | |
325 | rkisp1_write(params->rkisp1, arg->fac_bl1, RKISP1_CIF_ISP_FILT_FAC_BL1); | |
326 | rkisp1_write(params->rkisp1, arg->fac_mid, RKISP1_CIF_ISP_FILT_FAC_MID); | |
327 | rkisp1_write(params->rkisp1, arg->fac_sh0, RKISP1_CIF_ISP_FILT_FAC_SH0); | |
328 | rkisp1_write(params->rkisp1, arg->fac_sh1, RKISP1_CIF_ISP_FILT_FAC_SH1); | |
329 | rkisp1_write(params->rkisp1, | |
330 | arg->lum_weight, RKISP1_CIF_ISP_FILT_LUM_WEIGHT); | |
331 | ||
332 | rkisp1_write(params->rkisp1, | |
333 | (arg->mode ? RKISP1_CIF_ISP_FLT_MODE_DNR : 0) | | |
334 | RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) | | |
335 | RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) | | |
336 | RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1), | |
337 | RKISP1_CIF_ISP_FILT_MODE); | |
338 | ||
339 | /* avoid to override the old enable value */ | |
340 | filt_mode = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_FILT_MODE); | |
341 | filt_mode &= RKISP1_CIF_ISP_FLT_ENA; | |
342 | if (arg->mode) | |
343 | filt_mode |= RKISP1_CIF_ISP_FLT_MODE_DNR; | |
344 | filt_mode |= RKISP1_CIF_ISP_FLT_CHROMA_V_MODE(arg->chr_v_mode) | | |
345 | RKISP1_CIF_ISP_FLT_CHROMA_H_MODE(arg->chr_h_mode) | | |
346 | RKISP1_CIF_ISP_FLT_GREEN_STAGE1(arg->grn_stage1); | |
347 | rkisp1_write(params->rkisp1, filt_mode, RKISP1_CIF_ISP_FILT_MODE); | |
348 | } | |
349 | ||
350 | /* ISP demosaic interface function */ | |
351 | static int rkisp1_bdm_config(struct rkisp1_params *params, | |
352 | const struct rkisp1_cif_isp_bdm_config *arg) | |
353 | { | |
354 | u32 bdm_th; | |
355 | ||
356 | /* avoid to override the old enable value */ | |
357 | bdm_th = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_DEMOSAIC); | |
358 | bdm_th &= RKISP1_CIF_ISP_DEMOSAIC_BYPASS; | |
359 | bdm_th |= arg->demosaic_th & ~RKISP1_CIF_ISP_DEMOSAIC_BYPASS; | |
360 | /* set demosaic threshold */ | |
361 | rkisp1_write(params->rkisp1, bdm_th, RKISP1_CIF_ISP_DEMOSAIC); | |
362 | return 0; | |
363 | } | |
364 | ||
365 | /* ISP GAMMA correction interface function */ | |
366 | static void rkisp1_sdg_config(struct rkisp1_params *params, | |
367 | const struct rkisp1_cif_isp_sdg_config *arg) | |
368 | { | |
369 | unsigned int i; | |
370 | ||
371 | rkisp1_write(params->rkisp1, | |
372 | arg->xa_pnts.gamma_dx0, RKISP1_CIF_ISP_GAMMA_DX_LO); | |
373 | rkisp1_write(params->rkisp1, | |
374 | arg->xa_pnts.gamma_dx1, RKISP1_CIF_ISP_GAMMA_DX_HI); | |
375 | ||
376 | for (i = 0; i < RKISP1_CIF_ISP_DEGAMMA_CURVE_SIZE; i++) { | |
377 | rkisp1_write(params->rkisp1, arg->curve_r.gamma_y[i], | |
378 | RKISP1_CIF_ISP_GAMMA_R_Y0 + i * 4); | |
379 | rkisp1_write(params->rkisp1, arg->curve_g.gamma_y[i], | |
380 | RKISP1_CIF_ISP_GAMMA_G_Y0 + i * 4); | |
381 | rkisp1_write(params->rkisp1, arg->curve_b.gamma_y[i], | |
382 | RKISP1_CIF_ISP_GAMMA_B_Y0 + i * 4); | |
383 | } | |
384 | } | |
385 | ||
386 | /* ISP GAMMA correction interface function */ | |
387 | static void rkisp1_goc_config(struct rkisp1_params *params, | |
388 | const struct rkisp1_cif_isp_goc_config *arg) | |
389 | { | |
390 | unsigned int i; | |
391 | ||
392 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
393 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); | |
394 | rkisp1_write(params->rkisp1, arg->mode, RKISP1_CIF_ISP_GAMMA_OUT_MODE); | |
395 | ||
396 | for (i = 0; i < RKISP1_CIF_ISP_GAMMA_OUT_MAX_SAMPLES; i++) | |
397 | rkisp1_write(params->rkisp1, arg->gamma_y[i], | |
398 | RKISP1_CIF_ISP_GAMMA_OUT_Y_0 + i * 4); | |
399 | } | |
400 | ||
401 | /* ISP Cross Talk */ | |
402 | static void rkisp1_ctk_config(struct rkisp1_params *params, | |
403 | const struct rkisp1_cif_isp_ctk_config *arg) | |
404 | { | |
405 | rkisp1_write(params->rkisp1, arg->coeff0, RKISP1_CIF_ISP_CT_COEFF_0); | |
406 | rkisp1_write(params->rkisp1, arg->coeff1, RKISP1_CIF_ISP_CT_COEFF_1); | |
407 | rkisp1_write(params->rkisp1, arg->coeff2, RKISP1_CIF_ISP_CT_COEFF_2); | |
408 | rkisp1_write(params->rkisp1, arg->coeff3, RKISP1_CIF_ISP_CT_COEFF_3); | |
409 | rkisp1_write(params->rkisp1, arg->coeff4, RKISP1_CIF_ISP_CT_COEFF_4); | |
410 | rkisp1_write(params->rkisp1, arg->coeff5, RKISP1_CIF_ISP_CT_COEFF_5); | |
411 | rkisp1_write(params->rkisp1, arg->coeff6, RKISP1_CIF_ISP_CT_COEFF_6); | |
412 | rkisp1_write(params->rkisp1, arg->coeff7, RKISP1_CIF_ISP_CT_COEFF_7); | |
413 | rkisp1_write(params->rkisp1, arg->coeff8, RKISP1_CIF_ISP_CT_COEFF_8); | |
414 | rkisp1_write(params->rkisp1, arg->ct_offset_r, | |
415 | RKISP1_CIF_ISP_CT_OFFSET_R); | |
416 | rkisp1_write(params->rkisp1, arg->ct_offset_g, | |
417 | RKISP1_CIF_ISP_CT_OFFSET_G); | |
418 | rkisp1_write(params->rkisp1, arg->ct_offset_b, | |
419 | RKISP1_CIF_ISP_CT_OFFSET_B); | |
420 | } | |
421 | ||
422 | static void rkisp1_ctk_enable(struct rkisp1_params *params, bool en) | |
423 | { | |
424 | if (en) | |
425 | return; | |
426 | ||
427 | /* Write back the default values. */ | |
428 | rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_0); | |
429 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_1); | |
430 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_2); | |
431 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_3); | |
432 | rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_4); | |
433 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_5); | |
434 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_6); | |
435 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_COEFF_7); | |
436 | rkisp1_write(params->rkisp1, 0x80, RKISP1_CIF_ISP_CT_COEFF_8); | |
437 | ||
438 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_R); | |
439 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_G); | |
440 | rkisp1_write(params->rkisp1, 0, RKISP1_CIF_ISP_CT_OFFSET_B); | |
441 | } | |
442 | ||
443 | /* ISP White Balance Mode */ | |
444 | static void rkisp1_awb_meas_config(struct rkisp1_params *params, | |
445 | const struct rkisp1_cif_isp_awb_meas_config *arg) | |
446 | { | |
447 | u32 reg_val = 0; | |
448 | /* based on the mode,configure the awb module */ | |
449 | if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_YCBCR) { | |
450 | /* Reference Cb and Cr */ | |
451 | rkisp1_write(params->rkisp1, | |
452 | RKISP1_CIF_ISP_AWB_REF_CR_SET(arg->awb_ref_cr) | | |
453 | arg->awb_ref_cb, RKISP1_CIF_ISP_AWB_REF); | |
454 | /* Yc Threshold */ | |
455 | rkisp1_write(params->rkisp1, | |
456 | RKISP1_CIF_ISP_AWB_MAX_Y_SET(arg->max_y) | | |
457 | RKISP1_CIF_ISP_AWB_MIN_Y_SET(arg->min_y) | | |
458 | RKISP1_CIF_ISP_AWB_MAX_CS_SET(arg->max_csum) | | |
459 | arg->min_c, RKISP1_CIF_ISP_AWB_THRESH); | |
460 | } | |
461 | ||
462 | reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP); | |
463 | if (arg->enable_ymax_cmp) | |
464 | reg_val |= RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; | |
465 | else | |
466 | reg_val &= ~RKISP1_CIF_ISP_AWB_YMAX_CMP_EN; | |
467 | rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP); | |
468 | ||
469 | /* window offset */ | |
470 | rkisp1_write(params->rkisp1, | |
471 | arg->awb_wnd.v_offs, RKISP1_CIF_ISP_AWB_WND_V_OFFS); | |
472 | rkisp1_write(params->rkisp1, | |
473 | arg->awb_wnd.h_offs, RKISP1_CIF_ISP_AWB_WND_H_OFFS); | |
474 | /* AWB window size */ | |
475 | rkisp1_write(params->rkisp1, | |
476 | arg->awb_wnd.v_size, RKISP1_CIF_ISP_AWB_WND_V_SIZE); | |
477 | rkisp1_write(params->rkisp1, | |
478 | arg->awb_wnd.h_size, RKISP1_CIF_ISP_AWB_WND_H_SIZE); | |
479 | /* Number of frames */ | |
480 | rkisp1_write(params->rkisp1, | |
481 | arg->frames, RKISP1_CIF_ISP_AWB_FRAMES); | |
482 | } | |
483 | ||
484 | static void | |
485 | rkisp1_awb_meas_enable(struct rkisp1_params *params, | |
486 | const struct rkisp1_cif_isp_awb_meas_config *arg, | |
487 | bool en) | |
488 | { | |
489 | u32 reg_val = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AWB_PROP); | |
490 | ||
491 | /* switch off */ | |
492 | reg_val &= RKISP1_CIF_ISP_AWB_MODE_MASK_NONE; | |
493 | ||
494 | if (en) { | |
495 | if (arg->awb_mode == RKISP1_CIF_ISP_AWB_MODE_RGB) | |
496 | reg_val |= RKISP1_CIF_ISP_AWB_MODE_RGB_EN; | |
497 | else | |
498 | reg_val |= RKISP1_CIF_ISP_AWB_MODE_YCBCR_EN; | |
499 | ||
500 | rkisp1_write(params->rkisp1, reg_val, RKISP1_CIF_ISP_AWB_PROP); | |
501 | ||
502 | /* Measurements require AWB block be active. */ | |
503 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, | |
504 | RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); | |
505 | } else { | |
506 | rkisp1_write(params->rkisp1, | |
507 | reg_val, RKISP1_CIF_ISP_AWB_PROP); | |
508 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
509 | RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); | |
510 | } | |
511 | } | |
512 | ||
513 | static void | |
514 | rkisp1_awb_gain_config(struct rkisp1_params *params, | |
515 | const struct rkisp1_cif_isp_awb_gain_config *arg) | |
516 | { | |
517 | rkisp1_write(params->rkisp1, | |
518 | RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_green_r) | | |
519 | arg->gain_green_b, RKISP1_CIF_ISP_AWB_GAIN_G); | |
520 | ||
521 | rkisp1_write(params->rkisp1, | |
522 | RKISP1_CIF_ISP_AWB_GAIN_R_SET(arg->gain_red) | | |
523 | arg->gain_blue, RKISP1_CIF_ISP_AWB_GAIN_RB); | |
524 | } | |
525 | ||
526 | static void rkisp1_aec_config(struct rkisp1_params *params, | |
527 | const struct rkisp1_cif_isp_aec_config *arg) | |
528 | { | |
529 | unsigned int block_hsize, block_vsize; | |
530 | u32 exp_ctrl; | |
531 | ||
532 | /* avoid to override the old enable value */ | |
533 | exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL); | |
534 | exp_ctrl &= RKISP1_CIF_ISP_EXP_ENA; | |
535 | if (arg->autostop) | |
536 | exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP; | |
537 | if (arg->mode == RKISP1_CIF_ISP_EXP_MEASURING_MODE_1) | |
538 | exp_ctrl |= RKISP1_CIF_ISP_EXP_CTRL_MEASMODE_1; | |
539 | rkisp1_write(params->rkisp1, exp_ctrl, RKISP1_CIF_ISP_EXP_CTRL); | |
540 | ||
541 | rkisp1_write(params->rkisp1, | |
542 | arg->meas_window.h_offs, RKISP1_CIF_ISP_EXP_H_OFFSET); | |
543 | rkisp1_write(params->rkisp1, | |
544 | arg->meas_window.v_offs, RKISP1_CIF_ISP_EXP_V_OFFSET); | |
545 | ||
546 | block_hsize = arg->meas_window.h_size / | |
547 | RKISP1_CIF_ISP_EXP_COLUMN_NUM - 1; | |
548 | block_vsize = arg->meas_window.v_size / | |
549 | RKISP1_CIF_ISP_EXP_ROW_NUM - 1; | |
550 | ||
551 | rkisp1_write(params->rkisp1, | |
552 | RKISP1_CIF_ISP_EXP_H_SIZE_SET(block_hsize), | |
553 | RKISP1_CIF_ISP_EXP_H_SIZE); | |
554 | rkisp1_write(params->rkisp1, | |
555 | RKISP1_CIF_ISP_EXP_V_SIZE_SET(block_vsize), | |
556 | RKISP1_CIF_ISP_EXP_V_SIZE); | |
557 | } | |
558 | ||
559 | static void rkisp1_cproc_config(struct rkisp1_params *params, | |
560 | const struct rkisp1_cif_isp_cproc_config *arg) | |
561 | { | |
562 | struct rkisp1_cif_isp_isp_other_cfg *cur_other_cfg = | |
563 | ¶ms->cur_params.others; | |
564 | struct rkisp1_cif_isp_ie_config *cur_ie_config = | |
565 | &cur_other_cfg->ie_config; | |
566 | u32 effect = cur_ie_config->effect; | |
567 | u32 quantization = params->quantization; | |
568 | ||
569 | rkisp1_write(params->rkisp1, arg->contrast, RKISP1_CIF_C_PROC_CONTRAST); | |
570 | rkisp1_write(params->rkisp1, arg->hue, RKISP1_CIF_C_PROC_HUE); | |
571 | rkisp1_write(params->rkisp1, arg->sat, RKISP1_CIF_C_PROC_SATURATION); | |
572 | rkisp1_write(params->rkisp1, arg->brightness, | |
573 | RKISP1_CIF_C_PROC_BRIGHTNESS); | |
574 | ||
575 | if (quantization != V4L2_QUANTIZATION_FULL_RANGE || | |
576 | effect != V4L2_COLORFX_NONE) { | |
577 | rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, | |
578 | RKISP1_CIF_C_PROC_YOUT_FULL | | |
579 | RKISP1_CIF_C_PROC_YIN_FULL | | |
580 | RKISP1_CIF_C_PROC_COUT_FULL); | |
581 | } else { | |
582 | rkisp1_param_set_bits(params, RKISP1_CIF_C_PROC_CTRL, | |
583 | RKISP1_CIF_C_PROC_YOUT_FULL | | |
584 | RKISP1_CIF_C_PROC_YIN_FULL | | |
585 | RKISP1_CIF_C_PROC_COUT_FULL); | |
586 | } | |
587 | } | |
588 | ||
589 | static void rkisp1_hst_config(struct rkisp1_params *params, | |
590 | const struct rkisp1_cif_isp_hst_config *arg) | |
591 | { | |
592 | unsigned int block_hsize, block_vsize; | |
593 | static const u32 hist_weight_regs[] = { | |
594 | RKISP1_CIF_ISP_HIST_WEIGHT_00TO30, | |
595 | RKISP1_CIF_ISP_HIST_WEIGHT_40TO21, | |
596 | RKISP1_CIF_ISP_HIST_WEIGHT_31TO12, | |
597 | RKISP1_CIF_ISP_HIST_WEIGHT_22TO03, | |
598 | RKISP1_CIF_ISP_HIST_WEIGHT_13TO43, | |
599 | RKISP1_CIF_ISP_HIST_WEIGHT_04TO34, | |
600 | RKISP1_CIF_ISP_HIST_WEIGHT_44, | |
601 | }; | |
602 | const u8 *weight; | |
603 | unsigned int i; | |
604 | u32 hist_prop; | |
605 | ||
606 | /* avoid to override the old enable value */ | |
607 | hist_prop = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_HIST_PROP); | |
608 | hist_prop &= RKISP1_CIF_ISP_HIST_PROP_MODE_MASK; | |
609 | hist_prop |= RKISP1_CIF_ISP_HIST_PREDIV_SET(arg->histogram_predivider); | |
610 | rkisp1_write(params->rkisp1, hist_prop, RKISP1_CIF_ISP_HIST_PROP); | |
611 | rkisp1_write(params->rkisp1, | |
612 | arg->meas_window.h_offs, | |
613 | RKISP1_CIF_ISP_HIST_H_OFFS); | |
614 | rkisp1_write(params->rkisp1, | |
615 | arg->meas_window.v_offs, | |
616 | RKISP1_CIF_ISP_HIST_V_OFFS); | |
617 | ||
618 | block_hsize = arg->meas_window.h_size / | |
619 | RKISP1_CIF_ISP_HIST_COLUMN_NUM - 1; | |
620 | block_vsize = arg->meas_window.v_size / RKISP1_CIF_ISP_HIST_ROW_NUM - 1; | |
621 | ||
622 | rkisp1_write(params->rkisp1, block_hsize, RKISP1_CIF_ISP_HIST_H_SIZE); | |
623 | rkisp1_write(params->rkisp1, block_vsize, RKISP1_CIF_ISP_HIST_V_SIZE); | |
624 | ||
625 | weight = arg->hist_weight; | |
626 | for (i = 0; i < ARRAY_SIZE(hist_weight_regs); ++i, weight += 4) | |
627 | rkisp1_write(params->rkisp1, | |
628 | RKISP1_CIF_ISP_HIST_WEIGHT_SET(weight[0], | |
629 | weight[1], | |
630 | weight[2], | |
631 | weight[3]), | |
632 | hist_weight_regs[i]); | |
633 | } | |
634 | ||
635 | static void | |
636 | rkisp1_hst_enable(struct rkisp1_params *params, | |
637 | const struct rkisp1_cif_isp_hst_config *arg, bool en) | |
638 | { | |
639 | if (en) { | |
640 | u32 hist_prop = rkisp1_read(params->rkisp1, | |
641 | RKISP1_CIF_ISP_HIST_PROP); | |
642 | ||
643 | hist_prop &= ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK; | |
644 | hist_prop |= arg->mode; | |
645 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, | |
646 | hist_prop); | |
647 | } else { | |
648 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_HIST_PROP, | |
649 | RKISP1_CIF_ISP_HIST_PROP_MODE_MASK); | |
650 | } | |
651 | } | |
652 | ||
653 | static void rkisp1_afm_config(struct rkisp1_params *params, | |
654 | const struct rkisp1_cif_isp_afc_config *arg) | |
655 | { | |
656 | size_t num_of_win = min_t(size_t, ARRAY_SIZE(arg->afm_win), | |
657 | arg->num_afm_win); | |
658 | u32 afm_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_AFM_CTRL); | |
659 | unsigned int i; | |
660 | ||
661 | /* Switch off to configure. */ | |
662 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, | |
663 | RKISP1_CIF_ISP_AFM_ENA); | |
664 | ||
665 | for (i = 0; i < num_of_win; i++) { | |
666 | rkisp1_write(params->rkisp1, | |
667 | RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_offs) | | |
668 | RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_offs), | |
669 | RKISP1_CIF_ISP_AFM_LT_A + i * 8); | |
670 | rkisp1_write(params->rkisp1, | |
671 | RKISP1_CIF_ISP_AFM_WINDOW_X(arg->afm_win[i].h_size + | |
672 | arg->afm_win[i].h_offs) | | |
673 | RKISP1_CIF_ISP_AFM_WINDOW_Y(arg->afm_win[i].v_size + | |
674 | arg->afm_win[i].v_offs), | |
675 | RKISP1_CIF_ISP_AFM_RB_A + i * 8); | |
676 | } | |
677 | rkisp1_write(params->rkisp1, arg->thres, RKISP1_CIF_ISP_AFM_THRES); | |
678 | rkisp1_write(params->rkisp1, arg->var_shift, | |
679 | RKISP1_CIF_ISP_AFM_VAR_SHIFT); | |
680 | /* restore afm status */ | |
681 | rkisp1_write(params->rkisp1, afm_ctrl, RKISP1_CIF_ISP_AFM_CTRL); | |
682 | } | |
683 | ||
684 | static void rkisp1_ie_config(struct rkisp1_params *params, | |
685 | const struct rkisp1_cif_isp_ie_config *arg) | |
686 | { | |
687 | u32 eff_ctrl; | |
688 | ||
689 | eff_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL); | |
690 | eff_ctrl &= ~RKISP1_CIF_IMG_EFF_CTRL_MODE_MASK; | |
691 | ||
692 | if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) | |
693 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_YCBCR_FULL; | |
694 | ||
695 | switch (arg->effect) { | |
696 | case V4L2_COLORFX_SEPIA: | |
697 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA; | |
698 | break; | |
699 | case V4L2_COLORFX_SET_CBCR: | |
700 | rkisp1_write(params->rkisp1, arg->eff_tint, | |
701 | RKISP1_CIF_IMG_EFF_TINT); | |
702 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SEPIA; | |
703 | break; | |
704 | /* | |
705 | * Color selection is similar to water color(AQUA): | |
706 | * grayscale + selected color w threshold | |
707 | */ | |
708 | case V4L2_COLORFX_AQUA: | |
709 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_COLOR_SEL; | |
710 | rkisp1_write(params->rkisp1, arg->color_sel, | |
711 | RKISP1_CIF_IMG_EFF_COLOR_SEL); | |
712 | break; | |
713 | case V4L2_COLORFX_EMBOSS: | |
714 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_EMBOSS; | |
715 | rkisp1_write(params->rkisp1, arg->eff_mat_1, | |
716 | RKISP1_CIF_IMG_EFF_MAT_1); | |
717 | rkisp1_write(params->rkisp1, arg->eff_mat_2, | |
718 | RKISP1_CIF_IMG_EFF_MAT_2); | |
719 | rkisp1_write(params->rkisp1, arg->eff_mat_3, | |
720 | RKISP1_CIF_IMG_EFF_MAT_3); | |
721 | break; | |
722 | case V4L2_COLORFX_SKETCH: | |
723 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_SKETCH; | |
724 | rkisp1_write(params->rkisp1, arg->eff_mat_3, | |
725 | RKISP1_CIF_IMG_EFF_MAT_3); | |
726 | rkisp1_write(params->rkisp1, arg->eff_mat_4, | |
727 | RKISP1_CIF_IMG_EFF_MAT_4); | |
728 | rkisp1_write(params->rkisp1, arg->eff_mat_5, | |
729 | RKISP1_CIF_IMG_EFF_MAT_5); | |
730 | break; | |
731 | case V4L2_COLORFX_BW: | |
732 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_BLACKWHITE; | |
733 | break; | |
734 | case V4L2_COLORFX_NEGATIVE: | |
735 | eff_ctrl |= RKISP1_CIF_IMG_EFF_CTRL_MODE_NEGATIVE; | |
736 | break; | |
737 | default: | |
738 | break; | |
739 | } | |
740 | ||
741 | rkisp1_write(params->rkisp1, eff_ctrl, RKISP1_CIF_IMG_EFF_CTRL); | |
742 | } | |
743 | ||
744 | static void rkisp1_ie_enable(struct rkisp1_params *params, bool en) | |
745 | { | |
746 | if (en) { | |
747 | rkisp1_param_set_bits(params, RKISP1_CIF_ICCL, | |
748 | RKISP1_CIF_ICCL_IE_CLK); | |
749 | rkisp1_write(params->rkisp1, RKISP1_CIF_IMG_EFF_CTRL_ENABLE, | |
750 | RKISP1_CIF_IMG_EFF_CTRL); | |
751 | rkisp1_param_set_bits(params, RKISP1_CIF_IMG_EFF_CTRL, | |
752 | RKISP1_CIF_IMG_EFF_CTRL_CFG_UPD); | |
753 | } else { | |
754 | rkisp1_param_clear_bits(params, RKISP1_CIF_IMG_EFF_CTRL, | |
755 | RKISP1_CIF_IMG_EFF_CTRL_ENABLE); | |
756 | rkisp1_param_clear_bits(params, RKISP1_CIF_ICCL, | |
757 | RKISP1_CIF_ICCL_IE_CLK); | |
758 | } | |
759 | } | |
760 | ||
761 | static void rkisp1_csm_config(struct rkisp1_params *params, bool full_range) | |
762 | { | |
763 | static const u16 full_range_coeff[] = { | |
764 | 0x0026, 0x004b, 0x000f, | |
765 | 0x01ea, 0x01d6, 0x0040, | |
766 | 0x0040, 0x01ca, 0x01f6 | |
767 | }; | |
768 | static const u16 limited_range_coeff[] = { | |
769 | 0x0021, 0x0040, 0x000d, | |
770 | 0x01ed, 0x01db, 0x0038, | |
771 | 0x0038, 0x01d1, 0x01f7, | |
772 | }; | |
773 | unsigned int i; | |
774 | ||
775 | if (full_range) { | |
776 | for (i = 0; i < ARRAY_SIZE(full_range_coeff); i++) | |
777 | rkisp1_write(params->rkisp1, full_range_coeff[i], | |
778 | RKISP1_CIF_ISP_CC_COEFF_0 + i * 4); | |
779 | ||
780 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_CTRL, | |
781 | RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | | |
782 | RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); | |
783 | } else { | |
784 | for (i = 0; i < ARRAY_SIZE(limited_range_coeff); i++) | |
785 | rkisp1_write(params->rkisp1, limited_range_coeff[i], | |
786 | RKISP1_CIF_ISP_CC_COEFF_0 + i * 4); | |
787 | ||
788 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
789 | RKISP1_CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | | |
790 | RKISP1_CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA); | |
791 | } | |
792 | } | |
793 | ||
794 | /* ISP De-noise Pre-Filter(DPF) function */ | |
795 | static void rkisp1_dpf_config(struct rkisp1_params *params, | |
796 | const struct rkisp1_cif_isp_dpf_config *arg) | |
797 | { | |
798 | unsigned int isp_dpf_mode, spatial_coeff, i; | |
799 | ||
800 | switch (arg->gain.mode) { | |
801 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_GAINS: | |
802 | isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN | | |
803 | RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; | |
804 | break; | |
805 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_LSC_GAINS: | |
806 | isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP; | |
807 | break; | |
808 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_NF_LSC_GAINS: | |
809 | isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_USE_NF_GAIN | | |
810 | RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP | | |
811 | RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP; | |
812 | break; | |
813 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_GAINS: | |
814 | isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; | |
815 | break; | |
816 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_AWB_LSC_GAINS: | |
817 | isp_dpf_mode = RKISP1_CIF_ISP_DPF_MODE_LSC_GAIN_COMP | | |
818 | RKISP1_CIF_ISP_DPF_MODE_AWB_GAIN_COMP; | |
819 | break; | |
820 | case RKISP1_CIF_ISP_DPF_GAIN_USAGE_DISABLED: | |
821 | default: | |
822 | isp_dpf_mode = 0; | |
823 | break; | |
824 | } | |
825 | ||
826 | if (arg->nll.scale_mode == RKISP1_CIF_ISP_NLL_SCALE_LOGARITHMIC) | |
827 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_NLL_SEGMENTATION; | |
828 | if (arg->rb_flt.fltsize == RKISP1_CIF_ISP_DPF_RB_FILTERSIZE_9x9) | |
829 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_RB_FLTSIZE_9x9; | |
830 | if (!arg->rb_flt.r_enable) | |
831 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_R_FLT_DIS; | |
832 | if (!arg->rb_flt.b_enable) | |
833 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_B_FLT_DIS; | |
834 | if (!arg->g_flt.gb_enable) | |
835 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GB_FLT_DIS; | |
836 | if (!arg->g_flt.gr_enable) | |
837 | isp_dpf_mode |= RKISP1_CIF_ISP_DPF_MODE_GR_FLT_DIS; | |
838 | ||
839 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_DPF_MODE, | |
840 | isp_dpf_mode); | |
841 | rkisp1_write(params->rkisp1, arg->gain.nf_b_gain, | |
842 | RKISP1_CIF_ISP_DPF_NF_GAIN_B); | |
843 | rkisp1_write(params->rkisp1, arg->gain.nf_r_gain, | |
844 | RKISP1_CIF_ISP_DPF_NF_GAIN_R); | |
845 | rkisp1_write(params->rkisp1, arg->gain.nf_gb_gain, | |
846 | RKISP1_CIF_ISP_DPF_NF_GAIN_GB); | |
847 | rkisp1_write(params->rkisp1, arg->gain.nf_gr_gain, | |
848 | RKISP1_CIF_ISP_DPF_NF_GAIN_GR); | |
849 | ||
850 | for (i = 0; i < RKISP1_CIF_ISP_DPF_MAX_NLF_COEFFS; i++) { | |
851 | rkisp1_write(params->rkisp1, arg->nll.coeff[i], | |
852 | RKISP1_CIF_ISP_DPF_NULL_COEFF_0 + i * 4); | |
853 | } | |
854 | ||
855 | spatial_coeff = arg->g_flt.spatial_coeff[0] | | |
856 | (arg->g_flt.spatial_coeff[1] << 8) | | |
857 | (arg->g_flt.spatial_coeff[2] << 16) | | |
858 | (arg->g_flt.spatial_coeff[3] << 24); | |
859 | rkisp1_write(params->rkisp1, spatial_coeff, | |
860 | RKISP1_CIF_ISP_DPF_S_WEIGHT_G_1_4); | |
861 | ||
862 | spatial_coeff = arg->g_flt.spatial_coeff[4] | | |
863 | (arg->g_flt.spatial_coeff[5] << 8); | |
864 | rkisp1_write(params->rkisp1, spatial_coeff, | |
865 | RKISP1_CIF_ISP_DPF_S_WEIGHT_G_5_6); | |
866 | ||
867 | spatial_coeff = arg->rb_flt.spatial_coeff[0] | | |
868 | (arg->rb_flt.spatial_coeff[1] << 8) | | |
869 | (arg->rb_flt.spatial_coeff[2] << 16) | | |
870 | (arg->rb_flt.spatial_coeff[3] << 24); | |
871 | rkisp1_write(params->rkisp1, spatial_coeff, | |
872 | RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_1_4); | |
873 | ||
874 | spatial_coeff = arg->rb_flt.spatial_coeff[4] | | |
875 | (arg->rb_flt.spatial_coeff[5] << 8); | |
876 | rkisp1_write(params->rkisp1, spatial_coeff, | |
877 | RKISP1_CIF_ISP_DPF_S_WEIGHT_RB_5_6); | |
878 | } | |
879 | ||
880 | static void | |
881 | rkisp1_dpf_strength_config(struct rkisp1_params *params, | |
882 | const struct rkisp1_cif_isp_dpf_strength_config *arg) | |
883 | { | |
884 | rkisp1_write(params->rkisp1, arg->b, RKISP1_CIF_ISP_DPF_STRENGTH_B); | |
885 | rkisp1_write(params->rkisp1, arg->g, RKISP1_CIF_ISP_DPF_STRENGTH_G); | |
886 | rkisp1_write(params->rkisp1, arg->r, RKISP1_CIF_ISP_DPF_STRENGTH_R); | |
887 | } | |
888 | ||
889 | static void | |
890 | rkisp1_isp_isr_other_config(struct rkisp1_params *params, | |
891 | const struct rkisp1_params_cfg *new_params) | |
892 | { | |
893 | unsigned int module_en_update, module_cfg_update, module_ens; | |
894 | ||
895 | module_en_update = new_params->module_en_update; | |
896 | module_cfg_update = new_params->module_cfg_update; | |
897 | module_ens = new_params->module_ens; | |
898 | ||
899 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) || | |
900 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) { | |
901 | /*update dpc config */ | |
902 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_DPCC)) | |
903 | rkisp1_dpcc_config(params, | |
904 | &new_params->others.dpcc_config); | |
905 | ||
906 | if (module_en_update & RKISP1_CIF_ISP_MODULE_DPCC) { | |
907 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_DPCC)) | |
908 | rkisp1_param_set_bits(params, | |
909 | RKISP1_CIF_ISP_DPCC_MODE, | |
910 | RKISP1_CIF_ISP_DPCC_ENA); | |
911 | else | |
912 | rkisp1_param_clear_bits(params, | |
913 | RKISP1_CIF_ISP_DPCC_MODE, | |
914 | RKISP1_CIF_ISP_DPCC_ENA); | |
915 | } | |
916 | } | |
917 | ||
918 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_BLS) || | |
919 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) { | |
920 | /* update bls config */ | |
921 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_BLS)) | |
922 | rkisp1_bls_config(params, | |
923 | &new_params->others.bls_config); | |
924 | ||
925 | if (module_en_update & RKISP1_CIF_ISP_MODULE_BLS) { | |
926 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_BLS)) | |
927 | rkisp1_param_set_bits(params, | |
928 | RKISP1_CIF_ISP_BLS_CTRL, | |
929 | RKISP1_CIF_ISP_BLS_ENA); | |
930 | else | |
931 | rkisp1_param_clear_bits(params, | |
932 | RKISP1_CIF_ISP_BLS_CTRL, | |
933 | RKISP1_CIF_ISP_BLS_ENA); | |
934 | } | |
935 | } | |
936 | ||
937 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_SDG) || | |
938 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) { | |
939 | /* update sdg config */ | |
940 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_SDG)) | |
941 | rkisp1_sdg_config(params, | |
942 | &new_params->others.sdg_config); | |
943 | ||
944 | if (module_en_update & RKISP1_CIF_ISP_MODULE_SDG) { | |
945 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_SDG)) | |
946 | rkisp1_param_set_bits(params, | |
947 | RKISP1_CIF_ISP_CTRL, | |
948 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); | |
949 | else | |
950 | rkisp1_param_clear_bits(params, | |
951 | RKISP1_CIF_ISP_CTRL, | |
952 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); | |
953 | } | |
954 | } | |
955 | ||
956 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_LSC) || | |
957 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) { | |
958 | /* update lsc config */ | |
959 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_LSC)) | |
960 | rkisp1_lsc_config(params, | |
961 | &new_params->others.lsc_config); | |
962 | ||
963 | if (module_en_update & RKISP1_CIF_ISP_MODULE_LSC) { | |
964 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_LSC)) | |
965 | rkisp1_param_set_bits(params, | |
966 | RKISP1_CIF_ISP_LSC_CTRL, | |
967 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
968 | else | |
969 | rkisp1_param_clear_bits(params, | |
970 | RKISP1_CIF_ISP_LSC_CTRL, | |
971 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
972 | } | |
973 | } | |
974 | ||
975 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) || | |
976 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) { | |
977 | /* update awb gains */ | |
978 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) | |
979 | rkisp1_awb_gain_config(params, | |
980 | &new_params->others.awb_gain_config); | |
981 | ||
982 | if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB_GAIN) { | |
983 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AWB_GAIN)) | |
984 | rkisp1_param_set_bits(params, | |
985 | RKISP1_CIF_ISP_CTRL, | |
986 | RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); | |
987 | else | |
988 | rkisp1_param_clear_bits(params, | |
989 | RKISP1_CIF_ISP_CTRL, | |
990 | RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); | |
991 | } | |
992 | } | |
993 | ||
994 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_BDM) || | |
995 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) { | |
996 | /* update bdm config */ | |
997 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_BDM)) | |
998 | rkisp1_bdm_config(params, | |
999 | &new_params->others.bdm_config); | |
1000 | ||
1001 | if (module_en_update & RKISP1_CIF_ISP_MODULE_BDM) { | |
1002 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_BDM)) | |
1003 | rkisp1_param_set_bits(params, | |
1004 | RKISP1_CIF_ISP_DEMOSAIC, | |
1005 | RKISP1_CIF_ISP_DEMOSAIC_BYPASS); | |
1006 | else | |
1007 | rkisp1_param_clear_bits(params, | |
1008 | RKISP1_CIF_ISP_DEMOSAIC, | |
1009 | RKISP1_CIF_ISP_DEMOSAIC_BYPASS); | |
1010 | } | |
1011 | } | |
1012 | ||
1013 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_FLT) || | |
1014 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) { | |
1015 | /* update filter config */ | |
1016 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_FLT)) | |
1017 | rkisp1_flt_config(params, | |
1018 | &new_params->others.flt_config); | |
1019 | ||
1020 | if (module_en_update & RKISP1_CIF_ISP_MODULE_FLT) { | |
1021 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_FLT)) | |
1022 | rkisp1_param_set_bits(params, | |
1023 | RKISP1_CIF_ISP_FILT_MODE, | |
1024 | RKISP1_CIF_ISP_FLT_ENA); | |
1025 | else | |
1026 | rkisp1_param_clear_bits(params, | |
1027 | RKISP1_CIF_ISP_FILT_MODE, | |
1028 | RKISP1_CIF_ISP_FLT_ENA); | |
1029 | } | |
1030 | } | |
1031 | ||
1032 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_CTK) || | |
1033 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) { | |
1034 | /* update ctk config */ | |
1035 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_CTK)) | |
1036 | rkisp1_ctk_config(params, | |
1037 | &new_params->others.ctk_config); | |
1038 | ||
1039 | if (module_en_update & RKISP1_CIF_ISP_MODULE_CTK) | |
1040 | rkisp1_ctk_enable(params, | |
1041 | !!(module_ens & RKISP1_CIF_ISP_MODULE_CTK)); | |
1042 | } | |
1043 | ||
1044 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_GOC) || | |
1045 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) { | |
1046 | /* update goc config */ | |
1047 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_GOC)) | |
1048 | rkisp1_goc_config(params, | |
1049 | &new_params->others.goc_config); | |
1050 | ||
1051 | if (module_en_update & RKISP1_CIF_ISP_MODULE_GOC) { | |
1052 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_GOC)) | |
1053 | rkisp1_param_set_bits(params, | |
1054 | RKISP1_CIF_ISP_CTRL, | |
1055 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); | |
1056 | else | |
1057 | rkisp1_param_clear_bits(params, | |
1058 | RKISP1_CIF_ISP_CTRL, | |
1059 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); | |
1060 | } | |
1061 | } | |
1062 | ||
1063 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) || | |
1064 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) { | |
1065 | /* update cproc config */ | |
1066 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_CPROC)) { | |
1067 | rkisp1_cproc_config(params, | |
1068 | &new_params->others.cproc_config); | |
1069 | } | |
1070 | ||
1071 | if (module_en_update & RKISP1_CIF_ISP_MODULE_CPROC) { | |
1072 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_CPROC)) | |
1073 | rkisp1_param_set_bits(params, | |
1074 | RKISP1_CIF_C_PROC_CTRL, | |
1075 | RKISP1_CIF_C_PROC_CTR_ENABLE); | |
1076 | else | |
1077 | rkisp1_param_clear_bits(params, | |
1078 | RKISP1_CIF_C_PROC_CTRL, | |
1079 | RKISP1_CIF_C_PROC_CTR_ENABLE); | |
1080 | } | |
1081 | } | |
1082 | ||
1083 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_IE) || | |
1084 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) { | |
1085 | /* update ie config */ | |
1086 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_IE)) | |
1087 | rkisp1_ie_config(params, | |
1088 | &new_params->others.ie_config); | |
1089 | ||
1090 | if (module_en_update & RKISP1_CIF_ISP_MODULE_IE) | |
1091 | rkisp1_ie_enable(params, | |
1092 | !!(module_ens & RKISP1_CIF_ISP_MODULE_IE)); | |
1093 | } | |
1094 | ||
1095 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF) || | |
1096 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) { | |
1097 | /* update dpf config */ | |
1098 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF)) | |
1099 | rkisp1_dpf_config(params, | |
1100 | &new_params->others.dpf_config); | |
1101 | ||
1102 | if (module_en_update & RKISP1_CIF_ISP_MODULE_DPF) { | |
1103 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_DPF)) | |
1104 | rkisp1_param_set_bits(params, | |
1105 | RKISP1_CIF_ISP_DPF_MODE, | |
1106 | RKISP1_CIF_ISP_DPF_MODE_EN); | |
1107 | else | |
1108 | rkisp1_param_clear_bits(params, | |
1109 | RKISP1_CIF_ISP_DPF_MODE, | |
1110 | RKISP1_CIF_ISP_DPF_MODE_EN); | |
1111 | } | |
1112 | } | |
1113 | ||
1114 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH) || | |
1115 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_DPF_STRENGTH)) { | |
1116 | /* update dpf strength config */ | |
1117 | rkisp1_dpf_strength_config(params, | |
1118 | &new_params->others.dpf_strength_config); | |
1119 | } | |
1120 | } | |
1121 | ||
1122 | static void rkisp1_isp_isr_meas_config(struct rkisp1_params *params, | |
1123 | struct rkisp1_params_cfg *new_params) | |
1124 | { | |
1125 | unsigned int module_en_update, module_cfg_update, module_ens; | |
1126 | ||
1127 | module_en_update = new_params->module_en_update; | |
1128 | module_cfg_update = new_params->module_cfg_update; | |
1129 | module_ens = new_params->module_ens; | |
1130 | ||
1131 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_AWB) || | |
1132 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) { | |
1133 | /* update awb config */ | |
1134 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AWB)) | |
1135 | rkisp1_awb_meas_config(params, | |
1136 | &new_params->meas.awb_meas_config); | |
1137 | ||
1138 | if (module_en_update & RKISP1_CIF_ISP_MODULE_AWB) | |
1139 | rkisp1_awb_meas_enable(params, | |
1140 | &new_params->meas.awb_meas_config, | |
1141 | !!(module_ens & RKISP1_CIF_ISP_MODULE_AWB)); | |
1142 | } | |
1143 | ||
1144 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_AFC) || | |
1145 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) { | |
1146 | /* update afc config */ | |
1147 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AFC)) | |
1148 | rkisp1_afm_config(params, | |
1149 | &new_params->meas.afc_config); | |
1150 | ||
1151 | if (module_en_update & RKISP1_CIF_ISP_MODULE_AFC) { | |
1152 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AFC)) | |
1153 | rkisp1_param_set_bits(params, | |
1154 | RKISP1_CIF_ISP_AFM_CTRL, | |
1155 | RKISP1_CIF_ISP_AFM_ENA); | |
1156 | else | |
1157 | rkisp1_param_clear_bits(params, | |
1158 | RKISP1_CIF_ISP_AFM_CTRL, | |
1159 | RKISP1_CIF_ISP_AFM_ENA); | |
1160 | } | |
1161 | } | |
1162 | ||
1163 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_HST) || | |
1164 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) { | |
1165 | /* update hst config */ | |
1166 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_HST)) | |
1167 | rkisp1_hst_config(params, | |
1168 | &new_params->meas.hst_config); | |
1169 | ||
1170 | if (module_en_update & RKISP1_CIF_ISP_MODULE_HST) | |
1171 | rkisp1_hst_enable(params, | |
1172 | &new_params->meas.hst_config, | |
1173 | !!(module_ens & RKISP1_CIF_ISP_MODULE_HST)); | |
1174 | } | |
1175 | ||
1176 | if ((module_en_update & RKISP1_CIF_ISP_MODULE_AEC) || | |
1177 | (module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) { | |
1178 | /* update aec config */ | |
1179 | if ((module_cfg_update & RKISP1_CIF_ISP_MODULE_AEC)) | |
1180 | rkisp1_aec_config(params, | |
1181 | &new_params->meas.aec_config); | |
1182 | ||
1183 | if (module_en_update & RKISP1_CIF_ISP_MODULE_AEC) { | |
1184 | if (!!(module_ens & RKISP1_CIF_ISP_MODULE_AEC)) | |
1185 | rkisp1_param_set_bits(params, | |
1186 | RKISP1_CIF_ISP_EXP_CTRL, | |
1187 | RKISP1_CIF_ISP_EXP_ENA); | |
1188 | else | |
1189 | rkisp1_param_clear_bits(params, | |
1190 | RKISP1_CIF_ISP_EXP_CTRL, | |
1191 | RKISP1_CIF_ISP_EXP_ENA); | |
1192 | } | |
1193 | } | |
1194 | } | |
1195 | ||
1196 | void rkisp1_params_isr(struct rkisp1_device *rkisp1, u32 isp_mis) | |
1197 | { | |
1198 | unsigned int frame_sequence = atomic_read(&rkisp1->isp.frame_sequence); | |
1199 | struct rkisp1_params *params = &rkisp1->params; | |
1200 | struct rkisp1_params_cfg *new_params; | |
1201 | struct rkisp1_buffer *cur_buf = NULL; | |
1202 | ||
1203 | spin_lock(¶ms->config_lock); | |
1204 | if (!params->is_streaming) { | |
1205 | spin_unlock(¶ms->config_lock); | |
1206 | return; | |
1207 | } | |
1208 | ||
1209 | /* get one empty buffer */ | |
1210 | if (!list_empty(¶ms->params)) | |
1211 | cur_buf = list_first_entry(¶ms->params, | |
1212 | struct rkisp1_buffer, queue); | |
1213 | spin_unlock(¶ms->config_lock); | |
1214 | ||
1215 | if (!cur_buf) | |
1216 | return; | |
1217 | ||
1218 | new_params = (struct rkisp1_params_cfg *)(cur_buf->vaddr[0]); | |
1219 | ||
1220 | if (isp_mis & RKISP1_CIF_ISP_FRAME) { | |
1221 | u32 isp_ctrl; | |
1222 | ||
1223 | rkisp1_isp_isr_other_config(params, new_params); | |
1224 | rkisp1_isp_isr_meas_config(params, new_params); | |
1225 | ||
1226 | /* update shadow register immediately */ | |
1227 | isp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_CTRL); | |
1228 | isp_ctrl |= RKISP1_CIF_ISP_CTRL_ISP_CFG_UPD; | |
1229 | rkisp1_write(params->rkisp1, isp_ctrl, RKISP1_CIF_ISP_CTRL); | |
1230 | ||
1231 | spin_lock(¶ms->config_lock); | |
1232 | list_del(&cur_buf->queue); | |
1233 | spin_unlock(¶ms->config_lock); | |
1234 | ||
1235 | cur_buf->vb.sequence = frame_sequence; | |
1236 | vb2_buffer_done(&cur_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); | |
1237 | } | |
1238 | } | |
1239 | ||
1240 | static const struct rkisp1_cif_isp_awb_meas_config rkisp1_awb_params_default_config = { | |
1241 | { | |
1242 | 0, 0, RKISP1_DEFAULT_WIDTH, RKISP1_DEFAULT_HEIGHT | |
1243 | }, | |
1244 | RKISP1_CIF_ISP_AWB_MODE_YCBCR, 200, 30, 20, 20, 0, 128, 128 | |
1245 | }; | |
1246 | ||
1247 | static const struct rkisp1_cif_isp_aec_config rkisp1_aec_params_default_config = { | |
1248 | RKISP1_CIF_ISP_EXP_MEASURING_MODE_0, | |
1249 | RKISP1_CIF_ISP_EXP_CTRL_AUTOSTOP_0, | |
1250 | { | |
1251 | RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, | |
1252 | RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 | |
1253 | } | |
1254 | }; | |
1255 | ||
1256 | static const struct rkisp1_cif_isp_hst_config rkisp1_hst_params_default_config = { | |
1257 | RKISP1_CIF_ISP_HISTOGRAM_MODE_RGB_COMBINED, | |
1258 | 3, | |
1259 | { | |
1260 | RKISP1_DEFAULT_WIDTH >> 2, RKISP1_DEFAULT_HEIGHT >> 2, | |
1261 | RKISP1_DEFAULT_WIDTH >> 1, RKISP1_DEFAULT_HEIGHT >> 1 | |
1262 | }, | |
1263 | { | |
1264 | 0, /* To be filled in with 0x01 at runtime. */ | |
1265 | } | |
1266 | }; | |
1267 | ||
1268 | static const struct rkisp1_cif_isp_afc_config rkisp1_afc_params_default_config = { | |
1269 | 1, | |
1270 | { | |
1271 | { | |
1272 | 300, 225, 200, 150 | |
1273 | } | |
1274 | }, | |
1275 | 4, | |
1276 | 14 | |
1277 | }; | |
1278 | ||
1279 | static void rkisp1_params_config_parameter(struct rkisp1_params *params) | |
1280 | { | |
1281 | struct rkisp1_cif_isp_hst_config hst = rkisp1_hst_params_default_config; | |
1282 | ||
1283 | spin_lock(¶ms->config_lock); | |
1284 | ||
1285 | rkisp1_awb_meas_config(params, &rkisp1_awb_params_default_config); | |
1286 | rkisp1_awb_meas_enable(params, &rkisp1_awb_params_default_config, | |
1287 | true); | |
1288 | ||
1289 | rkisp1_aec_config(params, &rkisp1_aec_params_default_config); | |
1290 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_EXP_CTRL, | |
1291 | RKISP1_CIF_ISP_EXP_ENA); | |
1292 | ||
1293 | rkisp1_afm_config(params, &rkisp1_afc_params_default_config); | |
1294 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_AFM_CTRL, | |
1295 | RKISP1_CIF_ISP_AFM_ENA); | |
1296 | ||
1297 | memset(hst.hist_weight, 0x01, sizeof(hst.hist_weight)); | |
1298 | rkisp1_hst_config(params, &hst); | |
1299 | rkisp1_param_set_bits(params, RKISP1_CIF_ISP_HIST_PROP, | |
1300 | ~RKISP1_CIF_ISP_HIST_PROP_MODE_MASK | | |
1301 | rkisp1_hst_params_default_config.mode); | |
1302 | ||
1303 | /* set the range */ | |
1304 | if (params->quantization == V4L2_QUANTIZATION_FULL_RANGE) | |
1305 | rkisp1_csm_config(params, true); | |
1306 | else | |
1307 | rkisp1_csm_config(params, false); | |
1308 | ||
1309 | /* override the default things */ | |
1310 | rkisp1_isp_isr_other_config(params, ¶ms->cur_params); | |
1311 | rkisp1_isp_isr_meas_config(params, ¶ms->cur_params); | |
1312 | ||
1313 | spin_unlock(¶ms->config_lock); | |
1314 | } | |
1315 | ||
1316 | /* Not called when the camera active, thus not isr protection. */ | |
1317 | void rkisp1_params_configure(struct rkisp1_params *params, | |
1318 | enum rkisp1_fmt_raw_pat_type bayer_pat, | |
1319 | enum v4l2_quantization quantization) | |
1320 | { | |
1321 | params->quantization = quantization; | |
1322 | params->raw_type = bayer_pat; | |
1323 | rkisp1_params_config_parameter(params); | |
1324 | } | |
1325 | ||
1326 | /* Not called when the camera active, thus not isr protection. */ | |
1327 | void rkisp1_params_disable(struct rkisp1_params *params) | |
1328 | { | |
1329 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPCC_MODE, | |
1330 | RKISP1_CIF_ISP_DPCC_ENA); | |
1331 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_LSC_CTRL, | |
1332 | RKISP1_CIF_ISP_LSC_CTRL_ENA); | |
1333 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_BLS_CTRL, | |
1334 | RKISP1_CIF_ISP_BLS_ENA); | |
1335 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
1336 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_IN_ENA); | |
1337 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
1338 | RKISP1_CIF_ISP_CTRL_ISP_GAMMA_OUT_ENA); | |
1339 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DEMOSAIC, | |
1340 | RKISP1_CIF_ISP_DEMOSAIC_BYPASS); | |
1341 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_FILT_MODE, | |
1342 | RKISP1_CIF_ISP_FLT_ENA); | |
1343 | rkisp1_awb_meas_enable(params, NULL, false); | |
1344 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_CTRL, | |
1345 | RKISP1_CIF_ISP_CTRL_ISP_AWB_ENA); | |
1346 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_EXP_CTRL, | |
1347 | RKISP1_CIF_ISP_EXP_ENA); | |
1348 | rkisp1_ctk_enable(params, false); | |
1349 | rkisp1_param_clear_bits(params, RKISP1_CIF_C_PROC_CTRL, | |
1350 | RKISP1_CIF_C_PROC_CTR_ENABLE); | |
1351 | rkisp1_hst_enable(params, NULL, false); | |
1352 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_AFM_CTRL, | |
1353 | RKISP1_CIF_ISP_AFM_ENA); | |
1354 | rkisp1_ie_enable(params, false); | |
1355 | rkisp1_param_clear_bits(params, RKISP1_CIF_ISP_DPF_MODE, | |
1356 | RKISP1_CIF_ISP_DPF_MODE_EN); | |
1357 | } | |
1358 | ||
1359 | static int rkisp1_params_enum_fmt_meta_out(struct file *file, void *priv, | |
1360 | struct v4l2_fmtdesc *f) | |
1361 | { | |
1362 | struct video_device *video = video_devdata(file); | |
1363 | struct rkisp1_params *params = video_get_drvdata(video); | |
1364 | ||
1365 | if (f->index > 0 || f->type != video->queue->type) | |
1366 | return -EINVAL; | |
1367 | ||
1368 | f->pixelformat = params->vdev_fmt.fmt.meta.dataformat; | |
1369 | ||
1370 | return 0; | |
1371 | } | |
1372 | ||
1373 | static int rkisp1_params_g_fmt_meta_out(struct file *file, void *fh, | |
1374 | struct v4l2_format *f) | |
1375 | { | |
1376 | struct video_device *video = video_devdata(file); | |
1377 | struct rkisp1_params *params = video_get_drvdata(video); | |
1378 | struct v4l2_meta_format *meta = &f->fmt.meta; | |
1379 | ||
1380 | if (f->type != video->queue->type) | |
1381 | return -EINVAL; | |
1382 | ||
1383 | memset(meta, 0, sizeof(*meta)); | |
1384 | meta->dataformat = params->vdev_fmt.fmt.meta.dataformat; | |
1385 | meta->buffersize = params->vdev_fmt.fmt.meta.buffersize; | |
1386 | ||
1387 | return 0; | |
1388 | } | |
1389 | ||
1390 | static int rkisp1_params_querycap(struct file *file, | |
1391 | void *priv, struct v4l2_capability *cap) | |
1392 | { | |
1393 | struct video_device *vdev = video_devdata(file); | |
1394 | ||
1395 | strscpy(cap->driver, RKISP1_DRIVER_NAME, sizeof(cap->driver)); | |
1396 | strscpy(cap->card, vdev->name, sizeof(cap->card)); | |
1397 | strscpy(cap->bus_info, RKISP1_BUS_INFO, sizeof(cap->bus_info)); | |
1398 | ||
1399 | return 0; | |
1400 | } | |
1401 | ||
1402 | /* ISP params video device IOCTLs */ | |
1403 | static const struct v4l2_ioctl_ops rkisp1_params_ioctl = { | |
1404 | .vidioc_reqbufs = vb2_ioctl_reqbufs, | |
1405 | .vidioc_querybuf = vb2_ioctl_querybuf, | |
1406 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | |
1407 | .vidioc_qbuf = vb2_ioctl_qbuf, | |
1408 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | |
1409 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, | |
1410 | .vidioc_expbuf = vb2_ioctl_expbuf, | |
1411 | .vidioc_streamon = vb2_ioctl_streamon, | |
1412 | .vidioc_streamoff = vb2_ioctl_streamoff, | |
1413 | .vidioc_enum_fmt_meta_out = rkisp1_params_enum_fmt_meta_out, | |
1414 | .vidioc_g_fmt_meta_out = rkisp1_params_g_fmt_meta_out, | |
1415 | .vidioc_s_fmt_meta_out = rkisp1_params_g_fmt_meta_out, | |
1416 | .vidioc_try_fmt_meta_out = rkisp1_params_g_fmt_meta_out, | |
1417 | .vidioc_querycap = rkisp1_params_querycap, | |
1418 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | |
1419 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | |
1420 | }; | |
1421 | ||
1422 | static int rkisp1_params_vb2_queue_setup(struct vb2_queue *vq, | |
1423 | unsigned int *num_buffers, | |
1424 | unsigned int *num_planes, | |
1425 | unsigned int sizes[], | |
1426 | struct device *alloc_devs[]) | |
1427 | { | |
1428 | struct rkisp1_params *params = vq->drv_priv; | |
1429 | ||
1430 | *num_buffers = clamp_t(u32, *num_buffers, | |
1431 | RKISP1_ISP_PARAMS_REQ_BUFS_MIN, | |
1432 | RKISP1_ISP_PARAMS_REQ_BUFS_MAX); | |
1433 | ||
1434 | *num_planes = 1; | |
1435 | ||
1436 | sizes[0] = sizeof(struct rkisp1_params_cfg); | |
1437 | ||
1438 | INIT_LIST_HEAD(¶ms->params); | |
1439 | params->is_first_params = true; | |
1440 | ||
1441 | return 0; | |
1442 | } | |
1443 | ||
1444 | static void rkisp1_params_vb2_buf_queue(struct vb2_buffer *vb) | |
1445 | { | |
1446 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); | |
1447 | struct rkisp1_buffer *params_buf = | |
1448 | container_of(vbuf, struct rkisp1_buffer, vb); | |
1449 | struct vb2_queue *vq = vb->vb2_queue; | |
1450 | struct rkisp1_params *params = vq->drv_priv; | |
1451 | struct rkisp1_params_cfg *new_params; | |
1452 | unsigned long flags; | |
1453 | unsigned int frame_sequence = | |
1454 | atomic_read(¶ms->rkisp1->isp.frame_sequence); | |
1455 | ||
1456 | if (params->is_first_params) { | |
1457 | new_params = (struct rkisp1_params_cfg *) | |
1458 | (vb2_plane_vaddr(vb, 0)); | |
1459 | vbuf->sequence = frame_sequence; | |
1460 | vb2_buffer_done(¶ms_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); | |
1461 | params->is_first_params = false; | |
1462 | params->cur_params = *new_params; | |
1463 | return; | |
1464 | } | |
1465 | ||
1466 | params_buf->vaddr[0] = vb2_plane_vaddr(vb, 0); | |
1467 | spin_lock_irqsave(¶ms->config_lock, flags); | |
1468 | list_add_tail(¶ms_buf->queue, ¶ms->params); | |
1469 | spin_unlock_irqrestore(¶ms->config_lock, flags); | |
1470 | } | |
1471 | ||
1472 | static int rkisp1_params_vb2_buf_prepare(struct vb2_buffer *vb) | |
1473 | { | |
1474 | if (vb2_plane_size(vb, 0) < sizeof(struct rkisp1_params_cfg)) | |
1475 | return -EINVAL; | |
1476 | ||
1477 | vb2_set_plane_payload(vb, 0, sizeof(struct rkisp1_params_cfg)); | |
1478 | ||
1479 | return 0; | |
1480 | } | |
1481 | ||
1482 | static void rkisp1_params_vb2_stop_streaming(struct vb2_queue *vq) | |
1483 | { | |
1484 | struct rkisp1_params *params = vq->drv_priv; | |
1485 | struct rkisp1_buffer *buf; | |
1486 | unsigned long flags; | |
1487 | unsigned int i; | |
1488 | ||
1489 | /* stop params input firstly */ | |
1490 | spin_lock_irqsave(¶ms->config_lock, flags); | |
1491 | params->is_streaming = false; | |
1492 | spin_unlock_irqrestore(¶ms->config_lock, flags); | |
1493 | ||
1494 | for (i = 0; i < RKISP1_ISP_PARAMS_REQ_BUFS_MAX; i++) { | |
1495 | spin_lock_irqsave(¶ms->config_lock, flags); | |
1496 | if (!list_empty(¶ms->params)) { | |
1497 | buf = list_first_entry(¶ms->params, | |
1498 | struct rkisp1_buffer, queue); | |
1499 | list_del(&buf->queue); | |
1500 | spin_unlock_irqrestore(¶ms->config_lock, | |
1501 | flags); | |
1502 | } else { | |
1503 | spin_unlock_irqrestore(¶ms->config_lock, | |
1504 | flags); | |
1505 | break; | |
1506 | } | |
1507 | ||
1508 | if (buf) | |
1509 | vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); | |
1510 | buf = NULL; | |
1511 | } | |
1512 | } | |
1513 | ||
1514 | static int | |
1515 | rkisp1_params_vb2_start_streaming(struct vb2_queue *queue, unsigned int count) | |
1516 | { | |
1517 | struct rkisp1_params *params = queue->drv_priv; | |
1518 | unsigned long flags; | |
1519 | ||
1520 | spin_lock_irqsave(¶ms->config_lock, flags); | |
1521 | params->is_streaming = true; | |
1522 | spin_unlock_irqrestore(¶ms->config_lock, flags); | |
1523 | ||
1524 | return 0; | |
1525 | } | |
1526 | ||
1527 | static struct vb2_ops rkisp1_params_vb2_ops = { | |
1528 | .queue_setup = rkisp1_params_vb2_queue_setup, | |
1529 | .wait_prepare = vb2_ops_wait_prepare, | |
1530 | .wait_finish = vb2_ops_wait_finish, | |
1531 | .buf_queue = rkisp1_params_vb2_buf_queue, | |
1532 | .buf_prepare = rkisp1_params_vb2_buf_prepare, | |
1533 | .start_streaming = rkisp1_params_vb2_start_streaming, | |
1534 | .stop_streaming = rkisp1_params_vb2_stop_streaming, | |
1535 | ||
1536 | }; | |
1537 | ||
1538 | static struct v4l2_file_operations rkisp1_params_fops = { | |
1539 | .mmap = vb2_fop_mmap, | |
1540 | .unlocked_ioctl = video_ioctl2, | |
1541 | .poll = vb2_fop_poll, | |
1542 | .open = v4l2_fh_open, | |
1543 | .release = vb2_fop_release | |
1544 | }; | |
1545 | ||
1546 | static int rkisp1_params_init_vb2_queue(struct vb2_queue *q, | |
1547 | struct rkisp1_params *params) | |
1548 | { | |
1549 | struct rkisp1_vdev_node *node; | |
1550 | ||
1551 | node = container_of(q, struct rkisp1_vdev_node, buf_queue); | |
1552 | ||
1553 | q->type = V4L2_BUF_TYPE_META_OUTPUT; | |
1554 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; | |
1555 | q->drv_priv = params; | |
1556 | q->ops = &rkisp1_params_vb2_ops; | |
1557 | q->mem_ops = &vb2_vmalloc_memops; | |
1558 | q->buf_struct_size = sizeof(struct rkisp1_buffer); | |
1559 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | |
1560 | q->lock = &node->vlock; | |
1561 | ||
1562 | return vb2_queue_init(q); | |
1563 | } | |
1564 | ||
1565 | static void rkisp1_init_params(struct rkisp1_params *params) | |
1566 | { | |
1567 | params->vdev_fmt.fmt.meta.dataformat = | |
1568 | V4L2_META_FMT_RK_ISP1_PARAMS; | |
1569 | params->vdev_fmt.fmt.meta.buffersize = | |
1570 | sizeof(struct rkisp1_params_cfg); | |
1571 | } | |
1572 | ||
1573 | int rkisp1_params_register(struct rkisp1_params *params, | |
1574 | struct v4l2_device *v4l2_dev, | |
1575 | struct rkisp1_device *rkisp1) | |
1576 | { | |
1577 | struct rkisp1_vdev_node *node = ¶ms->vnode; | |
1578 | struct video_device *vdev = &node->vdev; | |
1579 | int ret; | |
1580 | ||
1581 | params->rkisp1 = rkisp1; | |
1582 | mutex_init(&node->vlock); | |
1583 | spin_lock_init(¶ms->config_lock); | |
1584 | ||
1585 | strscpy(vdev->name, RKISP1_PARAMS_DEV_NAME, sizeof(vdev->name)); | |
1586 | ||
1587 | video_set_drvdata(vdev, params); | |
1588 | vdev->ioctl_ops = &rkisp1_params_ioctl; | |
1589 | vdev->fops = &rkisp1_params_fops; | |
1590 | vdev->release = video_device_release_empty; | |
1591 | /* | |
1592 | * Provide a mutex to v4l2 core. It will be used | |
1593 | * to protect all fops and v4l2 ioctls. | |
1594 | */ | |
1595 | vdev->lock = &node->vlock; | |
1596 | vdev->v4l2_dev = v4l2_dev; | |
1597 | vdev->queue = &node->buf_queue; | |
1598 | vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_META_OUTPUT; | |
1599 | vdev->vfl_dir = VFL_DIR_TX; | |
1600 | rkisp1_params_init_vb2_queue(vdev->queue, params); | |
1601 | rkisp1_init_params(params); | |
1602 | video_set_drvdata(vdev, params); | |
1603 | ||
1604 | node->pad.flags = MEDIA_PAD_FL_SOURCE; | |
1605 | ret = media_entity_pads_init(&vdev->entity, 1, &node->pad); | |
1606 | if (ret) | |
1607 | goto err_release_queue; | |
0e17c50f | 1608 | ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); |
bae1155c JC |
1609 | if (ret) { |
1610 | dev_err(&vdev->dev, | |
1611 | "failed to register %s, ret=%d\n", vdev->name, ret); | |
1612 | goto err_cleanup_media_entity; | |
1613 | } | |
1614 | return 0; | |
1615 | err_cleanup_media_entity: | |
1616 | media_entity_cleanup(&vdev->entity); | |
1617 | err_release_queue: | |
1618 | vb2_queue_release(vdev->queue); | |
1619 | return ret; | |
1620 | } | |
1621 | ||
1622 | void rkisp1_params_unregister(struct rkisp1_params *params) | |
1623 | { | |
1624 | struct rkisp1_vdev_node *node = ¶ms->vnode; | |
1625 | struct video_device *vdev = &node->vdev; | |
1626 | ||
1627 | video_unregister_device(vdev); | |
1628 | media_entity_cleanup(&vdev->entity); | |
1629 | vb2_queue_release(vdev->queue); | |
1630 | } |