• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Copyright (C) 2011-2018 ARM or its affiliates
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 as published by
9 * the Free Software Foundation; version 2.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19 
20 #include <linux/version.h>
21 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
22 #include <linux/ktime.h>
23 #include <linux/time64.h>
24 #include <linux/timekeeping.h>
25 #endif
26 #include <linux/module.h>
27 #include "acamera_fw.h"
28 #include "acamera_math.h"
29 #include "acamera_math.h"
30 #include "acamera_isp_config.h"
31 #include "system_timer.h"
32 
33 #include "acamera_logger.h"
34 #include "sensor_fsm.h"
35 
36 #include "acamera.h"
37 
38 #if USER_MODULE
39 #include "sbuf.h"
40 #endif
41 
42 typedef struct {
43     uint16_t active_width;
44     uint16_t active_height;
45     uint16_t total_width;
46     uint16_t total_height;
47     uint16_t offset_x;
48     uint16_t offset_y;
49     uint16_t h_front_porch;
50     uint16_t v_front_porch;
51     uint16_t h_sync_width;
52     uint16_t v_sync_width;
53 } dvi_sync_param_t;
54 
55 
56 #ifdef LOG_MODULE
57 #undef LOG_MODULE
58 #define LOG_MODULE LOG_MODULE_SENSOR
59 #endif
60 
61 unsigned int temper3_4k = 0;
62 module_param(temper3_4k, uint, 0664);
63 MODULE_PARM_DESC(temper3_4k, "\n temper3 4k enable\n");
64 
sensor_init_output(sensor_fsm_ptr_t p_fsm,int mode)65 void sensor_init_output( sensor_fsm_ptr_t p_fsm, int mode )
66 {
67     const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
68     if ( ( mode != 720 ) && ( mode != 1080 ) ) {
69         if ( param->active.height >= 1080 ) {
70             mode = 1080;
71         } else {
72             mode = 720;
73         }
74     }
75 
76     // decrease output mode to 720p if active_height < mode
77     if ( mode > param->active.height )
78         mode = 720;
79 
80     p_fsm->isp_output_mode = mode;
81 }
82 
83 ///////////////////////////////////////////////////////////////////////////////
84 
sensor_boot_init(sensor_fsm_ptr_t p_fsm)85 uint32_t sensor_boot_init( sensor_fsm_ptr_t p_fsm )
86 {
87     ACAMERA_FSM2CTX_PTR( p_fsm )
88         ->settings.sensor_init( &p_fsm->sensor_ctx, &p_fsm->ctrl );
89 
90 
91 #if USER_MODULE
92     uint32_t idx = 0;
93     sensor_param_t *param = (sensor_param_t *)p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
94     struct sensor_info ksensor_info;
95     acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_KSENSOR_INFO, NULL, 0, &ksensor_info, sizeof( ksensor_info ) );
96 
97     param->modes_num = ksensor_info.modes_num;
98     if ( param->modes_num > ISP_MAX_SENSOR_MODES ) {
99         param->modes_num = ISP_MAX_SENSOR_MODES;
100     }
101 
102     for ( idx = 0; idx < param->modes_num; idx++ ) {
103         param->modes_table[idx] = ksensor_info.modes[idx];
104     }
105 #endif
106 
107     return 0;
108 }
109 
sensor_hw_init(sensor_fsm_ptr_t p_fsm)110 void sensor_hw_init( sensor_fsm_ptr_t p_fsm )
111 {
112 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
113     struct timeval  txs,txe;
114     do_gettimeofday(&txs);
115 #endif
116 
117 #if FW_DO_INITIALIZATION
118 	if(p_fsm->p_fsm_mgr->isp_seamless == 0)
119 		acamera_isp_input_port_mode_request_write( p_fsm->cmn.isp_base, ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_STOP ); // urgent stop
120 #endif                                                                                                               //FW_DO_INITIALIZATION
121 
122     // 1): set sensor to preset_mode as required.
123 	if(p_fsm->p_fsm_mgr->isp_seamless)
124 	{
125 		if(acamera_isp_input_port_mode_status_read( 0 ) != ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_START)
126 			p_fsm->ctrl.set_mode( p_fsm->sensor_ctx, p_fsm->preset_mode );
127 	}
128 	else
129 		p_fsm->ctrl.set_mode( p_fsm->sensor_ctx, p_fsm->preset_mode );
130     p_fsm->ctrl.disable_sensor_isp( p_fsm->sensor_ctx );
131 
132 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
133     do_gettimeofday(&txe);
134 	LOG( LOG_INFO, "sensor_hw_init:%d", (txe.tv_sec*1000000+txe.tv_usec) -  (txs.tv_sec*1000000+txs.tv_usec));
135 #endif
136 
137     // 2): set to wdr_mode through general router (wdr_mode changed in sensor param in 1st step).
138     const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
139 
140     fsm_param_set_wdr_param_t set_wdr_param;
141     set_wdr_param.wdr_mode = param->modes_table[param->mode].wdr_mode;
142     set_wdr_param.exp_number = param->modes_table[param->mode].exposures;
143 	if(p_fsm->p_fsm_mgr->isp_seamless)
144 	{
145 		if(acamera_isp_input_port_mode_status_read( 0 ) == ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_START)
146 		{
147 			if((param->modes_table[p_fsm->preset_mode].exposures == 2 && set_wdr_param.exp_number == 1) ||
148 				(param->modes_table[p_fsm->preset_mode].exposures == 1 && set_wdr_param.exp_number == 2) ||
149 				(param->modes_table[p_fsm->preset_mode].exposures == 1 && set_wdr_param.exp_number == 3))
150 			{
151 					LOG(LOG_CRIT, "preset not match user mode, execute switch and close seamless");
152 					p_fsm->ctrl.set_mode( p_fsm->sensor_ctx, p_fsm->preset_mode );
153 					p_fsm->p_fsm_mgr->isp_seamless = 0;
154 			}
155 			if(param->modes_table[p_fsm->preset_mode].exposures != set_wdr_param.exp_number)
156 			{
157 				set_wdr_param.wdr_mode = param->modes_table[p_fsm->preset_mode].wdr_mode;
158 				set_wdr_param.exp_number = param->modes_table[p_fsm->preset_mode].exposures;
159 			}
160 		}
161 	}
162     acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_WDR_MODE, &set_wdr_param, sizeof( set_wdr_param ) );
163     // 3): Init or update the calibration data.
164     acamera_init_calibrations( ACAMERA_FSM2CTX_PTR( p_fsm ), ((sensor_param_t *)(p_fsm->sensor_ctx))->s_name.name );
165 
166     // 4). update new settings to ISP if necessary
167     //acamera_update_cur_settings_to_isp(0xff);
168 }
169 
sensor_configure_buffers(sensor_fsm_ptr_t p_fsm)170 void sensor_configure_buffers( sensor_fsm_ptr_t p_fsm )
171 {
172 #if ISP_HAS_TEMPER
173     acamera_isp_temper_enable_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 0 );
174     aframe_t *temper_frames = ACAMERA_FSM2CTX_PTR( p_fsm )->settings.temper_frames;
175     uint32_t temper_frames_num = ACAMERA_FSM2CTX_PTR( p_fsm )->settings.temper_frames_number;
176     uint32_t temper_frame_size = acamera_isp_top_active_width_read( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base ) * acamera_isp_top_active_height_read( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base ) * 4;
177     if ( temper_frames != NULL && temper_frames_num != 0 && ( ( temper_frames_num > 1 ) ? ( temper_frames[0].size + temper_frames[1].size >= temper_frame_size * 2 ) : ( temper_frames[0].size >= temper_frame_size ) ) ) {
178         if ( temper_frames_num == 1 ) {
179             acamera_isp_temper_dma_lsb_bank_base_reader_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[0].address );
180             acamera_isp_temper_dma_lsb_bank_base_writer_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[0].address );
181             acamera_isp_temper_temper2_mode_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 1 ); //temper 2
182         } else {
183             // temper3 has lsb and msb parts
184             acamera_isp_temper_dma_lsb_bank_base_reader_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[0].address );
185             acamera_isp_temper_dma_lsb_bank_base_writer_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[0].address );
186             acamera_isp_temper_dma_msb_bank_base_reader_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[1].address );
187             acamera_isp_temper_dma_msb_bank_base_writer_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[1].address );
188             acamera_isp_temper_temper2_mode_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 0 ); //temper 3
189         }
190         acamera_isp_temper_dma_line_offset_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, temper_frames[0].line_offset);
191         acamera_isp_temper_enable_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 1 );
192         acamera_isp_temper_dma_frame_write_on_lsb_dma_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 1 );
193         acamera_isp_temper_dma_frame_read_on_lsb_dma_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 1 );
194 
195     } else {
196         acamera_isp_temper_enable_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 0 );
197         acamera_isp_temper_dma_frame_write_on_lsb_dma_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 0 );
198         acamera_isp_temper_dma_frame_read_on_lsb_dma_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 0 );
199         LOG( LOG_ERR, "No output buffers for temper block provided in settings. Temper is disabled" );
200     }
201 
202     if ( temper3_4k == 0 )
203     {
204         const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
205         if ( param->modes_table[p_fsm->preset_mode].resolution.width > 1920 &&  param->modes_table[p_fsm->preset_mode].resolution.height > 1080 )
206         {
207             LOG(LOG_CRIT, "Resolution: %dx%d > 1080P, close temper3",param->modes_table[p_fsm->preset_mode].resolution.width ,param->modes_table[p_fsm->preset_mode].resolution.height);
208             acamera_isp_temper_temper2_mode_write( ACAMERA_FSM2CTX_PTR( p_fsm )->settings.isp_base, 1 );
209         }
210     }
211 #endif
212 }
213 
sensor_check_mirror_bayer(sensor_fsm_ptr_t p_fsm)214 static void sensor_check_mirror_bayer(sensor_fsm_ptr_t p_fsm)
215 {
216     uint8_t mirror_bypass = acamera_isp_top_bypass_mirror_read(p_fsm->cmn.isp_base);
217 
218     if (mirror_bypass == 1)
219         return;
220 
221     uint8_t bayer = acamera_isp_top_rggb_start_post_mirror_read(p_fsm->cmn.isp_base);
222     if (bayer == BAYER_RGGB)
223         acamera_isp_top_rggb_start_post_mirror_write( p_fsm->cmn.isp_base, BAYER_GRBG );
224     else if (bayer == BAYER_GRBG)
225         acamera_isp_top_rggb_start_post_mirror_write( p_fsm->cmn.isp_base, BAYER_RGGB );
226     else if (bayer == BAYER_GBRG)
227         acamera_isp_top_rggb_start_post_mirror_write( p_fsm->cmn.isp_base, BAYER_BGGR );
228     else if (bayer == BAYER_BGGR)
229         acamera_isp_top_rggb_start_post_mirror_write( p_fsm->cmn.isp_base, BAYER_GBRG );
230 }
231 
sensor_update_bayer_bits(sensor_fsm_ptr_t p_fsm)232 static void sensor_update_bayer_bits(sensor_fsm_ptr_t p_fsm)
233 {
234     const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
235     uint8_t isp_bayer = param->bayer;
236     uint8_t bits = param->modes_table[p_fsm->preset_mode].bits;
237     uint8_t isp_bit_width = 1;
238 
239     switch (bits) {
240     case 8:
241         isp_bit_width = 0;
242         break;
243     case 10:
244         isp_bit_width = 1;
245         break;
246     case 12:
247         isp_bit_width = 2;
248         break;
249     case 14:
250         isp_bit_width = 3;
251         break;
252     case 16:
253         isp_bit_width = 4;
254         break;
255     case 20:
256         isp_bit_width = 5;
257         break;
258     default:
259         LOG(LOG_ERR, "Error input bits\n");
260         break;
261     }
262 
263     acamera_isp_top_rggb_start_pre_mirror_write(p_fsm->cmn.isp_base, isp_bayer);
264     acamera_isp_top_rggb_start_post_mirror_write(p_fsm->cmn.isp_base, isp_bayer);
265     acamera_isp_input_formatter_input_bitwidth_select_write(p_fsm->cmn.isp_base, isp_bit_width);
266 
267     sensor_check_mirror_bayer(p_fsm);
268 }
269 
270 
sensor_sw_init(sensor_fsm_ptr_t p_fsm)271 void sensor_sw_init( sensor_fsm_ptr_t p_fsm )
272 {
273     const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
274 
275 #if FW_DO_INITIALIZATION
276 	if(p_fsm->p_fsm_mgr->isp_seamless == 0){
277 	    /* sensor resolution */
278 	    acamera_isp_top_active_width_write( p_fsm->cmn.isp_base, param->active.width );
279 	    acamera_isp_top_active_height_write( p_fsm->cmn.isp_base, param->active.height );
280 
281 	    acamera_isp_metering_af_active_width_write(p_fsm->cmn.isp_base, param->active.width);
282 	    acamera_isp_metering_af_active_height_write(p_fsm->cmn.isp_base, param->active.height);
283 
284 		acamera_isp_lumvar_active_width_write(p_fsm->cmn.isp_base, param->active.width);
285 		acamera_isp_lumvar_active_height_write(p_fsm->cmn.isp_base, param->active.height);
286 
287 		acamera_isp_input_port_hc_size0_write( p_fsm->cmn.isp_base, param->active.width );
288 		acamera_isp_input_port_hc_size1_write( p_fsm->cmn.isp_base, param->active.width );
289 		acamera_isp_input_port_vc_size_write( p_fsm->cmn.isp_base, param->active.height );
290 
291 	    sensor_init_output( p_fsm, p_fsm->isp_output_mode );
292 	}
293 #endif //FW_DO_INITIALIZATION
294 
295     //acamera_isp_input_port_mode_request_write( p_fsm->cmn.isp_base, ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_START );
296 
297     sensor_update_black( p_fsm );
298 
299     sensor_update_bayer_bits(p_fsm);
300 
301 	if(p_fsm->p_fsm_mgr->isp_seamless)
302 	{
303 		if(acamera_isp_input_port_mode_status_read( 0 ) != ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_START)
304 		{
305 			acamera_reset_ping_pong_port();
306 			acamera_update_cur_settings_to_isp(ISP_CONFIG_PING);
307 		}
308 	}
309 	else
310 	{
311 		acamera_reset_ping_pong_port();
312 		acamera_update_cur_settings_to_isp(ISP_CONFIG_PING);
313 	}
314     LOG( LOG_NOTICE, "Sensor initialization is complete, ID 0x%04X resolution %dx%d", p_fsm->ctrl.get_id( p_fsm->sensor_ctx ), param->active.width, param->active.height );
315 }
316 
sqrt_ext_param_update(sensor_fsm_ptr_t p_fsm)317 static void sqrt_ext_param_update(sensor_fsm_ptr_t p_fsm)
318 {
319     int32_t rtn = 0;
320     int32_t t_gain = 0;
321     struct sqrt_ext_param_t p_result;
322     fsm_ext_param_ctrl_t p_ctrl;
323 
324     acamera_fsm_mgr_get_param(p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_CMOS_TOTAL_GAIN, NULL, 0, &t_gain, sizeof(t_gain));
325 
326     p_ctrl.ctx = (void *)(ACAMERA_FSM2CTX_PTR(p_fsm));
327     p_ctrl.id = CALIBRATION_SQRT_EXT_CONTROL;
328     p_ctrl.total_gain = t_gain;
329     p_ctrl.result = (void *)&p_result;
330 
331     rtn = acamera_extern_param_calculate(&p_ctrl);
332     if (rtn != 0) {
333         LOG(LOG_CRIT, "Failed to calculate sqrt ext");
334         return;
335     }
336 
337     acamera_isp_sqrt_black_level_in_write(p_fsm->cmn.isp_base, p_result.black_level_in);
338     acamera_isp_sqrt_black_level_out_write(p_fsm->cmn.isp_base, p_result.black_level_out);
339 }
340 
square_be_ext_param_update(sensor_fsm_ptr_t p_fsm)341 static void square_be_ext_param_update(sensor_fsm_ptr_t p_fsm)
342 {
343     int32_t rtn = 0;
344     int32_t t_gain = 0;
345     struct square_be_ext_param_t p_result;
346     fsm_ext_param_ctrl_t p_ctrl;
347 
348     acamera_fsm_mgr_get_param(p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_CMOS_TOTAL_GAIN, NULL, 0, &t_gain, sizeof(t_gain));
349 
350     p_ctrl.ctx = (void *)(ACAMERA_FSM2CTX_PTR(p_fsm));
351     p_ctrl.id = CALIBRATION_SQUARE_BE_EXT_CONTROL;
352     p_ctrl.total_gain = t_gain;
353     p_ctrl.result = (void *)&p_result;
354 
355     rtn = acamera_extern_param_calculate(&p_ctrl);
356     if (rtn != 0) {
357         LOG(LOG_CRIT, "Failed to square be ext");
358         return;
359     }
360 
361     acamera_isp_square_be_black_level_in_write(p_fsm->cmn.isp_base, p_result.black_level_in);
362     acamera_isp_square_be_black_level_out_write(p_fsm->cmn.isp_base, p_result.black_level_out);
363 }
364 
sensor_update_black(sensor_fsm_ptr_t p_fsm)365 void sensor_update_black( sensor_fsm_ptr_t p_fsm )
366 {
367     int32_t stub = 0;
368     exposure_set_t exp;
369 
370     acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_FRAME_EXPOSURE_SET, &stub, sizeof( stub ), &exp, sizeof( exp ) );
371 
372     uint16_t again_log2 = ( uint16_t )( exp.info.again_log2 >> ( LOG2_GAIN_SHIFT - 5 ) ); // makes again in format log2(gain)*32
373     uint32_t wdr_mode = 0;
374 
375     acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_WDR_MODE, NULL, 0, &wdr_mode, sizeof( wdr_mode ) );
376     uint32_t idx_r = CALIBRATION_BLACK_LEVEL_R;
377     uint32_t idx_b = CALIBRATION_BLACK_LEVEL_B;
378     uint32_t idx_gr = CALIBRATION_BLACK_LEVEL_GR;
379     uint32_t idx_gb = CALIBRATION_BLACK_LEVEL_GB;
380     uint32_t r = acamera_calc_modulation_u16( again_log2, _GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_r ), _GET_ROWS( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_r ) );
381     uint32_t b = acamera_calc_modulation_u16( again_log2, _GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_b ), _GET_ROWS( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_b ) );
382     uint32_t gr = acamera_calc_modulation_u16( again_log2, _GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gr ), _GET_ROWS( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gr ) );
383     uint32_t gb = acamera_calc_modulation_u16( again_log2, _GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gb ), _GET_ROWS( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gb ) );
384 
385     p_fsm->black_level = r;
386 
387     if ( wdr_mode == WDR_MODE_FS_LIN ) {
388         if ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_manual_frame_stitch == 0 ) {
389             acamera_isp_frame_stitch_black_level_long_write( p_fsm->cmn.isp_base, p_fsm->black_level );
390             acamera_isp_frame_stitch_black_level_medium_write( p_fsm->cmn.isp_base, p_fsm->black_level );
391             acamera_isp_frame_stitch_black_level_short_write( p_fsm->cmn.isp_base, p_fsm->black_level );
392             acamera_isp_frame_stitch_black_level_very_short_write( p_fsm->cmn.isp_base, p_fsm->black_level );
393             acamera_isp_frame_stitch_black_level_out_write( p_fsm->cmn.isp_base, p_fsm->black_level << BLACK_LEVEL_SHIFT_DG );
394         }
395 
396         if ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_manual_black_level == 0 ) {
397             acamera_isp_sensor_offset_pre_shading_offset_00_write( p_fsm->cmn.isp_base, (uint32_t)_GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_r )->y << BLACK_LEVEL_SHIFT_WB );
398             acamera_isp_sensor_offset_pre_shading_offset_01_write( p_fsm->cmn.isp_base, (uint32_t)_GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gr )->y << BLACK_LEVEL_SHIFT_WB );
399             acamera_isp_sensor_offset_pre_shading_offset_10_write( p_fsm->cmn.isp_base, (uint32_t)_GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gb )->y << BLACK_LEVEL_SHIFT_WB );
400             acamera_isp_sensor_offset_pre_shading_offset_11_write( p_fsm->cmn.isp_base, (uint32_t)_GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_b )->y << BLACK_LEVEL_SHIFT_WB );
401 
402             sqrt_ext_param_update(p_fsm);
403             square_be_ext_param_update(p_fsm);
404         }
405 
406         acamera_isp_digital_gain_offset_write( p_fsm->cmn.isp_base, (uint32_t)_GET_MOD_ENTRY16_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), idx_gr )->y << BLACK_LEVEL_SHIFT_DG );
407     } else {
408         if ( ACAMERA_FSM2CTX_PTR( p_fsm )->stab.global_manual_black_level == 0 ) {
409             acamera_isp_sensor_offset_pre_shading_offset_00_write( p_fsm->cmn.isp_base, r << BLACK_LEVEL_SHIFT_WB );
410             acamera_isp_sensor_offset_pre_shading_offset_01_write( p_fsm->cmn.isp_base, gr << BLACK_LEVEL_SHIFT_WB );
411             acamera_isp_sensor_offset_pre_shading_offset_10_write( p_fsm->cmn.isp_base, gb << BLACK_LEVEL_SHIFT_WB );
412             acamera_isp_sensor_offset_pre_shading_offset_11_write( p_fsm->cmn.isp_base, b << BLACK_LEVEL_SHIFT_WB );
413 
414             sqrt_ext_param_update(p_fsm);
415             square_be_ext_param_update(p_fsm);
416         }
417 
418         acamera_isp_digital_gain_offset_write( p_fsm->cmn.isp_base, (uint32_t)p_fsm->black_level << BLACK_LEVEL_SHIFT_DG );
419     }
420 }
421 
sensor_get_lines_second(sensor_fsm_ptr_t p_fsm)422 uint32_t sensor_get_lines_second( sensor_fsm_ptr_t p_fsm )
423 {
424     const sensor_param_t *param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
425     return param->lines_per_second;
426 }
427 
sensor_deinit(sensor_fsm_ptr_t p_fsm)428 void sensor_deinit( sensor_fsm_ptr_t p_fsm )
429 {
430     ACAMERA_FSM2CTX_PTR( p_fsm )
431         ->settings.sensor_deinit( p_fsm->sensor_ctx );
432 }
433