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 "acamera_fw.h"
21 #include "general_fsm.h"
22
23 #ifdef LOG_MODULE
24 #undef LOG_MODULE
25 #define LOG_MODULE LOG_MODULE_GENERAL
26 #endif
27
general_fsm_clear(general_fsm_t * p_fsm)28 void general_fsm_clear( general_fsm_t *p_fsm )
29 {
30 p_fsm->api_reg_addr = 0;
31 p_fsm->api_reg_size = 8;
32 p_fsm->api_reg_source = 0;
33 p_fsm->calibration_read_status = 0;
34 p_fsm->wdr_mode = ISP_WDR_DEFAULT_MODE;
35
36 #if ISP_WDR_SWITCH
37 p_fsm->wdr_mode_req = ISP_WDR_DEFAULT_MODE;
38 p_fsm->wdr_auto_mode = 0;
39 p_fsm->wdr_mode_frames = 0;
40 p_fsm->cur_exp_number = SENSOR_DEFAULT_EXP_NUM;
41 #endif
42 }
43
general_request_interrupt(general_fsm_ptr_t p_fsm,system_fw_interrupt_mask_t mask)44 void general_request_interrupt( general_fsm_ptr_t p_fsm, system_fw_interrupt_mask_t mask )
45 {
46 acamera_isp_interrupts_disable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
47 p_fsm->mask.irq_mask |= mask;
48 acamera_isp_interrupts_enable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
49 }
50
general_fsm_init(void * fsm,fsm_init_param_t * init_param)51 void general_fsm_init( void *fsm, fsm_init_param_t *init_param )
52 {
53 general_fsm_t *p_fsm = (general_fsm_t *)fsm;
54 p_fsm->cmn.p_fsm_mgr = init_param->p_fsm_mgr;
55 p_fsm->cmn.isp_base = init_param->isp_base;
56 p_fsm->p_fsm_mgr = init_param->p_fsm_mgr;
57
58 general_initialize( p_fsm );
59 }
60
general_set_reg_value(general_fsm_t * p_fsm,uint32_t value)61 static int general_set_reg_value( general_fsm_t *p_fsm, uint32_t value )
62 {
63 int rc = 0;
64
65 #if REGISTERS_SOURCE_ID
66 switch ( p_fsm->api_reg_source ) {
67 case ISP:
68 switch ( p_fsm->api_reg_size ) {
69 case 8:
70 acamera_sbus_write_u8( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr, value );
71 break;
72 case 16:
73 acamera_sbus_write_u16( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr, value );
74 break;
75 case 32:
76 acamera_sbus_write_u32( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr, value );
77 break;
78 default:
79 rc = -1;
80 break;
81 }
82
83 break;
84
85 case SENSOR: {
86 fsm_param_reg_cfg_t reg_cfg;
87 reg_cfg.reg_addr = p_fsm->api_reg_addr;
88 reg_cfg.reg_value = value;
89 rc = acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_SENSOR_REG, ®_cfg, sizeof( reg_cfg ) );
90 break;
91 }
92
93 #if defined( ISP_HAS_AF_LMS_FSM ) || defined( ISP_HAS_AF_MANUAL_FSM )
94 case LENS: {
95 fsm_param_reg_cfg_t reg_cfg;
96 reg_cfg.reg_addr = p_fsm->api_reg_addr;
97 reg_cfg.reg_value = value;
98 rc = acamera_fsm_mgr_set_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_SET_AF_LENS_REG, ®_cfg, sizeof( reg_cfg ) );
99 break;
100 }
101 #endif
102
103 default:
104 rc = -1;
105 break;
106 }
107 #endif
108
109 return rc;
110 }
111
general_fsm_set_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size)112 int general_fsm_set_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size )
113 {
114 int rc = 0;
115 general_fsm_t *p_fsm = (general_fsm_t *)fsm;
116
117 switch ( param_id ) {
118 case FSM_PARAM_SET_RELOAD_CALIBRATION:
119 acamera_reload_isp_calibratons( p_fsm );
120 break;
121
122 case FSM_PARAM_SET_WDR_MODE: {
123
124 if ( !input || input_size != sizeof( fsm_param_set_wdr_param_t ) ) {
125 LOG( LOG_ERR, "Inavlid param, param_id: %d.", param_id );
126 rc = -1;
127 break;
128 }
129
130 fsm_param_set_wdr_param_t *wdr_param = (fsm_param_set_wdr_param_t *)input;
131
132 #if ISP_WDR_SWITCH
133 p_fsm->wdr_mode_req = wdr_param->wdr_mode;
134
135 if ( ( p_fsm->wdr_mode_req != p_fsm->wdr_mode ) || ( p_fsm->cur_exp_number != wdr_param->exp_number ) ) {
136 p_fsm->wdr_mode = p_fsm->wdr_mode_req;
137 p_fsm->cur_exp_number = wdr_param->exp_number;
138
139 general_set_wdr_mode( p_fsm );
140
141 p_fsm->wdr_mode_frames = 0;
142 }
143 #else
144 p_fsm->wdr_mode = wdr_param->wdr_mode;
145 #endif
146 break;
147 }
148
149 case FSM_PARAM_SET_REG_SETTING: {
150 if ( !input || input_size != sizeof( fsm_param_reg_setting_t ) ) {
151 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
152 rc = -1;
153 break;
154 }
155
156 fsm_param_reg_setting_t *p_input = (fsm_param_reg_setting_t *)input;
157
158 if ( p_input->flag & REG_SETTING_BIT_REG_ADDR ) {
159 p_fsm->api_reg_addr = p_input->api_reg_addr;
160 }
161
162 if ( p_input->flag & REG_SETTING_BIT_REG_SIZE ) {
163 p_fsm->api_reg_size = p_input->api_reg_size;
164 }
165
166 if ( p_input->flag & REG_SETTING_BIT_REG_SOURCE ) {
167 p_fsm->api_reg_source = p_input->api_reg_source;
168 }
169
170 if ( p_input->flag & REG_SETTING_BIT_REG_VALUE ) {
171 rc = general_set_reg_value( p_fsm, p_input->api_reg_value );
172 }
173 break;
174 }
175
176 case FSM_PARAM_SET_SCENE_MODE:
177 if ( !input || input_size != sizeof( uint32_t ) ) {
178 LOG( LOG_ERR, "Inavlid param, param_id: %d.", param_id );
179 rc = -1;
180 break;
181 }
182
183 p_fsm->api_scene_mode = *(uint32_t *)input;
184
185 break;
186
187 default:
188 rc = -1;
189 break;
190 }
191
192 return rc;
193 }
194
general_get_reg_value(general_fsm_t * p_fsm,uint32_t * value)195 static int general_get_reg_value( general_fsm_t *p_fsm, uint32_t *value )
196 {
197 int rc = 0;
198
199 #if REGISTERS_SOURCE_ID
200 switch ( p_fsm->api_reg_source ) {
201 case ISP:
202 switch ( p_fsm->api_reg_size ) {
203 case 8:
204 *value = acamera_sbus_read_u8( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr );
205 break;
206 case 16:
207 *value = acamera_sbus_read_u16( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr );
208 break;
209 case 32:
210 *value = acamera_sbus_read_u32( &( p_fsm->isp_sbus ), p_fsm->api_reg_addr );
211 break;
212 default:
213 *value = ERR_BAD_ARGUMENT;
214 rc = -1;
215 break;
216 }
217
218 break;
219
220 case SENSOR:
221 rc = acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_SENSOR_REG, &p_fsm->api_reg_addr, sizeof( p_fsm->api_reg_addr ), value, sizeof( uint32_t ) );
222 break;
223
224 #if defined( ISP_HAS_AF_LMS_FSM ) || defined( ISP_HAS_AF_MANUAL_FSM )
225 case LENS:
226 rc = acamera_fsm_mgr_get_param( p_fsm->cmn.p_fsm_mgr, FSM_PARAM_GET_AF_LENS_REG, &p_fsm->api_reg_addr, sizeof( p_fsm->api_reg_addr ), value, sizeof( uint32_t ) );
227 break;
228 #endif
229
230 default:
231 *value = ERR_BAD_ARGUMENT;
232 rc = -1;
233 break;
234 }
235 #endif
236
237 return rc;
238 }
239
general_fsm_get_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size,void * output,uint32_t output_size)240 int general_fsm_get_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size, void *output, uint32_t output_size )
241 {
242 int rc = 0;
243 general_fsm_t *p_fsm = (general_fsm_t *)fsm;
244
245 switch ( param_id ) {
246 case FSM_PARAM_GET_WDR_MODE:
247
248 if ( !output || output_size != sizeof( uint32_t ) ) {
249 LOG( LOG_ERR, "Inavlid param, param_id: %d.", param_id );
250 rc = -1;
251 break;
252 }
253
254 *(uint32_t *)output = p_fsm->wdr_mode;
255
256 break;
257
258 case FSM_PARAM_GET_CALC_FE_LUT_OUTPUT:
259
260 if ( !input || input_size != sizeof( uint32_t ) ||
261 !output || output_size != sizeof( uint32_t ) ) {
262 LOG( LOG_ERR, "Inavlid param, param_id: %d.", param_id );
263 rc = -1;
264 break;
265 }
266
267 // Based on old code, the input param is an uint32_t, but in function we just used uint16_t.
268 *(uint32_t *)output = general_calc_fe_lut_output( p_fsm, *(uint16_t *)input );
269
270 break;
271
272 case FSM_PARAM_GET_REG_SETTING: {
273 if ( !input || input_size != sizeof( fsm_param_reg_setting_t ) ||
274 !output || output_size != sizeof( fsm_param_reg_setting_t ) ) {
275 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
276 rc = -1;
277 break;
278 }
279
280 fsm_param_reg_setting_t *p_input = (fsm_param_reg_setting_t *)input;
281 fsm_param_reg_setting_t *p_output = (fsm_param_reg_setting_t *)output;
282
283 if ( p_input->flag & REG_SETTING_BIT_REG_ADDR ) {
284 p_output->api_reg_addr = p_fsm->api_reg_addr;
285 }
286
287 if ( p_input->flag & REG_SETTING_BIT_REG_SIZE ) {
288 p_output->api_reg_size = p_fsm->api_reg_size;
289 }
290
291 if ( p_input->flag & REG_SETTING_BIT_REG_SOURCE ) {
292 p_output->api_reg_source = p_fsm->api_reg_source;
293 }
294
295 if ( p_input->flag & REG_SETTING_BIT_REG_VALUE ) {
296 rc = general_get_reg_value( p_fsm, &p_output->api_reg_value );
297 }
298
299 break;
300 }
301
302 case FSM_PARAM_GET_SCENE_MODE:
303 if ( !output || output_size != sizeof( uint32_t ) ) {
304 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
305 rc = -1;
306 break;
307 }
308
309 *(uint32_t *)output = p_fsm->api_scene_mode;
310
311 break;
312
313 default:
314 rc = -1;
315 break;
316 }
317
318 return rc;
319 }
320
general_fsm_process_event(general_fsm_t * p_fsm,event_id_t event_id)321 uint8_t general_fsm_process_event( general_fsm_t *p_fsm, event_id_t event_id )
322 {
323 uint8_t b_event_processed = 0;
324
325
326 switch ( event_id ) {
327 default:
328 break;
329 case event_id_new_frame:
330 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_START );
331 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_END );
332 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_ANTIFOG_HIST );
333 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_AF2_STATS );
334 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_AWB_STATS );
335 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_AE_STATS );
336
337 //need to be almost sync as the new address available from FR or DS
338 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_WRITER_FR ); //enabled for DMA_WRITER_FSM
339 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_WRITER_DS );
340
341 b_event_processed = 1;
342 break;
343
344 case event_id_drop_frame:
345 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_START );
346
347 //need to drop cur frame from FR or DS
348 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_DROP_FR ); //enabled for DMA_WRITER_FSM
349 acamera_general_interrupt_hanlder( ACAMERA_FSM2CTX_PTR( p_fsm ), ACAMERA_IRQ_FRAME_DROP_DS );
350
351 b_event_processed = 1;
352 break;
353 }
354 return b_event_processed;
355 }
356