• 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 "sensor_fsm.h"
22 
23 #ifdef LOG_MODULE
24 #undef LOG_MODULE
25 #define LOG_MODULE LOG_MODULE_SENSOR
26 #endif
27 
sensor_fsm_clear(sensor_fsm_t * p_fsm)28 void sensor_fsm_clear( sensor_fsm_t *p_fsm )
29 {
30     p_fsm->mode = ( 0 );
31     p_fsm->preset_mode = SENSOR_DEFAULT_PRESET_MODE;
32     p_fsm->isp_output_mode = ( ISP_DISPLAY_MODE );
33     p_fsm->is_streaming = ( 0 );
34     p_fsm->info_preset_num = SENSOR_DEFAULT_PRESET_MODE;
35     p_fsm->boot_status = sensor_boot_init( p_fsm );
36 	p_fsm->preset_mode = ((sensor_param_t *)(p_fsm->sensor_ctx))->mode;
37 }
38 
sensor_request_interrupt(sensor_fsm_ptr_t p_fsm,system_fw_interrupt_mask_t mask)39 void sensor_request_interrupt( sensor_fsm_ptr_t p_fsm, system_fw_interrupt_mask_t mask )
40 {
41     acamera_isp_interrupts_disable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
42     p_fsm->mask.irq_mask |= mask;
43     acamera_isp_interrupts_enable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
44 }
45 
46 
sensor_fsm_init(void * fsm,fsm_init_param_t * init_param)47 void sensor_fsm_init( void *fsm, fsm_init_param_t *init_param )
48 {
49     sensor_fsm_t *p_fsm = (sensor_fsm_t *)fsm;
50     p_fsm->cmn.p_fsm_mgr = init_param->p_fsm_mgr;
51     p_fsm->cmn.isp_base = init_param->isp_base;
52     p_fsm->p_fsm_mgr = init_param->p_fsm_mgr;
53 
54     sensor_fsm_clear( p_fsm );
55 
56     sensor_hw_init( p_fsm );
57     sensor_sw_init( p_fsm );
58     sensor_configure_buffers( p_fsm );
59     fsm_raise_event( p_fsm, event_id_sensor_ready );
60 }
61 
sensor_fsm_get_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size,void * output,uint32_t output_size)62 int sensor_fsm_get_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size, void *output, uint32_t output_size )
63 {
64     int rc = 0;
65     sensor_fsm_t *p_fsm = (sensor_fsm_t *)fsm;
66 
67     switch ( param_id ) {
68     case FSM_PARAM_GET_SENSOR_STREAMING:
69         if ( !output || output_size != sizeof( uint32_t ) ) {
70             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
71             rc = -1;
72             break;
73         }
74 
75         *(uint32_t *)output = p_fsm->is_streaming;
76 
77         break;
78 
79     case FSM_PARAM_GET_SENSOR_LINES_SECOND:
80         if ( !output || output_size != sizeof( uint32_t ) ) {
81             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
82             rc = -1;
83             break;
84         }
85 
86         *(uint32_t *)output = sensor_get_lines_second( p_fsm );
87 
88         break;
89 
90     case FSM_PARAM_GET_SENSOR_INFO: {
91         const sensor_param_t *param;
92         if ( !output || output_size != sizeof( fsm_param_sensor_info_t ) ) {
93             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
94             rc = -1;
95             break;
96         }
97 
98         param = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
99         fsm_param_sensor_info_t *p_sensor_info = (fsm_param_sensor_info_t *)output;
100 
101         p_sensor_info->total_width = param->total.width;
102         p_sensor_info->total_height = param->total.height;
103         p_sensor_info->active_width = param->active.width;
104         p_sensor_info->active_height = param->active.height;
105         p_sensor_info->pixels_per_line = param->pixels_per_line;
106         p_sensor_info->lines_per_second = param->lines_per_second;
107 
108         p_sensor_info->again_log2_max = param->again_log2_max;
109         p_sensor_info->dgain_log2_max = param->dgain_log2_max;
110         p_sensor_info->integration_time_min = param->integration_time_min;
111         p_sensor_info->integration_time_max = param->integration_time_max;
112         p_sensor_info->integration_time_long_max = param->integration_time_long_max;
113         p_sensor_info->integration_time_limit = param->integration_time_limit;
114 
115         p_sensor_info->integration_time_apply_delay = param->integration_time_apply_delay;
116         p_sensor_info->sensor_exp_number = param->sensor_exp_number;
117         p_sensor_info->isp_exposure_channel_delay = param->isp_exposure_channel_delay;
118 
119         p_sensor_info->isp_output_mode = p_fsm->isp_output_mode;
120         p_sensor_info->resolution_mode = p_fsm->mode;
121         p_sensor_info->black_level = p_fsm->black_level;
122         p_sensor_info->sensor_bits = param->modes_table[param->mode].bits;
123         break;
124     }
125 
126     case FSM_PARAM_GET_SENSOR_PARAM:
127         if ( !output || output_size != sizeof( sensor_param_t ** ) ) {
128             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
129             rc = -1;
130             break;
131         }
132 
133         *( (const sensor_param_t **)output ) = p_fsm->ctrl.get_parameters( p_fsm->sensor_ctx );
134 
135         break;
136 
137     case FSM_PARAM_GET_SENSOR_INFO_PRESET_NUM:
138         if ( !output || output_size != sizeof( uint32_t ) ) {
139             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
140             rc = -1;
141             break;
142         }
143 
144         *(uint32_t *)output = p_fsm->info_preset_num;
145 
146         break;
147 
148     case FSM_PARAM_GET_SENSOR_REG:
149         if ( !input || input_size != sizeof( uint32_t ) ||
150              !output || output_size != sizeof( uint32_t ) ) {
151             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
152             rc = -1;
153             break;
154         }
155 
156         *(uint32_t *)output = p_fsm->ctrl.read_sensor_register( p_fsm->sensor_ctx, *(uint32_t *)input );
157         break;
158 
159     case FSM_PARAM_GET_SENSOR_ID:
160         if ( !output || output_size != sizeof( uint32_t ) ) {
161             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
162             rc = -1;
163             break;
164         }
165 
166         *(uint32_t *)output = p_fsm->ctrl.get_id( p_fsm->sensor_ctx );
167         break;
168 
169     default:
170         rc = -1;
171         break;
172     }
173 
174     return rc;
175 }
176 
sensor_fsm_set_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size)177 int sensor_fsm_set_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size )
178 {
179     int rc = 0;
180     sensor_fsm_t *p_fsm = (sensor_fsm_t *)fsm;
181     acamera_context_ptr_t ctx_ptr = NULL;
182 
183     switch ( param_id ) {
184     case FSM_PARAM_SET_SENSOR_STREAMING: {
185         uint32_t streaming;
186         if ( !input || input_size != sizeof( uint32_t ) ) {
187             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
188             rc = -1;
189             break;
190         }
191 
192         streaming = *(uint32_t *)input;
193 
194         if (streaming == 1) {
195             p_fsm->ctrl.start_streaming( p_fsm->sensor_ctx );
196         } else if(streaming == 0){
197             p_fsm->ctrl.stop_streaming( p_fsm->sensor_ctx );
198         }
199         p_fsm->is_streaming = streaming;
200         break;
201     }
202 
203     case FSM_PARAM_SET_SENSOR_PRESET_MODE:
204         if ( !input || input_size != sizeof( uint32_t ) ) {
205             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
206             rc = -1;
207             break;
208         }
209 
210         ctx_ptr = ACAMERA_FSM2CTX_PTR(p_fsm);
211         ctx_ptr->irq_flag++;
212         p_fsm->preset_mode = *(uint32_t *)input;
213         sensor_hw_init( p_fsm );
214         sensor_configure_buffers( p_fsm );
215         sensor_sw_init( p_fsm );
216         ctx_ptr->irq_flag--;
217         break;
218 
219     case FSM_PARAM_SET_SENSOR_INFO_PRESET_NUM:
220         if ( !input || input_size != sizeof( uint32_t ) ) {
221             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
222             rc = -1;
223             break;
224         }
225 
226         p_fsm->info_preset_num = *(uint32_t *)input;
227 
228         break;
229 
230     case FSM_PARAM_SET_SENSOR_ALLOC_ANALOG_GAIN: {
231         if ( !input || input_size != sizeof( int32_t ) ) {
232             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
233             rc = -1;
234             break;
235         }
236 
237         int32_t expect_again = *( (int32_t *)input );
238 
239         *( (int32_t *)input ) = p_fsm->ctrl.alloc_analog_gain( p_fsm->sensor_ctx, expect_again );
240 
241         break;
242     }
243 
244     case FSM_PARAM_SET_SENSOR_ALLOC_DIGITAL_GAIN: {
245         if ( !input || input_size != sizeof( int32_t ) ) {
246             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
247             rc = -1;
248             break;
249         }
250 
251         int32_t expect_dgain = *( (int32_t *)input );
252 
253         *( (int32_t *)input ) = p_fsm->ctrl.alloc_digital_gain( p_fsm->sensor_ctx, expect_dgain );
254 
255         break;
256     }
257 
258     case FSM_PARAM_SET_SENSOR_ALLOC_INTEGRATION_TIME: {
259         if ( !input || input_size != sizeof( fsm_param_sensor_int_time_t ) ) {
260             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
261             rc = -1;
262             break;
263         }
264 
265         fsm_param_sensor_int_time_t *p_time = (fsm_param_sensor_int_time_t *)input;
266 
267         p_fsm->ctrl.alloc_integration_time( p_fsm->sensor_ctx, &p_time->int_time, &p_time->int_time_M, &p_time->int_time_L );
268 
269         break;
270     }
271 
272     case FSM_PARAM_SET_SENSOR_UPDATE:
273 
274         p_fsm->ctrl.sensor_update( p_fsm->sensor_ctx );
275 
276         break;
277 
278     case FSM_PARAM_SET_SENSOR_REG: {
279         if ( !input || input_size != sizeof( fsm_param_reg_cfg_t ) ) {
280             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
281             rc = -1;
282             break;
283         }
284 
285         fsm_param_reg_cfg_t *p_cfg = (fsm_param_reg_cfg_t *)input;
286         p_fsm->ctrl.write_sensor_register( p_fsm->sensor_ctx, p_cfg->reg_addr, p_cfg->reg_value );
287         break;
288     }
289     case FSM_PARAM_SET_SENSOR_TEST_PATTERN:
290         if ( !input ) {
291             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
292             rc = -1;
293             break;
294         }
295         uint8_t mode = *( (uint8_t *)input );
296 
297         p_fsm->ctrl.sensor_test_pattern( p_fsm->sensor_ctx, mode);
298 
299         break;
300     case FSM_PARAM_SET_SENSOR_SENSOR_IR_CUT: {
301         if ( !input || input_size != sizeof( uint32_t ) ) {
302             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
303             rc = -1;
304             break;
305         }
306         int32_t ir_cut_state = *(uint32_t *)input;
307         p_fsm->ctrl.ir_cut_set( p_fsm->sensor_ctx, ir_cut_state);
308 
309         break;
310     }
311     case FSM_PARAM_SET_SENSOR_MODE_SWITCH: {
312         if ( !input || input_size != sizeof( uint32_t ) ) {
313             LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
314             rc = -1;
315             break;
316         }
317 
318         ctx_ptr = ACAMERA_FSM2CTX_PTR(p_fsm);
319 
320         p_fsm->preset_mode = *(uint32_t *)input;
321         p_fsm->ctrl.stop_streaming( p_fsm->sensor_ctx );
322         sensor_hw_init( p_fsm );
323         sensor_configure_buffers( p_fsm );
324         sensor_sw_init( p_fsm );
325         p_fsm->ctrl.start_streaming( p_fsm->sensor_ctx );
326         acamera_isp_input_port_mode_request_write( p_fsm->cmn.isp_base, ACAMERA_ISP_INPUT_PORT_MODE_REQUEST_SAFE_START );
327         break;
328     }
329     default:
330         rc = -1;
331         break;
332     }
333 
334     return rc;
335 }
336 
sensor_fsm_process_event(sensor_fsm_t * p_fsm,event_id_t event_id)337 uint8_t sensor_fsm_process_event( sensor_fsm_t *p_fsm, event_id_t event_id )
338 {
339     uint8_t b_event_processed = 0;
340     switch ( event_id ) {
341     default:
342         break;
343     case event_id_frame_end:
344         sensor_update_black( p_fsm );
345         b_event_processed = 1;
346         break;
347 
348     case event_id_sensor_sw_reset:
349         fsm_raise_event( p_fsm, event_id_sensor_not_ready );
350         sensor_sw_init( p_fsm );
351         sensor_configure_buffers( p_fsm );
352         fsm_raise_event( p_fsm, event_id_sensor_ready );
353         b_event_processed = 1;
354         break;
355 
356     case event_id_acamera_reset_sensor_hw:
357         fsm_raise_event( p_fsm, event_id_sensor_ready );
358         b_event_processed = 1;
359         break;
360     }
361 
362     return b_event_processed;
363 }
364