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 #include <linux/vmalloc.h>
20 #include "acamera_fw.h"
21 #include "af_manual_fsm.h"
22 #include "sbuf.h"
23
24 #ifdef LOG_MODULE
25 #undef LOG_MODULE
26 #define LOG_MODULE LOG_MODULE_AF_MANUAL
27 #endif
28
29 extern void af_set_new_param( AF_fsm_ptr_t p_fsm, sbuf_af_t *p_sbuf_af );
30
AF_fsm_clear(AF_fsm_t * p_fsm)31 void AF_fsm_clear( AF_fsm_t *p_fsm )
32 {
33 p_fsm->frame_num = 0;
34 p_fsm->mode = AF_MODE_AF;
35 p_fsm->pos_manual = 0;
36 p_fsm->new_pos = 0;
37 p_fsm->roi = 0x4040C0C0;
38 p_fsm->lens_driver_ok = 0;
39 p_fsm->roi_api = 0x4040C0C0;
40 p_fsm->frame_skip_cnt = 0x0;
41 p_fsm->frame_skip_start = 0x0;
42 p_fsm->last_pos_done = 0;
43 p_fsm->new_last_sharp = 0;
44 p_fsm->last_sharp_done = 0;
45 p_fsm->zone_weight = NULL;
46 p_fsm->zone_process_statistic = NULL;
47 p_fsm->zone_process_reliablility = NULL;
48 memset( &p_fsm->lens_ctrl, 0, sizeof( p_fsm->lens_ctrl ) );
49 }
50
AF_request_interrupt(AF_fsm_ptr_t p_fsm,system_fw_interrupt_mask_t mask)51 void AF_request_interrupt( AF_fsm_ptr_t p_fsm, system_fw_interrupt_mask_t mask )
52 {
53 acamera_isp_interrupts_disable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
54 p_fsm->mask.irq_mask |= mask;
55 acamera_isp_interrupts_enable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
56 }
57
AF_fsm_init(void * fsm,fsm_init_param_t * init_param)58 void AF_fsm_init( void *fsm, fsm_init_param_t *init_param )
59 {
60 AF_fsm_t *p_fsm = (AF_fsm_t *)fsm;
61 p_fsm->cmn.p_fsm_mgr = init_param->p_fsm_mgr;
62 p_fsm->cmn.isp_base = init_param->isp_base;
63 p_fsm->p_fsm_mgr = init_param->p_fsm_mgr;
64
65 AF_fsm_clear( p_fsm );
66
67 AF_init( p_fsm );
68 }
69
70
AF_fsm_set_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size)71 int AF_fsm_set_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size )
72 {
73 int rc = 0;
74 AF_fsm_t *p_fsm = (AF_fsm_t *)fsm;
75
76 if ( !p_fsm->lens_driver_ok ) {
77 LOG( LOG_INFO, "Not supported: no lens driver." );
78 return -1;
79 }
80
81 switch ( param_id ) {
82 case FSM_PARAM_SET_AF_NEW_PARAM:
83 if ( !input || input_size != sizeof( sbuf_af_t ) ) {
84 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
85 rc = -1;
86 break;
87 }
88
89 af_set_new_param( p_fsm, (sbuf_af_t *)input );
90
91 break;
92
93 case FSM_PARAM_SET_AF_MODE:
94 if ( !input || input_size != sizeof( uint32_t ) ) {
95 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
96 rc = -1;
97 break;
98 }
99
100 p_fsm->mode = *(uint32_t *)input;
101
102 break;
103
104 case FSM_PARAM_SET_AF_RANGE_LOW: {
105 if ( !input || input_size != sizeof( uint32_t ) ) {
106 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
107 rc = -1;
108 break;
109 }
110
111 uint32_t value = *(uint32_t *)input;
112
113 if ( value <= 256 ) {
114 af_lms_param_t *param = (af_lms_param_t *)_GET_USHORT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_AF_LMS );
115 p_fsm->pos_min = param->pos_min + ( uint16_t )( ( uint32_t )( param->pos_max - param->pos_min ) * value >> 8 );
116 }
117 break;
118 }
119
120 case FSM_PARAM_SET_AF_RANGE_HIGH: {
121 if ( !input || input_size != sizeof( uint32_t ) ) {
122 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
123 rc = -1;
124 break;
125 }
126
127 uint32_t value = *(uint32_t *)input;
128
129 if ( value <= 256 ) {
130 af_lms_param_t *param = (af_lms_param_t *)_GET_USHORT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_AF_LMS );
131 p_fsm->pos_max = param->pos_min + ( uint16_t )( ( uint32_t )( param->pos_max - param->pos_min ) * value >> 8 );
132 }
133
134 break;
135 }
136
137 case FSM_PARAM_SET_AF_ROI: {
138 if ( !input || input_size != sizeof( fsm_param_roi_t ) ) {
139 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
140 rc = -1;
141 break;
142 }
143
144 fsm_param_roi_t *p_new = (fsm_param_roi_t *)input;
145 p_fsm->roi_api = p_new->roi_api;
146 p_fsm->roi = p_new->roi;
147
148
149 break;
150 }
151
152 case FSM_PARAM_SET_AF_MANUAL_POS: {
153 if ( !input || input_size != sizeof( uint32_t ) ) {
154 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
155 rc = -1;
156 break;
157 }
158
159 uint32_t pos_manual = *(uint32_t *)input;
160
161 if ( pos_manual <= 256 ) {
162 p_fsm->pos_manual = pos_manual;
163 }
164
165 break;
166 }
167
168 default:
169 rc = -1;
170 break;
171 }
172
173 return rc;
174 }
175
176
AF_fsm_get_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size,void * output,uint32_t output_size)177 int AF_fsm_get_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size, void *output, uint32_t output_size )
178 {
179 int rc = 0;
180 AF_fsm_t *p_fsm = (AF_fsm_t *)fsm;
181
182 if ( !p_fsm->lens_driver_ok ) {
183 LOG( LOG_INFO, "Not supported: no lens driver." );
184 return -1;
185 }
186
187 switch ( param_id ) {
188 case FSM_PARAM_GET_AF_MODE:
189 if ( !output || output_size != sizeof( uint32_t ) ) {
190 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
191 rc = -1;
192 break;
193 }
194
195 *(uint32_t *)output = p_fsm->mode;
196
197 break;
198
199 case FSM_PARAM_GET_LENS_PARAM: {
200 if ( !output || output_size != sizeof( lens_param_t ) ) {
201 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
202 rc = -1;
203 break;
204 }
205
206 const lens_param_t *p_lens_param = p_fsm->lens_ctrl.get_parameters( p_fsm->lens_ctx );
207
208 *(lens_param_t *)output = *p_lens_param;
209
210 break;
211 }
212
213 case FSM_PARAM_GET_AF_MANUAL_POS: {
214 if ( !output || output_size != sizeof( uint32_t ) ) {
215 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
216 rc = -1;
217 break;
218 }
219
220 uint16_t af_range = p_fsm->pos_max - p_fsm->pos_min;
221 uint32_t last_position = p_fsm->last_position;
222 uint32_t pos = 0;
223
224 if ( last_position < p_fsm->pos_min ) {
225 last_position = p_fsm->pos_min;
226 } else if ( last_position > p_fsm->pos_max ) {
227 last_position = p_fsm->pos_max;
228 }
229
230 pos = ( ( ( last_position - p_fsm->pos_min ) << 8 ) + af_range / 2 ) / ( af_range );
231
232 if ( pos > 255 ) {
233 pos = 255;
234 }
235
236 *(uint32_t *)output = pos;
237
238 break;
239 }
240
241 case FSM_PARAM_GET_AF_RANGE_LOW: {
242 if ( !output || output_size != sizeof( uint32_t ) ) {
243 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
244 rc = -1;
245 break;
246 }
247
248 af_lms_param_t *param = (af_lms_param_t *)_GET_USHORT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_AF_LMS );
249 *(uint32_t *)output = ( param->pos_max != param->pos_min ) ? ( ( uint32_t )( p_fsm->pos_min - param->pos_min ) << 8 ) / ( param->pos_max - param->pos_min ) : -1;
250
251 break;
252 }
253
254 case FSM_PARAM_GET_AF_RANGE_HIGH: {
255 if ( !output || output_size != sizeof( uint32_t ) ) {
256 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
257 rc = -1;
258 break;
259 }
260
261 af_lms_param_t *param = (af_lms_param_t *)_GET_USHORT_PTR( ACAMERA_FSM2CTX_PTR( p_fsm ), CALIBRATION_AF_LMS );
262 *(uint32_t *)output = ( param->pos_max != param->pos_min ) ? ( ( uint32_t )( p_fsm->pos_max - param->pos_min ) << 8 ) / ( param->pos_max - param->pos_min ) : -1;
263
264 break;
265 }
266
267 case FSM_PARAM_GET_AF_ROI: {
268 if ( !output || output_size != sizeof( fsm_param_roi_t ) ) {
269 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
270 rc = -1;
271 break;
272 }
273
274 fsm_param_roi_t *p_current = (fsm_param_roi_t *)output;
275 p_current->roi_api = p_fsm->roi_api;
276 p_current->roi = p_fsm->roi;
277 break;
278 }
279
280 case FSM_PARAM_GET_AF_LENS_REG:
281 if ( !input || input_size != sizeof( uint32_t ) ||
282 !output || output_size != sizeof( uint32_t ) ) {
283 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
284 rc = -1;
285 break;
286 }
287
288 *(uint32_t *)output = p_fsm->lens_ctrl.read_lens_register( p_fsm->lens_ctx, *(uint32_t *)input );
289 break;
290
291 case FSM_PARAM_GET_AF_LENS_STATUS:
292 if ( !output || output_size != sizeof( int32_t ) ) {
293 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
294 rc = -1;
295 break;
296 }
297
298 *(int32_t *)output = p_fsm->lens_driver_ok;
299 break;
300
301 default:
302 rc = -1;
303 break;
304 }
305
306 return rc;
307 }
308
309
AF_fsm_process_event(AF_fsm_t * p_fsm,event_id_t event_id)310 uint8_t AF_fsm_process_event( AF_fsm_t *p_fsm, event_id_t event_id )
311 {
312 return 0;
313 }
314