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 "ae_manual_fsm.h"
22 #include "acamera_3aalg_preset.h"
23 #include "sbuf.h"
24
25 #ifdef LOG_MODULE
26 #undef LOG_MODULE
27 #define LOG_MODULE LOG_MODULE_AE_MANUAL
28 #endif
29
30 isp_ae_preset_t p_ae_preset;
31
AE_fsm_clear(AE_fsm_t * p_fsm)32 void AE_fsm_clear( AE_fsm_t *p_fsm )
33 {
34 p_fsm->error_log2 = p_ae_preset.error_log2;
35 p_fsm->ae_hist_mean = 0;
36 p_fsm->exposure_log2 = p_ae_preset.exposure_log2;
37 p_fsm->new_exposure_log2 = p_ae_preset.exposure_log2;
38 p_fsm->integrator = p_ae_preset.integrator;
39 p_fsm->exposure_ratio = p_ae_preset.exposure_ratio;
40 p_fsm->new_exposure_ratio = p_ae_preset.exposure_ratio;
41 p_fsm->exposure_ratio_avg = 64;
42 p_fsm->ae_roi_api = AE_CENTER_ZONES;
43 p_fsm->roi = AE_CENTER_ZONES;
44 p_fsm->save_hist_api = 0x0;
45 #if FW_ZONE_AE
46 p_fsm->smart_zone_enable = 1;
47 p_fsm->x1 = ( (AE_CENTER_ZONES)&0xFF );
48 p_fsm->y1 = ( ( AE_CENTER_ZONES >> 8 ) & 0xFF );
49 p_fsm->x2 = ( ( AE_CENTER_ZONES >> 16 ) & 0xFF );
50 p_fsm->y2 = ( ( AE_CENTER_ZONES >> 24 ) & 0xFF );
51 #endif
52 p_fsm->frame_id_tracking = 0;
53 }
54
AE_request_interrupt(AE_fsm_ptr_t p_fsm,system_fw_interrupt_mask_t mask)55 void AE_request_interrupt( AE_fsm_ptr_t p_fsm, system_fw_interrupt_mask_t mask )
56 {
57 acamera_isp_interrupts_disable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
58 p_fsm->mask.irq_mask |= mask;
59 acamera_isp_interrupts_enable( ACAMERA_FSM2MGR_PTR( p_fsm ) );
60 }
61
AE_fsm_init(void * fsm,fsm_init_param_t * init_param)62 void AE_fsm_init( void *fsm, fsm_init_param_t *init_param )
63 {
64 AE_fsm_t *p_fsm = (AE_fsm_t *)fsm;
65 p_fsm->cmn.p_fsm_mgr = init_param->p_fsm_mgr;
66 p_fsm->cmn.isp_base = init_param->isp_base;
67 p_fsm->p_fsm_mgr = init_param->p_fsm_mgr;
68
69 AE_fsm_clear( p_fsm );
70
71 ae_initialize( p_fsm );
72 }
73
74
AE_fsm_set_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size)75 int AE_fsm_set_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size )
76 {
77 int rc = 0;
78 AE_fsm_t *p_fsm = (AE_fsm_t *)fsm;
79
80 switch ( param_id ) {
81 case FSM_PARAM_SET_AE_INIT:
82 AE_fsm_clear( p_fsm );
83 ae_initialize( p_fsm );
84 break;
85
86 case FSM_PARAM_SET_AE_NEW_PARAM:
87 if ( !input || input_size != sizeof( sbuf_ae_t ) ) {
88 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
89 rc = -1;
90 break;
91 }
92
93 ae_set_new_param( p_fsm, (sbuf_ae_t *)input );
94
95 break;
96
97 case FSM_PARAM_SET_AE_ROI: {
98 if ( !input || input_size != sizeof( fsm_param_roi_t ) ) {
99 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
100 rc = -1;
101 break;
102 }
103
104 fsm_param_roi_t *p_new = (fsm_param_roi_t *)input;
105 p_fsm->ae_roi_api = p_new->roi_api;
106 p_fsm->roi = p_new->roi;
107
108 ae_roi_update( p_fsm );
109
110 break;
111 }
112
113 case FSM_PARAM_SET_AE_ZONE_WEIGHT: {
114 if (!input || input_size == 0) {
115 LOG(LOG_ERR, "Invalid param. param id: %d.", param_id);
116 rc = -1;
117 break;
118 }
119
120 unsigned char *u_ae_wg = input;
121
122 rc = ae_set_zone_weight(p_fsm, u_ae_wg);
123 if (rc != 0)
124 LOG(LOG_ERR, "Failed to set ae zone weight");
125
126 break;
127 }
128 case FSM_PARAM_SET_AE_PRESET:
129 if ( !input || input_size != sizeof( isp_ae_preset_t ) ) {
130 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
131 rc = -1;
132 break;
133 }
134
135 isp_ae_preset_t *p_new = (isp_ae_preset_t *)input;
136 p_fsm->new_exposure_log2 = p_new->exposure_log2;
137 p_fsm->new_exposure_ratio = p_new->exposure_ratio;
138 p_ae_preset.error_log2 = p_new->error_log2;
139 p_ae_preset.exposure_log2 = p_new->exposure_log2;
140 p_ae_preset.integrator = p_new->integrator;
141 p_ae_preset.exposure_ratio = p_new->exposure_ratio;
142 ae_calculate_exposure( p_fsm );
143 break;
144
145 default:
146 rc = -1;
147 break;
148 }
149
150 return rc;
151 }
152
153
AE_fsm_get_param(void * fsm,uint32_t param_id,void * input,uint32_t input_size,void * output,uint32_t output_size)154 int AE_fsm_get_param( void *fsm, uint32_t param_id, void *input, uint32_t input_size, void *output, uint32_t output_size )
155 {
156 int rc = 0;
157 AE_fsm_t *p_fsm = (AE_fsm_t *)fsm;
158
159 switch ( param_id ) {
160 case FSM_PARAM_GET_AE_INFO: {
161 if ( !output || output_size != sizeof( fsm_param_ae_info_t ) ) {
162 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
163 rc = -1;
164 break;
165 }
166
167 fsm_param_ae_info_t *p_ae_info = (fsm_param_ae_info_t *)output;
168
169 p_ae_info->exposure_log2 = p_fsm->exposure_log2;
170 p_ae_info->ae_hist_mean = p_fsm->ae_hist_mean;
171 p_ae_info->exposure_ratio = p_fsm->exposure_ratio;
172 p_ae_info->error_log2 = p_fsm->error_log2;
173 break;
174 }
175
176 case FSM_PARAM_GET_AE_HIST_INFO: {
177 if ( !output || output_size != sizeof( fsm_param_ae_hist_info_t ) ) {
178 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
179 rc = -1;
180 break;
181 }
182
183 fsm_param_ae_hist_info_t *p_hist_info = (fsm_param_ae_hist_info_t *)output;
184
185 p_hist_info->fullhist_sum = p_fsm->fullhist_sum;
186 p_hist_info->fullhist = p_fsm->fullhist;
187 p_hist_info->frame_id = p_fsm->frame_id_tracking;
188
189 break;
190 }
191
192 case FSM_PARAM_GET_AE_ROI: {
193 if ( !output || output_size != sizeof( fsm_param_roi_t ) ) {
194 LOG( LOG_ERR, "Invalid param, param_id: %d.", param_id );
195 rc = -1;
196 break;
197 }
198
199 fsm_param_roi_t *p_current = (fsm_param_roi_t *)output;
200 p_current->roi_api = p_fsm->ae_roi_api;
201 p_current->roi = p_fsm->roi;
202
203 break;
204 }
205
206 default:
207 rc = -1;
208 break;
209 }
210
211 return rc;
212 }
213
214
AE_fsm_process_event(AE_fsm_t * p_fsm,event_id_t event_id)215 uint8_t AE_fsm_process_event( AE_fsm_t *p_fsm, event_id_t event_id )
216 {
217 uint8_t b_event_processed = 0;
218 switch ( event_id ) {
219 default:
220 break;
221 case event_id_ae_result_ready:
222 if ( ae_calculate_exposure( p_fsm ) ) {
223 fsm_raise_event( p_fsm, event_id_exposure_changed );
224 }
225
226 b_event_processed = 1;
227 }
228
229 return b_event_processed;
230 }
231