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