• 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 "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, &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, &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