blob: c977fc45161860a7039c46a20c0b17b0858d5b04 [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,
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -080020 bool regulator_enable)
Jigarkumar Zala35226272017-04-19 16:05:24 -070021{
22 int rc = 0;
23
24 if (!(flash_ctrl->switch_trigger)) {
25 CAM_ERR(CAM_FLASH, "Invalid argument");
26 return -EINVAL;
27 }
28
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -080029 if (regulator_enable &&
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;
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -080040 } else if ((!regulator_enable) &&
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 }
326 } else if (flash_data->opcode ==
327 CAMERA_SENSOR_FLASH_OP_OFF) {
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800328 rc = cam_flash_off(fctrl);
329 if (rc)
330 CAM_ERR(CAM_FLASH,
331 "LED off failed: %d",
332 rc);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700333 }
334 } else if (fctrl->nrt_info.cmn_attr.cmd_type ==
335 CAMERA_SENSOR_FLASH_CMD_TYPE_RER) {
336 flash_data = &fctrl->nrt_info;
337
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700338 if (fctrl->flash_state != CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700339 rc = cam_flash_off(fctrl);
340 if (rc) {
341 CAM_ERR(CAM_FLASH,
342 "Flash off failed: %d",
343 rc);
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700344 goto nrt_del_req;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700345 }
346 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700347 num_iterations = flash_data->num_iterations;
348 for (i = 0; i < num_iterations; i++) {
349 /* Turn On Torch */
350 if (fctrl->flash_state ==
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700351 CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700352 rc = cam_flash_low(fctrl, flash_data);
353 if (rc) {
354 CAM_ERR(CAM_FLASH,
355 "Fire Torch Failed");
356 goto nrt_del_req;
357 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700358
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700359 usleep_range(
360 flash_data->led_on_delay_ms * 1000,
361 flash_data->led_on_delay_ms * 1000 +
362 100);
363 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700364 /* Turn Off Torch */
365 rc = cam_flash_off(fctrl);
366 if (rc) {
367 CAM_ERR(CAM_FLASH,
368 "Flash off failed: %d",
369 rc);
370 continue;
371 }
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700372 fctrl->flash_state = CAM_FLASH_STATE_START;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700373 usleep_range(
374 flash_data->led_off_delay_ms * 1000,
375 flash_data->led_off_delay_ms * 1000 + 100);
376 }
377 }
378 } else {
379 frame_offset = req_id % MAX_PER_FRAME_ARRAY;
380 flash_data = &fctrl->per_frame[frame_offset];
381
382 if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_FIREHIGH) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700383 (flash_data->cmn_attr.is_settings_valid) &&
384 (flash_data->cmn_attr.request_id == req_id)) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700385 /* Turn On Flash */
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700386 if (fctrl->flash_state == CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700387 rc = cam_flash_high(fctrl, flash_data);
388 if (rc) {
389 CAM_ERR(CAM_FLASH,
390 "Flash ON failed: rc= %d",
391 rc);
392 goto apply_setting_err;
393 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700394 }
395 } else if ((flash_data->opcode ==
396 CAMERA_SENSOR_FLASH_OP_FIRELOW) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700397 (flash_data->cmn_attr.is_settings_valid) &&
398 (flash_data->cmn_attr.request_id == req_id)) {
Shankar Ravib6f86fd2017-08-11 16:31:33 +0530399 /* Turn On Torch */
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700400 if (fctrl->flash_state == CAM_FLASH_STATE_START) {
Jigarkumar Zala35226272017-04-19 16:05:24 -0700401 rc = cam_flash_low(fctrl, flash_data);
402 if (rc) {
403 CAM_ERR(CAM_FLASH,
404 "Torch ON failed: rc= %d",
405 rc);
406 goto apply_setting_err;
407 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700408 }
409 } else if ((flash_data->opcode == CAMERA_SENSOR_FLASH_OP_OFF) &&
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700410 (flash_data->cmn_attr.is_settings_valid) &&
411 (flash_data->cmn_attr.request_id == req_id)) {
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800412 rc = cam_flash_off(fctrl);
413 if (rc) {
414 CAM_ERR(CAM_FLASH,
415 "Flash off failed %d", rc);
416 goto apply_setting_err;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700417 }
418 } else {
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700419 CAM_DBG(CAM_FLASH, "NOP opcode: req_id: %u", req_id);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700420 }
421 }
422
423nrt_del_req:
424 delete_req(fctrl, req_id);
425apply_setting_err:
426 return rc;
427}
428
429int cam_flash_parser(struct cam_flash_ctrl *fctrl, void *arg)
430{
431 int rc = 0, i = 0;
432 uint64_t generic_ptr;
433 uint32_t *cmd_buf = NULL;
434 uint32_t *offset = NULL;
435 uint32_t frame_offset = 0;
436 size_t len_of_buffer;
437 struct cam_control *ioctl_ctrl = NULL;
438 struct cam_packet *csl_packet = NULL;
439 struct cam_cmd_buf_desc *cmd_desc = NULL;
440 struct common_header *cmn_hdr;
441 struct cam_config_dev_cmd config;
442 struct cam_req_mgr_add_request add_req;
443 struct cam_flash_init *cam_flash_info = NULL;
444 struct cam_flash_set_rer *flash_rer_info = NULL;
445 struct cam_flash_set_on_off *flash_operation_info = NULL;
446 struct cam_flash_query_curr *flash_query_info = NULL;
447
448 if (!fctrl || !arg) {
449 CAM_ERR(CAM_FLASH, "fctrl/arg is NULL");
450 return -EINVAL;
451 }
452 /* getting CSL Packet */
453 ioctl_ctrl = (struct cam_control *)arg;
454
455 if (copy_from_user((&config), (void __user *) ioctl_ctrl->handle,
456 sizeof(config))) {
457 CAM_ERR(CAM_FLASH, "Copy cmd handle from user failed");
458 rc = -EFAULT;
459 return rc;
460 }
461
462 rc = cam_mem_get_cpu_buf(config.packet_handle,
463 (uint64_t *)&generic_ptr, &len_of_buffer);
464 if (rc) {
465 CAM_ERR(CAM_FLASH, "Failed in getting the buffer : %d", rc);
466 return rc;
467 }
468
Shankar Ravib6f86fd2017-08-11 16:31:33 +0530469 if (config.offset > len_of_buffer) {
470 CAM_ERR(CAM_FLASH,
471 "offset is out of bounds: offset: %lld len: %zu",
472 config.offset, len_of_buffer);
473 return -EINVAL;
474 }
475
476 /* Add offset to the flash csl header */
477 csl_packet = (struct cam_packet *)(generic_ptr + config.offset);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700478
479 switch (csl_packet->header.op_code & 0xFFFFFF) {
480 case CAM_FLASH_PACKET_OPCODE_INIT: {
481 /* INIT packet*/
482 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
483 csl_packet->cmd_buf_offset);
484 fctrl->flash_init_setting.cmn_attr.request_id = 0;
485 fctrl->flash_init_setting.cmn_attr.is_settings_valid = true;
486 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
487 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
488 (uint64_t *)&generic_ptr, &len_of_buffer);
489 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
490 cmd_desc->offset);
491 cam_flash_info = (struct cam_flash_init *)cmd_buf;
492
493 switch (cam_flash_info->cmd_type) {
494 case CAMERA_SENSOR_FLASH_CMD_TYPE_INIT:
495 fctrl->flash_type = cam_flash_info->flash_type;
496 fctrl->is_regulator_enabled = false;
497 fctrl->nrt_info.cmn_attr.cmd_type =
498 CAMERA_SENSOR_FLASH_CMD_TYPE_INIT;
499 break;
500 default:
501 CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
502 cam_flash_info->cmd_type);
503 return -EINVAL;
504 }
505 break;
506 }
507 case CAM_FLASH_PACKET_OPCODE_SET_OPS: {
508 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
509 csl_packet->cmd_buf_offset);
510 frame_offset = csl_packet->header.request_id %
511 MAX_PER_FRAME_ARRAY;
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700512 if (fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid
513 == true) {
514 fctrl->per_frame[frame_offset].cmn_attr.request_id = 0;
515 fctrl->per_frame[frame_offset].
516 cmn_attr.is_settings_valid = false;
517 for (i = 0;
518 i < fctrl->per_frame[frame_offset].cmn_attr.count;
519 i++) {
520 fctrl->per_frame[frame_offset].
521 led_current_ma[i] = 0;
522 }
523 }
524
Jigarkumar Zala35226272017-04-19 16:05:24 -0700525 fctrl->per_frame[frame_offset].cmn_attr.request_id =
526 csl_packet->header.request_id;
527 fctrl->per_frame[frame_offset].cmn_attr.is_settings_valid =
528 true;
529 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
530 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
531 (uint64_t *)&generic_ptr, &len_of_buffer);
532 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
533 cmd_desc->offset);
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700534
535 if (!cmd_buf)
536 return -EINVAL;
537
Jigarkumar Zala35226272017-04-19 16:05:24 -0700538 cmn_hdr = (struct common_header *)cmd_buf;
539
540 switch (cmn_hdr->cmd_type) {
541 case CAMERA_SENSOR_FLASH_CMD_TYPE_FIRE: {
542 CAM_DBG(CAM_FLASH,
543 "CAMERA_FLASH_CMD_TYPE_OPS case called");
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800544 if (fctrl->flash_state != CAM_FLASH_STATE_START) {
545 CAM_ERR(CAM_FLASH,
546 "Rxed Update packets without linking");
547 fctrl->per_frame[frame_offset].
548 cmn_attr.is_settings_valid = false;
549 return -EINVAL;
550 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700551 flash_operation_info =
552 (struct cam_flash_set_on_off *) cmd_buf;
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700553 if (!flash_operation_info) {
554 CAM_ERR(CAM_FLASH, "flash_operation_info Null");
555 return -EINVAL;
556 }
557
Jigarkumar Zala35226272017-04-19 16:05:24 -0700558 fctrl->per_frame[frame_offset].opcode =
559 flash_operation_info->opcode;
560 fctrl->per_frame[frame_offset].cmn_attr.count =
561 flash_operation_info->count;
562 for (i = 0; i < flash_operation_info->count; i++)
563 fctrl->per_frame[frame_offset].led_current_ma[i]
564 = flash_operation_info->
565 led_current_ma[i];
566 break;
567 }
568 default:
569 CAM_ERR(CAM_FLASH, "Wrong cmd_type = %d",
570 cmn_hdr->cmd_type);
571 return -EINVAL;
572 }
Jigarkumar Zala35226272017-04-19 16:05:24 -0700573 break;
574 }
575 case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
576 offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
577 csl_packet->cmd_buf_offset);
578 fctrl->nrt_info.cmn_attr.is_settings_valid = true;
579 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
580 rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle,
581 (uint64_t *)&generic_ptr, &len_of_buffer);
582 cmd_buf = (uint32_t *)((uint8_t *)generic_ptr +
583 cmd_desc->offset);
584 cmn_hdr = (struct common_header *)cmd_buf;
585
586 switch (cmn_hdr->cmd_type) {
587 case CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET: {
588 CAM_DBG(CAM_FLASH, "Widget Flash Operation");
589 flash_operation_info =
590 (struct cam_flash_set_on_off *) cmd_buf;
591 fctrl->nrt_info.cmn_attr.count =
592 flash_operation_info->count;
593 fctrl->nrt_info.cmn_attr.request_id = 0;
594 fctrl->nrt_info.opcode =
595 flash_operation_info->opcode;
596 fctrl->nrt_info.cmn_attr.cmd_type =
597 CAMERA_SENSOR_FLASH_CMD_TYPE_WIDGET;
598
599 for (i = 0; i < flash_operation_info->count; i++)
600 fctrl->nrt_info.led_current_ma[i] =
601 flash_operation_info->led_current_ma[i];
602
603 mutex_lock(&fctrl->flash_wq_mutex);
604 rc = cam_flash_apply_setting(fctrl, 0);
605 if (rc)
606 CAM_ERR(CAM_FLASH, "Apply setting failed: %d",
607 rc);
608 mutex_unlock(&fctrl->flash_wq_mutex);
609 return rc;
610 }
611 case CAMERA_SENSOR_FLASH_CMD_TYPE_QUERYCURR: {
612 int query_curr_ma = 0;
613
614 flash_query_info =
615 (struct cam_flash_query_curr *)cmd_buf;
616
617 rc = qpnp_flash_led_prepare(fctrl->switch_trigger,
618 QUERY_MAX_CURRENT, &query_curr_ma);
619 CAM_DBG(CAM_FLASH, "query_curr_ma = %d",
620 query_curr_ma);
621 if (rc) {
622 CAM_ERR(CAM_FLASH,
623 "Query current failed with rc=%d", rc);
624 return rc;
625 }
626 flash_query_info->query_current_ma = query_curr_ma;
627 break;
628 }
629 case CAMERA_SENSOR_FLASH_CMD_TYPE_RER: {
630 rc = 0;
631 flash_rer_info = (struct cam_flash_set_rer *)cmd_buf;
632 fctrl->nrt_info.cmn_attr.cmd_type =
633 CAMERA_SENSOR_FLASH_CMD_TYPE_RER;
634 fctrl->nrt_info.opcode = flash_rer_info->opcode;
635 fctrl->nrt_info.cmn_attr.count = flash_rer_info->count;
636 fctrl->nrt_info.cmn_attr.request_id = 0;
637 fctrl->nrt_info.num_iterations =
638 flash_rer_info->num_iteration;
639 fctrl->nrt_info.led_on_delay_ms =
640 flash_rer_info->led_on_delay_ms;
641 fctrl->nrt_info.led_off_delay_ms =
642 flash_rer_info->led_off_delay_ms;
643
644 for (i = 0; i < flash_rer_info->count; i++)
645 fctrl->nrt_info.led_current_ma[i] =
646 flash_rer_info->led_current_ma[i];
647
648
649 mutex_lock(&fctrl->flash_wq_mutex);
650 rc = cam_flash_apply_setting(fctrl, 0);
651 if (rc)
652 CAM_ERR(CAM_FLASH, "apply_setting failed: %d",
653 rc);
654 mutex_unlock(&fctrl->flash_wq_mutex);
655 return rc;
656 }
657 default:
658 CAM_ERR(CAM_FLASH, "Wrong cmd_type : %d",
659 cmn_hdr->cmd_type);
660 return -EINVAL;
661 }
662
663 break;
664 }
665 case CAM_PKT_NOP_OPCODE: {
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800666 if (fctrl->flash_state != CAM_FLASH_STATE_START) {
667 CAM_ERR(CAM_FLASH,
668 "Rxed Update packets without linking");
669 fctrl->per_frame[frame_offset].
670 cmn_attr.is_settings_valid = false;
671 return -EINVAL;
672 }
673
Jigarkumar Zala7f1e5032017-09-22 16:39:30 -0700674 CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
675 csl_packet->header.request_id);
Jigarkumar Zala35226272017-04-19 16:05:24 -0700676 goto update_req_mgr;
677 }
678 default:
679 CAM_ERR(CAM_FLASH, "Wrong Opcode : %d",
680 (csl_packet->header.op_code & 0xFFFFFF));
681 return -EINVAL;
682 }
683update_req_mgr:
684 if (((csl_packet->header.op_code & 0xFFFFF) ==
685 CAM_PKT_NOP_OPCODE) ||
686 ((csl_packet->header.op_code & 0xFFFFF) ==
687 CAM_FLASH_PACKET_OPCODE_SET_OPS)) {
688 add_req.link_hdl = fctrl->bridge_intf.link_hdl;
689 add_req.req_id = csl_packet->header.request_id;
690 add_req.dev_hdl = fctrl->bridge_intf.device_hdl;
Sagar Gorea4d7dfd2017-09-13 19:56:24 -0700691
692 if ((csl_packet->header.op_code & 0xFFFFF) ==
693 CAM_FLASH_PACKET_OPCODE_SET_OPS)
694 add_req.skip_before_applying = 1;
695 else
696 add_req.skip_before_applying = 0;
697
Jigarkumar Zala35226272017-04-19 16:05:24 -0700698 if (fctrl->bridge_intf.crm_cb &&
699 fctrl->bridge_intf.crm_cb->add_req)
700 fctrl->bridge_intf.crm_cb->add_req(&add_req);
701 CAM_DBG(CAM_FLASH, "add req to req_mgr= %lld", add_req.req_id);
702 }
703
704 return rc;
705}
706
707int cam_flash_publish_dev_info(struct cam_req_mgr_device_info *info)
708{
709 info->dev_id = CAM_REQ_MGR_DEVICE_FLASH;
710 strlcpy(info->name, CAM_FLASH_NAME, sizeof(info->name));
711 info->p_delay = CAM_FLASH_PIPELINE_DELAY;
Sagar Gorea4d7dfd2017-09-13 19:56:24 -0700712 info->trigger = CAM_TRIGGER_POINT_SOF;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700713 return 0;
714}
715
716int cam_flash_establish_link(struct cam_req_mgr_core_dev_link_setup *link)
717{
718 struct cam_flash_ctrl *fctrl = NULL;
719
720 if (!link)
721 return -EINVAL;
722
723 fctrl = (struct cam_flash_ctrl *)cam_get_device_priv(link->dev_hdl);
724 if (!fctrl) {
725 CAM_ERR(CAM_FLASH, " Device data is NULL");
726 return -EINVAL;
727 }
728
729 if (link->link_enable) {
730 fctrl->bridge_intf.link_hdl = link->link_hdl;
731 fctrl->bridge_intf.crm_cb = link->crm_cb;
732 } else {
733 fctrl->bridge_intf.link_hdl = -1;
734 fctrl->bridge_intf.crm_cb = NULL;
735 }
736
737 return 0;
738}
739
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700740
741int cam_flash_stop_dev(struct cam_flash_ctrl *fctrl)
Jigarkumar Zala35226272017-04-19 16:05:24 -0700742{
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700743 int rc = 0, i, j;
Jigarkumar Zala35226272017-04-19 16:05:24 -0700744
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800745 cam_flash_off(fctrl);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700746
747 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
748 fctrl->per_frame[i].cmn_attr.request_id = 0;
749 fctrl->per_frame[i].cmn_attr.is_settings_valid = false;
750 fctrl->per_frame[i].cmn_attr.count = 0;
751 for (j = 0; j < CAM_FLASH_MAX_LED_TRIGGERS; j++)
752 fctrl->per_frame[i].led_current_ma[j] = 0;
753 }
754
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700755 rc = cam_flash_flush_nrt(fctrl);
756 if (rc) {
757 CAM_ERR(CAM_FLASH,
758 "NonRealTime Dev flush failed rc: %d", rc);
759 return rc;
760 }
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700761
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700762 if ((fctrl->flash_state == CAM_FLASH_STATE_START) &&
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700763 (fctrl->is_regulator_enabled == true)) {
Viswanadha Raju Thotakuraef9c8d02017-11-30 18:06:53 -0800764 rc = cam_flash_prepare(fctrl, false);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700765 if (rc)
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700766 CAM_ERR(CAM_FLASH, "Disable Regulator Failed rc: %d",
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700767 rc);
768 }
769
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700770 return rc;
771}
772
773int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
774{
775 int rc = 0;
776
777 if (fctrl->bridge_intf.device_hdl != 1) {
778 rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700779 if (rc)
780 CAM_ERR(CAM_FLASH,
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700781 "Failed in destroying device handle rc = %d",
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700782 rc);
783 fctrl->bridge_intf.device_hdl = -1;
784 fctrl->bridge_intf.link_hdl = -1;
785 fctrl->bridge_intf.session_hdl = -1;
786 }
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700787
788 return rc;
789}
790
791void cam_flash_shutdown(struct cam_flash_ctrl *fctrl)
792{
793 int rc;
794
795 if (fctrl->flash_state == CAM_FLASH_STATE_INIT)
796 return;
797
798 if (fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE) {
799 cam_flash_release_dev(fctrl);
800 return;
801 }
802
803 rc = cam_flash_stop_dev(fctrl);
804 if (rc)
805 CAM_ERR(CAM_FLASH, "Stop Failed rc: %d", rc);
806
807 rc = cam_flash_release_dev(fctrl);
808 if (rc)
809 CAM_ERR(CAM_FLASH, "Release failed rc: %d", rc);
810
811 fctrl->flash_state = CAM_FLASH_STATE_INIT;
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700812}
813
Jigarkumar Zala35226272017-04-19 16:05:24 -0700814int cam_flash_apply_request(struct cam_req_mgr_apply_request *apply)
815{
816 int rc = 0;
817 struct cam_flash_ctrl *fctrl = NULL;
818
819 if (!apply)
820 return -EINVAL;
821
822 fctrl = (struct cam_flash_ctrl *) cam_get_device_priv(apply->dev_hdl);
823 if (!fctrl) {
824 CAM_ERR(CAM_FLASH, "Device data is NULL");
825 rc = -EINVAL;
826 goto free_resource;
827 }
828
829 if (!(apply->report_if_bubble)) {
830 mutex_lock(&fctrl->flash_wq_mutex);
831 rc = cam_flash_apply_setting(fctrl, apply->request_id);
832 if (rc)
833 CAM_ERR(CAM_FLASH, "apply_setting failed with rc=%d",
834 rc);
835 mutex_unlock(&fctrl->flash_wq_mutex);
836 }
837
838free_resource:
839 return rc;
840}