blob: 55da2648530123eca2033d2d077ccc3a567f59d0 [file] [log] [blame]
Jigarkumar Zala35226272017-04-19 16:05:24 -07001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14
15#include "cam_sensor_cmn_header.h"
16#include "cam_flash_core.h"
Depeng Shao3d8ee902017-10-30 20:30:33 +080017#include "cam_res_mgr_api.h"
Jigarkumar Zala35226272017-04-19 16:05:24 -070018
19int cam_flash_prepare(struct cam_flash_ctrl *flash_ctrl,
20 enum cam_flash_state state)
21{
22 int rc = 0;
23
24 if (!(flash_ctrl->switch_trigger)) {
25 CAM_ERR(CAM_FLASH, "Invalid argument");
26 return -EINVAL;
27 }
28
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -070029 if ((state == CAM_FLASH_STATE_START) &&
Jigarkumar Zala35226272017-04-19 16:05:24 -070030 (flash_ctrl->is_regulator_enabled == false)) {
31 rc = qpnp_flash_led_prepare(flash_ctrl->switch_trigger,
32 ENABLE_REGULATOR, NULL);
33 if (rc) {
34 CAM_ERR(CAM_FLASH, "regulator enable failed rc = %d",
35 rc);
36 return rc;
37 }
38 flash_ctrl->is_regulator_enabled = true;
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -070039 flash_ctrl->flash_state = CAM_FLASH_STATE_START;
40 } else if ((state == CAM_FLASH_STATE_STOP) &&
Jigarkumar Zala35226272017-04-19 16:05:24 -070041 (flash_ctrl->is_regulator_enabled == true)) {
42 rc = qpnp_flash_led_prepare(flash_ctrl->switch_trigger,
43 DISABLE_REGULATOR, NULL);
44 if (rc) {
45 CAM_ERR(CAM_FLASH, "regulator disable failed rc = %d",
46 rc);
47 return rc;
48 }
49 flash_ctrl->is_regulator_enabled = false;
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -070050 flash_ctrl->flash_state = CAM_FLASH_STATE_ACQUIRE;
Jigarkumar Zala35226272017-04-19 16:05:24 -070051 } else {
52 CAM_ERR(CAM_FLASH, "Wrong Flash State : %d",
53 flash_ctrl->flash_state);
54 rc = -EINVAL;
55 }
56
57 return rc;
58}
59
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -070060static int cam_flash_flush_nrt(struct cam_flash_ctrl *fctrl)
61{
62 int j = 0;
63 struct cam_flash_frame_setting *nrt_settings;
64
65 if (!fctrl)
66 return -EINVAL;
67
68 nrt_settings = &fctrl->nrt_info;
69
70 if (nrt_settings->cmn_attr.cmd_type ==
71 CAMERA_SENSOR_FLASH_CMD_TYPE_INIT) {
72 fctrl->flash_init_setting.cmn_attr.is_settings_valid = false;
73 } else if ((nrt_settings->cmn_attr.cmd_type ==
74 CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET) ||
75 (nrt_settings->cmn_attr.cmd_type ==
76 CAMERA_SENSOR_FLASH_CMD_TYPE_RER)) {
77 fctrl->nrt_info.cmn_attr.is_settings_valid = false;
78 fctrl->nrt_info.cmn_attr.count = 0;
79 fctrl->nrt_info.num_iterations = 0;
80 fctrl->nrt_info.led_on_delay_ms = 0;
81 fctrl->nrt_info.led_off_delay_ms = 0;
82 for (j = 0; j < CAM_FLASH_MAX_LED_TRIGGERS; j++)
83 fctrl->nrt_info.led_current_ma[j] = 0;
84 }
85
86 return 0;
87}
88
89int cam_flash_flush_request(struct cam_req_mgr_flush_request *flush)
90{
91 int rc = 0;
92 int i = 0, j = 0;
93 struct cam_flash_ctrl *fctrl = NULL;
94 int frame_offset = 0;
95
96 fctrl = (struct cam_flash_ctrl *) cam_get_device_priv(flush->dev_hdl);
97 if (!fctrl) {
98 CAM_ERR(CAM_FLASH, "Device data is NULL");
99 return -EINVAL;
100 }
101
102 if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
103 /* flush all requests*/
104 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
105 fctrl->per_frame[i].cmn_attr.request_id = 0;
106 fctrl->per_frame[i].cmn_attr.is_settings_valid = false;
107 fctrl->per_frame[i].cmn_attr.count = 0;
108 for (j = 0; j < CAM_FLASH_MAX_LED_TRIGGERS; j++)
109 fctrl->per_frame[i].led_current_ma[j] = 0;
110 }
111
112 rc = cam_flash_flush_nrt(fctrl);
113 if (rc)
114 CAM_ERR(CAM_FLASH, "NonRealTime flush error");
115 } else if (flush->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
116 /* flush request with req_id*/
117 frame_offset = flush->req_id % MAX_PER_FRAME_ARRAY;
118 fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
119 fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
120 false;
121 fctrl->per_frame[frame_offset].cmn_attr.count = 0;
122 for (i = 0; i < CAM_FLASH_MAX_LED_TRIGGERS; i++)
123 fctrl->per_frame[frame_offset].led_current_ma[i] = 0;
124 }
125 return rc;
126}
127
Jigarkumar Zala35226272017-04-19 16:05:24 -0700128static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
129 struct cam_flash_frame_setting *flash_data, enum camera_flash_opcode op)
130{
131 uint32_t curr = 0, max_current = 0;
132 struct cam_flash_private_soc *soc_private = NULL;
133 int i = 0;
134
135 if (!flash_ctrl || !flash_data) {
136 CAM_ERR(CAM_FLASH, "Fctrl or Data NULL");
137 return -EINVAL;
138 }
139
140 soc_private = (struct cam_flash_private_soc *)
Shankar Ravib6f86fd2017-08-11 16:31:33 +0530141 flash_ctrl->soc_info.soc_private;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700142
143 if (op == CAMERA_SENSOR_FLASH_OP_FIRELOW) {
144 for (i = 0; i < flash_ctrl->torch_num_sources; i++) {
145 if (flash_ctrl->torch_trigger[i]) {
146 max_current = soc_private->torch_max_current[i];
147
148 if (flash_data->led_current_ma[i] <=
149 max_current)
150 curr = flash_data->led_current_ma[i];
151 else
152 curr = soc_private->torch_op_current[i];
153
154 CAM_DBG(CAM_FLASH,
155 "Led_Current[%d] = %d", i, curr);
Depeng Shao3d8ee902017-10-30 20:30:33 +0800156 cam_res_mgr_led_trigger_event(
157 flash_ctrl->torch_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700158 curr);
159 }
160 }
161 } else if (op == CAMERA_SENSOR_FLASH_OP_FIREHIGH) {
162 for (i = 0; i < flash_ctrl->flash_num_sources; i++) {
163 if (flash_ctrl->flash_trigger[i]) {
164 max_current = soc_private->flash_max_current[i];
165
166 if (flash_data->led_current_ma[i] <=
167 max_current)
168 curr = flash_data->led_current_ma[i];
169 else
170 curr = soc_private->flash_op_current[i];
171
172 CAM_DBG(CAM_FLASH, "LED flash_current[%d]: %d",
173 i, curr);
Depeng Shao3d8ee902017-10-30 20:30:33 +0800174 cam_res_mgr_led_trigger_event(
175 flash_ctrl->flash_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700176 curr);
177 }
178 }
179 } else {
180 CAM_ERR(CAM_FLASH, "Wrong Operation: %d", op);
181 return -EINVAL;
182 }
183
184 if (flash_ctrl->switch_trigger)
Depeng Shao3d8ee902017-10-30 20:30:33 +0800185 cam_res_mgr_led_trigger_event(
186 flash_ctrl->switch_trigger,
187 LED_SWITCH_ON);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700188
189 return 0;
190}
191
192int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
193{
194 int i = 0;
195
196 if (!flash_ctrl) {
197 CAM_ERR(CAM_FLASH, "Flash control Null");
198 return -EINVAL;
199 }
200
201 for (i = 0; i < flash_ctrl->flash_num_sources; i++)
202 if (flash_ctrl->flash_trigger[i])
Depeng Shao3d8ee902017-10-30 20:30:33 +0800203 cam_res_mgr_led_trigger_event(
204 flash_ctrl->flash_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700205 LED_OFF);
206
207 for (i = 0; i < flash_ctrl->torch_num_sources; i++)
208 if (flash_ctrl->torch_trigger[i])
Depeng Shao3d8ee902017-10-30 20:30:33 +0800209 cam_res_mgr_led_trigger_event(
210 flash_ctrl->torch_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700211 LED_OFF);
212
213 if (flash_ctrl->switch_trigger)
Depeng Shao3d8ee902017-10-30 20:30:33 +0800214 cam_res_mgr_led_trigger_event(flash_ctrl->switch_trigger,
Jigarkumar Zala35226272017-04-19 16:05:24 -0700215 LED_SWITCH_OFF);
216
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700217 flash_ctrl->flash_state = CAM_FLASH_STATE_START;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700218 return 0;
219}
220
221static int cam_flash_low(
222 struct cam_flash_ctrl *flash_ctrl,
223 struct cam_flash_frame_setting *flash_data)
224{
225 int i = 0, rc = 0;
226
227 if (!flash_data) {
228 CAM_ERR(CAM_FLASH, "Flash Data Null");
229 return -EINVAL;
230 }
231
232 for (i = 0; i < flash_ctrl->flash_num_sources; i++)
233 if (flash_ctrl->flash_trigger[i])
Depeng Shao3d8ee902017-10-30 20:30:33 +0800234 cam_res_mgr_led_trigger_event(
235 flash_ctrl->flash_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700236 LED_OFF);
237
238 rc = cam_flash_ops(flash_ctrl, flash_data,
239 CAMERA_SENSOR_FLASH_OP_FIRELOW);
240 if (rc)
241 CAM_ERR(CAM_FLASH, "Fire Torch failed: %d", rc);
242
243 return rc;
244}
245
246static int cam_flash_high(
247 struct cam_flash_ctrl *flash_ctrl,
248 struct cam_flash_frame_setting *flash_data)
249{
250 int i = 0, rc = 0;
251
252 if (!flash_data) {
253 CAM_ERR(CAM_FLASH, "Flash Data Null");
254 return -EINVAL;
255 }
256
257 for (i = 0; i < flash_ctrl->torch_num_sources; i++)
258 if (flash_ctrl->torch_trigger[i])
Depeng Shao3d8ee902017-10-30 20:30:33 +0800259 cam_res_mgr_led_trigger_event(
260 flash_ctrl->torch_trigger[i],
Jigarkumar Zala35226272017-04-19 16:05:24 -0700261 LED_OFF);
262
263 rc = cam_flash_ops(flash_ctrl, flash_data,
264 CAMERA_SENSOR_FLASH_OP_FIREHIGH);
265 if (rc)
266 CAM_ERR(CAM_FLASH, "Fire Flash Failed: %d", rc);
267
268 return rc;
269}
270
271static int delete_req(struct cam_flash_ctrl *fctrl, uint64_t req_id)
272{
273 int i = 0;
274 int frame_offset = 0;
275 struct cam_flash_frame_setting *flash_data = NULL;
276
277 if (req_id == 0) {
278 flash_data = &fctrl->nrt_info;
279 if ((fctrl->nrt_info.cmn_attr.cmd_type ==
280 CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET) ||
281 (fctrl->nrt_info.cmn_attr.cmd_type ==
282 CAMERA_SENSOR_FLASH_CMD_TYPE_RER)) {
283 flash_data->cmn_attr.is_settings_valid = false;
284 for (i = 0; i < flash_data->cmn_attr.count; i++)
285 flash_data->led_current_ma[i] = 0;
286 } else {
287 fctrl->flash_init_setting.cmn_attr.
288 is_settings_valid = false;
289 }
290 } else {
291 frame_offset = (req_id + MAX_PER_FRAME_ARRAY -
292 CAM_FLASH_PIPELINE_DELAY) % 8;
293 flash_data = &fctrl->per_frame[frame_offset];
294 if (req_id > flash_data->cmn_attr.request_id) {
295 flash_data->cmn_attr.request_id = 0;
296 flash_data->cmn_attr.is_settings_valid = false;
297 for (i = 0; i < flash_data->cmn_attr.count; i++)
298 flash_data->led_current_ma[i] = 0;
299 }
300 }
301
302 return 0;
303}
304
305int cam_flash_apply_setting(struct cam_flash_ctrl *fctrl,
306 uint64_t req_id)
307{
308 int rc = 0, i = 0;
309 int frame_offset = 0;
310 uint16_t num_iterations;
311 struct cam_flash_frame_setting *flash_data = NULL;
312
Soundrapandian Jeyaprakashafdca892017-07-27 15:23:13 -0700313 if (req_id == 0) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700314 if (fctrl->nrt_info.cmn_attr.cmd_type ==
315 CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET) {
316 flash_data = &fctrl->nrt_info;
317 if (flash_data->opcode ==
318 CAMERA_SENSOR_FLASH_OP_FIRELOW) {
Jigarkumar Zaladb2b4e62017-10-25 18:30:30 -0700319 rc = cam_flash_low(fctrl, flash_data);
320 if (rc) {
321 CAM_ERR(CAM_FLASH,
322 "Torch ON failed : %d",
323 rc);
324 goto nrt_del_req;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700325 }
Jigarkumar Zaladb2b4e62017-10-25 18:30:30 -0700326 fctrl->flash_state =
327 CAM_FLASH_STATE_LOW;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700328 } else if (flash_data->opcode ==
329 CAMERA_SENSOR_FLASH_OP_OFF) {
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700330 if (fctrl->flash_state ==
331 CAM_FLASH_STATE_LOW) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700332 rc = cam_flash_off(fctrl);
333 if (rc)
334 CAM_ERR(CAM_FLASH,
Jigarkumar Zaladb2b4e62017-10-25 18:30:30 -0700335 "LED off failed: %d",
336 rc);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700337 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700338 }
339 } else if (fctrl->nrt_info.cmn_attr.cmd_type ==
340 CAMERA_SENSOR_FLASH_CMD_TYPE_RER) {
341 flash_data = &fctrl->nrt_info;
342
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700343 if (fctrl->flash_state != CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700344 rc = cam_flash_off(fctrl);
345 if (rc) {
346 CAM_ERR(CAM_FLASH,
347 "Flash off failed: %d",
348 rc);
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700349 goto nrt_del_req;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700350 }
351 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700352 num_iterations = flash_data->num_iterations;
353 for (i = 0; i < num_iterations; i++) {
354 /* Turn On Torch */
355 if (fctrl->flash_state ==
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700356 CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700357 rc = cam_flash_low(fctrl, flash_data);
358 if (rc) {
359 CAM_ERR(CAM_FLASH,
360 "Fire Torch Failed");
361 goto nrt_del_req;
362 }
363 fctrl->flash_state =
364 CAM_FLASH_STATE_LOW;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700365
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700366 usleep_range(
367 flash_data->led_on_delay_ms * 1000,
368 flash_data->led_on_delay_ms * 1000 +
369 100);
370 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700371 /* Turn Off Torch */
372 rc = cam_flash_off(fctrl);
373 if (rc) {
374 CAM_ERR(CAM_FLASH,
375 "Flash off failed: %d",
376 rc);
377 continue;
378 }
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700379 fctrl->flash_state = CAM_FLASH_STATE_START;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700380 usleep_range(
381 flash_data->led_off_delay_ms * 1000,
382 flash_data->led_off_delay_ms * 1000 + 100);
383 }
384 }
385 } else {
386 frame_offset = req_id % MAX_PER_FRAME_ARRAY;
387 flash_data = &fctrl->per_frame[frame_offset];
388
389 if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_FIREHIGH) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700390 (flash_data->cmn_attr.is_settings_valid) &&
391 (flash_data->cmn_attr.request_id == req_id)) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700392 /* Turn On Flash */
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700393 if (fctrl->flash_state == CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700394 rc = cam_flash_high(fctrl, flash_data);
395 if (rc) {
396 CAM_ERR(CAM_FLASH,
397 "Flash ON failed: rc= %d",
398 rc);
399 goto apply_setting_err;
400 }
401 fctrl->flash_state = CAM_FLASH_STATE_HIGH;
402 }
403 } else if ((flash_data->opcode ==
404 CAMERA_SENSOR_FLASH_OP_FIRELOW) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700405 (flash_data->cmn_attr.is_settings_valid) &&
406 (flash_data->cmn_attr.request_id == req_id)) {
Shankar Ravib6f86fd2017-08-11 16:31:33 +0530407 /* Turn On Torch */
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700408 if (fctrl->flash_state == CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700409 rc = cam_flash_low(fctrl, flash_data);
410 if (rc) {
411 CAM_ERR(CAM_FLASH,
412 "Torch ON failed: rc= %d",
413 rc);
414 goto apply_setting_err;
415 }
416 fctrl->flash_state = CAM_FLASH_STATE_LOW;
417 }
418 } else if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700419 (flash_data->cmn_attr.is_settings_valid) &&
420 (flash_data->cmn_attr.request_id == req_id)) {
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700421 if ((fctrl->flash_state == CAM_FLASH_STATE_LOW) ||
422 (fctrl->flash_state == CAM_FLASH_STATE_HIGH)) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700423 rc = cam_flash_off(fctrl);
424 if (rc) {
425 CAM_ERR(CAM_FLASH,
426 "Flash off failed %d", rc);
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700427 goto apply_setting_err;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700428 }
429 }
430 } else {
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700431 CAM_DBG(CAM_FLASH, "NOP opcode: req_id: %u", req_id);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700432 }
433 }
434
435nrt_del_req:
436 delete_req(fctrl, req_id);
437apply_setting_err:
438 return rc;
439}
440
441int cam_flash_parser(struct cam_flash_ctrl *fctrl, void *arg)
442{
443 int rc = 0, i = 0;
444 uint64_t generic_ptr;
445 uint32_t *cmd_buf = NULL;
446 uint32_t *offset = NULL;
447 uint32_t frame_offset = 0;
448 size_t len_of_buffer;
449 struct cam_control *ioctl_ctrl = NULL;
450 struct cam_packet *csl_packet = NULL;
451 struct cam_cmd_buf_desc *cmd_desc = NULL;
452 struct common_header *cmn_hdr;
453 struct cam_config_dev_cmd config;
454 struct cam_req_mgr_add_request add_req;
455 struct cam_flash_init *cam_flash_info = NULL;
456 struct cam_flash_set_rer *flash_rer_info = NULL;
457 struct cam_flash_set_on_off *flash_operation_info = NULL;
458 struct cam_flash_query_curr *flash_query_info = NULL;
459
460 if (!fctrl || !arg) {
461 CAM_ERR(CAM_FLASH, "fctrl/arg is NULL");
462 return -EINVAL;
463 }
464 /* getting CSL Packet */
465 ioctl_ctrl = (struct cam_control *)arg;
466
467 if (copy_from_user((&config), (void __user *) ioctl_ctrl->handle,
468 sizeof(config))) {
469 CAM_ERR(CAM_FLASH, "Copy cmd handle from user failed");
470 rc = -EFAULT;
471 return rc;
472 }
473
474 rc = cam_mem_get_cpu_buf(config.packet_handle,
475 (uint64_t *)&generic_ptr, &len_of_buffer);
476 if (rc) {
477 CAM_ERR(CAM_FLASH, "Failed in getting the buffer : %d", rc);
478 return rc;
479 }
480
Shankar Ravib6f86fd2017-08-11 16:31:33 +0530481 if (config.offset > len_of_buffer) {
482 CAM_ERR(CAM_FLASH,
483 "offset is out of bounds: offset: %lld len: %zu",
484 config.offset, len_of_buffer);
485 return -EINVAL;
486 }
487
488 /* Add offset to the flash csl header */
489 csl_packet = (struct cam_packet *)(generic_ptr + config.offset);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700490
491 switch (csl_packet->header.op_code & 0xFFFFFF) {
492 case CAM_FLASH_PACKET_OPCODE_INIT: {
493 /* INIT packet*/
494 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
495 csl_packet->cmd_buf_offset);
496 fctrl->flash_init_setting.cmn_attr.request_id = 0;
497 fctrl->flash_init_setting.cmn_attr.is_settings_valid = true;
498 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
499 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
500 (uint64_t *)&generic_ptr, &len_of_buffer);
501 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
502 cmd_desc->offset);
503 cam_flash_info = (struct cam_flash_init *)cmd_buf;
504
505 switch (cam_flash_info->cmd_type) {
506 case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT:
507 fctrl->flash_type = cam_flash_info->flash_type;
508 fctrl->is_regulator_enabled = false;
509 fctrl->nrt_info.cmn_attr.cmd_type =
510 CAMERA_SENSOR_FLASH_CMD_TYPE_INIT;
511 break;
512 default:
513 CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
514 cam_flash_info->cmd_type);
515 return -EINVAL;
516 }
517 break;
518 }
519 case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
520 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
521 csl_packet->cmd_buf_offset);
522 frame_offset = csl_packet->header.request_id %
523 MAX_PER_FRAME_ARRAY;
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700524 if (fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid
525 == true) {
526 fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
527 fctrl->per_frame[frame_offset].
528 cmn_attr.is_settings_valid = false;
529 for (i = 0;
530 i < fctrl->per_frame[frame_offset].cmn_attr.count;
531 i++) {
532 fctrl->per_frame[frame_offset].
533 led_current_ma[i] = 0;
534 }
535 }
536
Jigarkumar Zala35226272017-04-19 16:05:24 -0700537 fctrl->per_frame[frame_offset].cmn_attr.request_id =
538 csl_packet->header.request_id;
539 fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
540 true;
541 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
542 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
543 (uint64_t *)&generic_ptr, &len_of_buffer);
544 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
545 cmd_desc->offset);
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700546
547 if (!cmd_buf)
548 return -EINVAL;
549
Jigarkumar Zala35226272017-04-19 16:05:24 -0700550 cmn_hdr = (struct common_header *)cmd_buf;
551
552 switch (cmn_hdr->cmd_type) {
553 case CAMERA_SENSOR_FLASH_CMD_TYPE_FIRE: {
554 CAM_DBG(CAM_FLASH,
555 "CAMERA_FLASH_CMD_TYPE_OPS case called");
556 flash_operation_info =
557 (struct cam_flash_set_on_off *) cmd_buf;
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700558 if (!flash_operation_info) {
559 CAM_ERR(CAM_FLASH, "flash_operation_info Null");
560 return -EINVAL;
561 }
562
Jigarkumar Zala35226272017-04-19 16:05:24 -0700563 fctrl->per_frame[frame_offset].opcode =
564 flash_operation_info->opcode;
565 fctrl->per_frame[frame_offset].cmn_attr.count =
566 flash_operation_info->count;
567 for (i = 0; i < flash_operation_info->count; i++)
568 fctrl->per_frame[frame_offset].led_current_ma[i]
569 = flash_operation_info->
570 led_current_ma[i];
571 break;
572 }
573 default:
574 CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
575 cmn_hdr->cmd_type);
576 return -EINVAL;
577 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700578 break;
579 }
580 case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
581 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
582 csl_packet->cmd_buf_offset);
583 fctrl->nrt_info.cmn_attr.is_settings_valid = true;
584 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
585 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
586 (uint64_t *)&generic_ptr, &len_of_buffer);
587 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
588 cmd_desc->offset);
589 cmn_hdr = (struct common_header *)cmd_buf;
590
591 switch (cmn_hdr->cmd_type) {
592 case CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET: {
593 CAM_DBG(CAM_FLASH, "Widget Flash Operation");
594 flash_operation_info =
595 (struct cam_flash_set_on_off *) cmd_buf;
596 fctrl->nrt_info.cmn_attr.count =
597 flash_operation_info->count;
598 fctrl->nrt_info.cmn_attr.request_id = 0;
599 fctrl->nrt_info.opcode =
600 flash_operation_info->opcode;
601 fctrl->nrt_info.cmn_attr.cmd_type =
602 CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET;
603
604 for (i = 0; i < flash_operation_info->count; i++)
605 fctrl->nrt_info.led_current_ma[i] =
606 flash_operation_info->led_current_ma[i];
607
608 mutex_lock(&fctrl->flash_wq_mutex);
609 rc = cam_flash_apply_setting(fctrl, 0);
610 if (rc)
611 CAM_ERR(CAM_FLASH, "Apply setting failed: %d",
612 rc);
613 mutex_unlock(&fctrl->flash_wq_mutex);
614 return rc;
615 }
616 case CAMERA_SENSOR_FLASH_CMD_TYPE_QUERYCURR: {
617 int query_curr_ma = 0;
618
619 flash_query_info =
620 (struct cam_flash_query_curr *)cmd_buf;
621
622 rc = qpnp_flash_led_prepare(fctrl->switch_trigger,
623 QUERY_MAX_CURRENT, &query_curr_ma);
624 CAM_DBG(CAM_FLASH, "query_curr_ma = %d",
625 query_curr_ma);
626 if (rc) {
627 CAM_ERR(CAM_FLASH,
628 "Query current failed with rc=%d", rc);
629 return rc;
630 }
631 flash_query_info->query_current_ma = query_curr_ma;
632 break;
633 }
634 case CAMERA_SENSOR_FLASH_CMD_TYPE_RER: {
635 rc = 0;
636 flash_rer_info = (struct cam_flash_set_rer *)cmd_buf;
637 fctrl->nrt_info.cmn_attr.cmd_type =
638 CAMERA_SENSOR_FLASH_CMD_TYPE_RER;
639 fctrl->nrt_info.opcode = flash_rer_info->opcode;
640 fctrl->nrt_info.cmn_attr.count = flash_rer_info->count;
641 fctrl->nrt_info.cmn_attr.request_id = 0;
642 fctrl->nrt_info.num_iterations =
643 flash_rer_info->num_iteration;
644 fctrl->nrt_info.led_on_delay_ms =
645 flash_rer_info->led_on_delay_ms;
646 fctrl->nrt_info.led_off_delay_ms =
647 flash_rer_info->led_off_delay_ms;
648
649 for (i = 0; i < flash_rer_info->count; i++)
650 fctrl->nrt_info.led_current_ma[i] =
651 flash_rer_info->led_current_ma[i];
652
653
654 mutex_lock(&fctrl->flash_wq_mutex);
655 rc = cam_flash_apply_setting(fctrl, 0);
656 if (rc)
657 CAM_ERR(CAM_FLASH, "apply_setting failed: %d",
658 rc);
659 mutex_unlock(&fctrl->flash_wq_mutex);
660 return rc;
661 }
662 default:
663 CAM_ERR(CAM_FLASH, "Wrong cmd_type : %d",
664 cmn_hdr->cmd_type);
665 return -EINVAL;
666 }
667
668 break;
669 }
670 case CAM_PKT_NOP_OPCODE: {
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700671 CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
672 csl_packet->header.request_id);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700673 goto update_req_mgr;
674 }
675 default:
676 CAM_ERR(CAM_FLASH, "Wrong Opcode : %d",
677 (csl_packet->header.op_code & 0xFFFFFF));
678 return -EINVAL;
679 }
680update_req_mgr:
681 if (((csl_packet->header.op_code & 0xFFFFF) ==
682 CAM_PKT_NOP_OPCODE) ||
683 ((csl_packet->header.op_code & 0xFFFFF) ==
684 CAM_FLASH_PACKET_OPCODE_SET_OPS)) {
685 add_req.link_hdl = fctrl->bridge_intf.link_hdl;
686 add_req.req_id = csl_packet->header.request_id;
687 add_req.dev_hdl = fctrl->bridge_intf.device_hdl;
Sagar Gorea4d7dfd2017-09-13 19:56:24 -0700688
689 if ((csl_packet->header.op_code & 0xFFFFF) ==
690 CAM_FLASH_PACKET_OPCODE_SET_OPS)
691 add_req.skip_before_applying = 1;
692 else
693 add_req.skip_before_applying = 0;
694
Jigarkumar Zala35226272017-04-19 16:05:24 -0700695 if (fctrl->bridge_intf.crm_cb &&
696 fctrl->bridge_intf.crm_cb->add_req)
697 fctrl->bridge_intf.crm_cb->add_req(&add_req);
698 CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id);
699 }
700
701 return rc;
702}
703
704int cam_flash_publish_dev_info(struct cam_req_mgr_device_info *info)
705{
706 info->dev_id = CAM_REQ_MGR_DEVICE_FLASH;
707 strlcpy(info->name, CAM_FLASH_NAME, sizeof(info->name));
708 info->p_delay = CAM_FLASH_PIPELINE_DELAY;
Sagar Gorea4d7dfd2017-09-13 19:56:24 -0700709 info->trigger = CAM_TRIGGER_POINT_SOF;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700710 return 0;
711}
712
713int cam_flash_establish_link(struct cam_req_mgr_core_dev_link_setup *link)
714{
715 struct cam_flash_ctrl *fctrl = NULL;
716
717 if (!link)
718 return -EINVAL;
719
720 fctrl = (struct cam_flash_ctrl *)cam_get_device_priv(link->dev_hdl);
721 if (!fctrl) {
722 CAM_ERR(CAM_FLASH, " Device data is NULL");
723 return -EINVAL;
724 }
725
726 if (link->link_enable) {
727 fctrl->bridge_intf.link_hdl = link->link_hdl;
728 fctrl->bridge_intf.crm_cb = link->crm_cb;
729 } else {
730 fctrl->bridge_intf.link_hdl = -1;
731 fctrl->bridge_intf.crm_cb = NULL;
732 }
733
734 return 0;
735}
736
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700737
738int cam_flash_stop_dev(struct cam_flash_ctrl *fctrl)
Jigarkumar Zala35226272017-04-19 16:05:24 -0700739{
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700740 int rc = 0, i, j;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700741
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700742 if ((fctrl->flash_state == CAM_FLASH_STATE_LOW) ||
743 (fctrl->flash_state == CAM_FLASH_STATE_HIGH))
744 cam_flash_off(fctrl);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700745
746 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
747 fctrl->per_frame[i].cmn_attr.request_id = 0;
748 fctrl->per_frame[i].cmn_attr.is_settings_valid = false;
749 fctrl->per_frame[i].cmn_attr.count = 0;
750 for (j = 0; j < CAM_FLASH_MAX_LED_TRIGGERS; j++)
751 fctrl->per_frame[i].led_current_ma[j] = 0;
752 }
753
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700754 rc = cam_flash_flush_nrt(fctrl);
755 if (rc) {
756 CAM_ERR(CAM_FLASH,
757 "NonRealTime Dev flush failed rc: %d", rc);
758 return rc;
759 }
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700760
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700761 if ((fctrl->flash_state == CAM_FLASH_STATE_START) &&
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700762 (fctrl->is_regulator_enabled == true)) {
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700763 rc = cam_flash_prepare(fctrl, CAM_FLASH_STATE_STOP);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700764 if (rc)
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700765 CAM_ERR(CAM_FLASH, "Disable Regulator Failed rc: %d",
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700766 rc);
767 }
768
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700769 return rc;
770}
771
772int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
773{
774 int rc = 0;
775
776 if (fctrl->bridge_intf.device_hdl != 1) {
777 rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700778 if (rc)
779 CAM_ERR(CAM_FLASH,
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700780 "Failed in destroying device handle rc = %d",
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700781 rc);
782 fctrl->bridge_intf.device_hdl = -1;
783 fctrl->bridge_intf.link_hdl = -1;
784 fctrl->bridge_intf.session_hdl = -1;
785 }
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700786
787 return rc;
788}
789
790void cam_flash_shutdown(struct cam_flash_ctrl *fctrl)
791{
792 int rc;
793
794 if (fctrl->flash_state == CAM_FLASH_STATE_INIT)
795 return;
796
797 if (fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE) {
798 cam_flash_release_dev(fctrl);
799 return;
800 }
801
802 rc = cam_flash_stop_dev(fctrl);
803 if (rc)
804 CAM_ERR(CAM_FLASH, "Stop Failed rc: %d", rc);
805
806 rc = cam_flash_release_dev(fctrl);
807 if (rc)
808 CAM_ERR(CAM_FLASH, "Release failed rc: %d", rc);
809
810 fctrl->flash_state = CAM_FLASH_STATE_INIT;
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700811}
812
Jigarkumar Zala35226272017-04-19 16:05:24 -0700813int cam_flash_apply_request(struct cam_req_mgr_apply_request *apply)
814{
815 int rc = 0;
816 struct cam_flash_ctrl *fctrl = NULL;
817
818 if (!apply)
819 return -EINVAL;
820
821 fctrl = (struct cam_flash_ctrl *) cam_get_device_priv(apply->dev_hdl);
822 if (!fctrl) {
823 CAM_ERR(CAM_FLASH, "Device data is NULL");
824 rc = -EINVAL;
825 goto free_resource;
826 }
827
828 if (!(apply->report_if_bubble)) {
829 mutex_lock(&fctrl->flash_wq_mutex);
830 rc = cam_flash_apply_setting(fctrl, apply->request_id);
831 if (rc)
832 CAM_ERR(CAM_FLASH, "apply_setting failed with rc=%d",
833 rc);
834 mutex_unlock(&fctrl->flash_wq_mutex);
835 }
836
837free_resource:
838 return rc;
839}