1 /*
2 * Copyright (c) 2019 Rockchip Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include "FlashLight.h"
19 #include "xcam_log.h"
20 #include "linux/rk-led-flash.h"
21
22 namespace RkCam {
23
FlashLightHw(std::string name[],int num)24 FlashLightHw::FlashLightHw(std::string name[], int num)
25 {
26 if (num >= FLASH_MAX_NUM) {
27 LOGE_CAMHW_SUBM(FL_SUBM, "not support flash num %d", num);
28 return ;
29 }
30
31 _dev_num = 0;
32 for (int i = 0 ; i < num; i++) {
33 _fl_device[i] = new V4l2SubDevice(name[i].c_str());
34 _dev_num++;
35 }
36 _active_fl_num = 0;
37 _keep_status = false;
38 xcam_mem_clear (_flash_settings);
39 }
40
~FlashLightHw()41 FlashLightHw::~FlashLightHw()
42 {
43
44 }
45
46 XCamReturn
init(int active_num)47 FlashLightHw::init(int active_num)
48 {
49 XCAM_ASSERT (active_num <= _dev_num);
50
51 for (int i = 0 ; i < active_num; i++) {
52 _fl_device[i]->open();
53 _active_fl_num++;
54 }
55
56 get_flash_info ();
57
58 return XCAM_RETURN_NO_ERROR;
59 }
60
61 XCamReturn
deinit()62 FlashLightHw::deinit()
63 {
64 if (!_keep_status) {
65 v4l_set_params(RK_AIQ_FLASH_MODE_OFF, 0, 0, false);
66 xcam_mem_clear (_flash_settings);
67 }
68 for (int i = 0 ; i < _active_fl_num; i++) {
69 _fl_device[i]->close();
70 }
71 _active_fl_num = 0;
72
73 return XCAM_RETURN_NO_ERROR;
74 }
75
76 XCamReturn
start()77 FlashLightHw::start()
78 {
79 for (int i = 0 ; i < _active_fl_num; i++) {
80 _fl_device[i]->start();
81 }
82
83 return XCAM_RETURN_NO_ERROR;
84 }
85
86 XCamReturn
stop()87 FlashLightHw::stop()
88 {
89 if (!_keep_status) {
90 v4l_set_params(RK_AIQ_FLASH_MODE_OFF, 0, 0, false);
91 xcam_mem_clear (_flash_settings);
92 }
93 for (int i = 0 ; i < _active_fl_num; i++) {
94 _fl_device[i]->stop();
95 }
96
97 return XCAM_RETURN_NO_ERROR;
98 }
99
100 XCamReturn
set_params(rk_aiq_flash_setting_t & flash_settings)101 FlashLightHw::set_params(rk_aiq_flash_setting_t& flash_settings)
102 {
103 XCamReturn ret = XCAM_RETURN_NO_ERROR;
104 // set flash if needed
105 rk_aiq_flash_setting_t* old_flash_settings = &_flash_settings;
106 if ((old_flash_settings->flash_mode != flash_settings.flash_mode) ||
107 (old_flash_settings->strobe != flash_settings.strobe) ||
108 (old_flash_settings->power[0] != flash_settings.power[0]) ||
109 (old_flash_settings->power[1] != flash_settings.power[1])
110 ) {
111 LOGD_CAMHW_SUBM(FL_SUBM, "flash_settings: mode:%d,power:%f,timeout_ms:%d,strobe:%d",
112 flash_settings.flash_mode, flash_settings.power[0],
113 flash_settings.timeout_ms, flash_settings.strobe);
114 ret = v4l_set_params(flash_settings.flash_mode, flash_settings.power,
115 flash_settings.timeout_ms, flash_settings.strobe);
116 if (!ret)
117 _flash_settings = flash_settings;
118 }
119
120 return ret;
121 }
122
123 XCamReturn
get_status(rk_aiq_flash_setting_t & flash_settings,uint32_t frame_id)124 FlashLightHw::get_status (rk_aiq_flash_setting_t& flash_settings, uint32_t frame_id)
125 {
126 if (!_active_fl_num)
127 return XCAM_RETURN_ERROR_FAILED;
128
129 flash_settings = _flash_settings;
130
131 if (_fl_device[0].ptr()) {
132 struct timeval flash_time;
133
134 if (_fl_device[0]->io_control (RK_VIDIOC_FLASH_TIMEINFO, &flash_time) < 0) {
135 LOGE_CAMHW_SUBM(FL_SUBM, " get RK_VIDIOC_FLASH_TIMEINFO failed. cmd = 0x%x", RK_VIDIOC_FLASH_TIMEINFO);
136 /* return XCAM_RETURN_ERROR_IOCTL; */
137 }
138 flash_settings.effect_ts = (int64_t)flash_time.tv_sec * 1000 * 1000 +
139 (int64_t)flash_time.tv_usec;
140 LOGD_CAMHW_SUBM(FL_SUBM, "frameid %u, get RK_VIDIOC_FLASH_TIMEINFO flash ts %lld",
141 frame_id, flash_settings.effect_ts);
142 }
143
144 // for the following case:
145 // 1) set to flash mode
146 // 2) one flash power set to 0
147 // then we can't get the effect ts from the node which power set to 0
148 if (_fl_device[1].ptr() && flash_settings.effect_ts == 0 &&
149 flash_settings.power[0] != flash_settings.power[1]) {
150 struct timeval flash_time;
151
152 if (_fl_device[1]->io_control (RK_VIDIOC_FLASH_TIMEINFO, &flash_time) < 0) {
153 LOGE_CAMHW_SUBM(FL_SUBM, " get RK_VIDIOC_FLASH_TIMEINFO failed. cmd = 0x%x", RK_VIDIOC_FLASH_TIMEINFO);
154 /* return XCAM_RETURN_ERROR_IOCTL; */
155 }
156 flash_settings.effect_ts = (int64_t)flash_time.tv_sec * 1000 * 1000 +
157 (int64_t)flash_time.tv_usec;
158 LOGD_CAMHW_SUBM(FL_SUBM, "frameid %u, get RK_VIDIOC_FLASH_TIMEINFO flash ts %lld",
159 frame_id, flash_settings.effect_ts);
160 }
161
162 return XCAM_RETURN_NO_ERROR;
163 }
164
165 XCamReturn
v4l_set_params(int fl_mode,float fl_intensity[],int fl_timeout,int fl_on)166 FlashLightHw::v4l_set_params(int fl_mode, float fl_intensity[], int fl_timeout, int fl_on)
167 {
168 struct v4l2_control control;
169 int fl_v4l_mode;
170 int i = 0;
171 #define set_fl_contol_to_dev(fl_dev,control_id,val) \
172 {\
173 xcam_mem_clear (control); \
174 control.id = control_id; \
175 control.value = val; \
176 if (fl_dev->io_control (VIDIOC_S_CTRL, &control) < 0) { \
177 LOGE_CAMHW_SUBM(FL_SUBM, " set fl %s to %d failed", #control_id, val); \
178 return XCAM_RETURN_ERROR_IOCTL; \
179 } \
180 LOGD_CAMHW_SUBM(FL_SUBM, "set fl %p, cid %s to %d, success",\
181 fl_dev.ptr(), #control_id, val); \
182 }\
183
184 if (fl_mode == RK_AIQ_FLASH_MODE_OFF)
185 fl_v4l_mode = V4L2_FLASH_LED_MODE_NONE;
186 else if (fl_mode == RK_AIQ_FLASH_MODE_FLASH || fl_mode == RK_AIQ_FLASH_MODE_FLASH_MAIN)
187 fl_v4l_mode = V4L2_FLASH_LED_MODE_FLASH;
188 else if (fl_mode == RK_AIQ_FLASH_MODE_FLASH_PRE || fl_mode == RK_AIQ_FLASH_MODE_TORCH)
189 fl_v4l_mode = V4L2_FLASH_LED_MODE_TORCH;
190 else {
191 LOGE_CAMHW_SUBM(FL_SUBM, " set fl to mode %d failed", fl_mode);
192 return XCAM_RETURN_ERROR_PARAM;
193 }
194
195 SmartPtr<V4l2SubDevice> fl_device;
196
197 if (fl_v4l_mode == V4L2_FLASH_LED_MODE_NONE) {
198 for (i = 0; i < _active_fl_num; i++) {
199 fl_device = _fl_device[i];
200 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_NONE);
201 }
202 } else if (fl_v4l_mode == V4L2_FLASH_LED_MODE_FLASH) {
203 for (i = 0; i < _active_fl_num; i++) {
204 fl_device = _fl_device[i];
205 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_FLASH);
206 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_TIMEOUT, fl_timeout * 1000);
207 if (_v4l_flash_info[i].fl_strth_adj_enable) {
208 int flash_power =
209 fl_intensity[i] * (_v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX]);
210 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_INTENSITY, flash_power);
211 LOGD_CAMHW_SUBM(FL_SUBM, "set flash: flash:%f max:%d set:%d\n",
212 fl_intensity[i],
213 _v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX],
214 flash_power);
215 }
216 }
217
218 // shoude flash on all finally
219 for (i = 0; i < _active_fl_num; i++) {
220 set_fl_contol_to_dev(fl_device,
221 fl_on ? V4L2_CID_FLASH_STROBE : V4L2_CID_FLASH_STROBE_STOP, 0);
222 }
223 } else if (fl_v4l_mode == V4L2_FLASH_LED_MODE_TORCH) {
224 for (i = 0; i < _active_fl_num; i++) {
225 fl_device = _fl_device[i];
226 if (_v4l_flash_info[i].tc_strth_adj_enable) {
227 int torch_power =
228 fl_intensity[i] * (_v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX]);
229 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_TORCH_INTENSITY, torch_power);
230 LOGD_CAMHW_SUBM(FL_SUBM, "set flash: torch:%f max:%d set:%d\n",
231 fl_intensity[i],
232 _v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX],
233 torch_power);
234 }
235 set_fl_contol_to_dev(fl_device, V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH);
236 }
237 } else {
238 LOGE_CAMHW_SUBM(FL_SUBM, "|||set_3a_fl error fl mode %d", fl_mode);
239 return XCAM_RETURN_ERROR_PARAM;
240 }
241
242 return XCAM_RETURN_NO_ERROR;
243 }
244
245 int
get_flash_info()246 FlashLightHw::get_flash_info ()
247 {
248 struct v4l2_queryctrl ctrl;
249 int flash_power, torch_power;
250 SmartPtr<V4l2SubDevice> fl_device;
251
252 for (int i = 0; i < _active_fl_num; i++) {
253 fl_device = _fl_device[i];
254
255 memset(&ctrl, 0, sizeof(ctrl));
256 ctrl.id = V4L2_CID_FLASH_INTENSITY;
257 if (fl_device->io_control(VIDIOC_QUERYCTRL, &ctrl) < 0) {
258 LOGE_CAMHW_SUBM(FL_SUBM, "query V4L2_CID_FLASH_INTENSITY failed. cmd = 0x%x",
259 V4L2_CID_FLASH_INTENSITY);
260 return -errno;
261 }
262
263 _v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MIN] =
264 ctrl.minimum;
265 _v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX] =
266 ctrl.maximum;
267 _v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_DEFAULT] =
268 ctrl.default_value;
269 _v4l_flash_info[i].flash_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_STEP] =
270 ctrl.step;
271 _v4l_flash_info[i].fl_strth_adj_enable = !(ctrl.flags & V4L2_CTRL_FLAG_READ_ONLY);
272
273 LOGD_CAMHW_SUBM(FL_SUBM, "fl_dev[%d], flash power range:[%d,%d], adjust enable %d",
274 i, ctrl.minimum, ctrl.maximum, _v4l_flash_info[i].fl_strth_adj_enable);
275
276 memset(&ctrl, 0, sizeof(ctrl));
277 ctrl.id = V4L2_CID_FLASH_TORCH_INTENSITY;
278 if (fl_device->io_control(VIDIOC_QUERYCTRL, &ctrl) < 0) {
279 LOGE_CAMHW_SUBM(FL_SUBM, "query V4L2_CID_FLASH_TORCH_INTENSITY failed. cmd = 0x%x",
280 V4L2_CID_FLASH_TORCH_INTENSITY);
281 return -errno;
282 }
283
284 _v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MIN] =
285 ctrl.minimum;
286 _v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_MAX] =
287 ctrl.maximum;
288 _v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_DEFAULT] =
289 ctrl.default_value;
290 _v4l_flash_info[i].torch_power_info[RK_AIQ_V4L_FLASH_QUERY_TYPE_E_STEP] =
291 ctrl.step;
292
293 _v4l_flash_info[i].tc_strth_adj_enable = !(ctrl.flags & V4L2_CTRL_FLAG_READ_ONLY);
294
295
296 LOGD_CAMHW_SUBM(FL_SUBM, "fl_dev[%d], torch power range:[%d,%d], adjust enable %d",
297 i, ctrl.minimum, ctrl.maximum, _v4l_flash_info[i].tc_strth_adj_enable);
298 }
299
300 return XCAM_RETURN_NO_ERROR;
301 }
302
303 }
304