blob: ff0d32c7f598dbb45106f9f128678a3c489ea911 [file] [log] [blame]
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -08001/* 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#include <cam_sensor_cmn_header.h>
15#include "cam_actuator_core.h"
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060016#include "cam_sensor_util.h"
17#include "cam_trace.h"
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080018
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -070019static int32_t cam_actuator_i2c_modes_util(
20 struct camera_io_master *io_master_info,
21 struct i2c_settings_list *i2c_list)
22{
23 int32_t rc = 0;
24 uint32_t i, size;
25
26 if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
27 rc = camera_io_dev_write(io_master_info,
28 &(i2c_list->i2c_settings));
29 if (rc < 0) {
30 CAM_ERR(CAM_ACTUATOR,
31 "Failed to random write I2C settings: %d",
32 rc);
33 return rc;
34 }
35 } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
36 rc = camera_io_dev_write_continuous(
37 io_master_info,
38 &(i2c_list->i2c_settings),
39 0);
40 if (rc < 0) {
41 CAM_ERR(CAM_ACTUATOR,
42 "Failed to seq write I2C settings: %d",
43 rc);
44 return rc;
45 }
46 } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_BURST) {
47 rc = camera_io_dev_write_continuous(
48 io_master_info,
49 &(i2c_list->i2c_settings),
50 1);
51 if (rc < 0) {
52 CAM_ERR(CAM_ACTUATOR,
53 "Failed to burst write I2C settings: %d",
54 rc);
55 return rc;
56 }
57 } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
58 size = i2c_list->i2c_settings.size;
59 for (i = 0; i < size; i++) {
60 rc = camera_io_dev_poll(
61 io_master_info,
62 i2c_list->i2c_settings.
63 reg_setting[i].reg_addr,
64 i2c_list->i2c_settings.
65 reg_setting[i].reg_data,
66 i2c_list->i2c_settings.
67 reg_setting[i].data_mask,
68 i2c_list->i2c_settings.addr_type,
69 i2c_list->i2c_settings.data_type,
70 i2c_list->i2c_settings.
71 reg_setting[i].delay);
72 if (rc < 0) {
73 CAM_ERR(CAM_ACTUATOR,
74 "i2c poll apply setting Fail: %d", rc);
75 return rc;
76 }
77 }
78 }
79
80 return rc;
81}
82
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080083int32_t cam_actuator_slaveInfo_pkt_parser(struct cam_actuator_ctrl_t *a_ctrl,
84 uint32_t *cmd_buf)
85{
86 int32_t rc = 0;
87 struct cam_cmd_i2c_info *i2c_info;
88
89 if (!a_ctrl || !cmd_buf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070090 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080091 return -EINVAL;
92 }
93
94 i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
Jigarkumar Zalaae152332017-07-18 17:21:48 -070095 if (a_ctrl->io_master_info.master_type == CCI_MASTER) {
Depeng Shao0fe56182017-09-25 11:13:48 +080096 a_ctrl->io_master_info.cci_client->cci_i2c_master =
97 a_ctrl->cci_i2c_master;
Jigarkumar Zalaae152332017-07-18 17:21:48 -070098 a_ctrl->io_master_info.cci_client->i2c_freq_mode =
99 i2c_info->i2c_freq_mode;
100 a_ctrl->io_master_info.cci_client->sid =
101 i2c_info->slave_addr >> 1;
102 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x Freq Mode: %d",
103 i2c_info->slave_addr, i2c_info->i2c_freq_mode);
104 } else if (a_ctrl->io_master_info.master_type == I2C_MASTER) {
105 a_ctrl->io_master_info.client->addr = i2c_info->slave_addr;
106 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x", i2c_info->slave_addr);
107 } else {
108 CAM_ERR(CAM_ACTUATOR, "Invalid Master type: %d",
109 a_ctrl->io_master_info.master_type);
110 rc = -EINVAL;
111 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800112
113 return rc;
114}
115
116int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
117 struct i2c_settings_array *i2c_set)
118{
119 struct i2c_settings_list *i2c_list;
120 int32_t rc = 0;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800121
122 if (a_ctrl == NULL || i2c_set == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700123 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800124 return -EINVAL;
125 }
126
127 if (i2c_set->is_settings_valid != 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700128 CAM_ERR(CAM_ACTUATOR, " Invalid settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800129 return -EINVAL;
130 }
131
132 list_for_each_entry(i2c_list,
133 &(i2c_set->list_head), list) {
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700134 rc = cam_actuator_i2c_modes_util(
135 &(a_ctrl->io_master_info),
136 i2c_list);
137 if (rc < 0) {
138 CAM_ERR(CAM_ACTUATOR,
139 "Failed to apply settings: %d",
140 rc);
141 return rc;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800142 }
143 }
144
145 return rc;
146}
147
148int32_t cam_actuator_apply_request(struct cam_req_mgr_apply_request *apply)
149{
150 int32_t rc = 0, request_id, del_req_id;
151 struct cam_actuator_ctrl_t *a_ctrl = NULL;
152
153 if (!apply) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700154 CAM_ERR(CAM_ACTUATOR, "Invalid Input Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800155 return -EINVAL;
156 }
157
158 a_ctrl = (struct cam_actuator_ctrl_t *)
159 cam_get_device_priv(apply->dev_hdl);
160 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700161 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800162 return -EINVAL;
163 }
164 request_id = apply->request_id % MAX_PER_FRAME_ARRAY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600165
Junzhe Zou5fa08b12017-08-15 10:08:12 -0700166 trace_cam_apply_req("Actuator", apply->request_id);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600167
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700168 CAM_DBG(CAM_ACTUATOR, "Request Id: %lld", apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800169
170 if ((apply->request_id ==
171 a_ctrl->i2c_data.per_frame[request_id].request_id) &&
172 (a_ctrl->i2c_data.per_frame[request_id].is_settings_valid)
173 == 1) {
174 rc = cam_actuator_apply_settings(a_ctrl,
175 &a_ctrl->i2c_data.per_frame[request_id]);
176 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700177 CAM_ERR(CAM_ACTUATOR,
178 "Failed in applying the request: %lld\n",
179 apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800180 return rc;
181 }
182 }
183 del_req_id = (request_id +
184 MAX_PER_FRAME_ARRAY - MAX_SYSTEM_PIPELINE_DELAY) %
185 MAX_PER_FRAME_ARRAY;
186
187 if (apply->request_id >
188 a_ctrl->i2c_data.per_frame[del_req_id].request_id) {
189 a_ctrl->i2c_data.per_frame[del_req_id].request_id = 0;
190 rc = delete_request(&a_ctrl->i2c_data.per_frame[del_req_id]);
191 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700192 CAM_ERR(CAM_ACTUATOR,
193 "Fail deleting the req: %d err: %d\n",
194 del_req_id, rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800195 return rc;
196 }
197 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700198 CAM_DBG(CAM_ACTUATOR, "No Valid Req to clean Up");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800199 }
200
201 return rc;
202}
203
204int32_t cam_actuator_establish_link(
205 struct cam_req_mgr_core_dev_link_setup *link)
206{
207 struct cam_actuator_ctrl_t *a_ctrl = NULL;
208
209 if (!link) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700210 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800211 return -EINVAL;
212 }
213
214 a_ctrl = (struct cam_actuator_ctrl_t *)
215 cam_get_device_priv(link->dev_hdl);
216 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700217 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800218 return -EINVAL;
219 }
220 if (link->link_enable) {
221 a_ctrl->bridge_intf.link_hdl = link->link_hdl;
222 a_ctrl->bridge_intf.crm_cb = link->crm_cb;
223 } else {
224 a_ctrl->bridge_intf.link_hdl = -1;
225 a_ctrl->bridge_intf.crm_cb = NULL;
226 }
227
228 return 0;
229}
230
231int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info)
232{
233 if (!info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700234 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800235 return -EINVAL;
236 }
237
238 info->dev_id = CAM_REQ_MGR_DEVICE_ACTUATOR;
239 strlcpy(info->name, CAM_ACTUATOR_NAME, sizeof(info->name));
240 info->p_delay = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -0700241 info->trigger = CAM_TRIGGER_POINT_SOF;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800242
243 return 0;
244}
245
246int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
247 void *arg)
248{
249 int32_t rc = 0;
250 uint64_t generic_ptr;
251 struct cam_control *ioctl_ctrl = NULL;
252 struct cam_packet *csl_packet = NULL;
253 struct cam_config_dev_cmd config;
254 struct i2c_data_settings *i2c_data = NULL;
255 struct i2c_settings_array *i2c_reg_settings = NULL;
256 struct cam_cmd_buf_desc *cmd_desc = NULL;
257 size_t len_of_buff = 0;
258 uint32_t *offset = NULL, *cmd_buf;
259 struct cam_req_mgr_add_request add_req;
260
261 if (!a_ctrl || !arg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700262 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800263 return -EINVAL;
264 }
265
266 ioctl_ctrl = (struct cam_control *)arg;
267 if (copy_from_user(&config, (void __user *) ioctl_ctrl->handle,
268 sizeof(config)))
269 return -EFAULT;
270 rc = cam_mem_get_cpu_buf(config.packet_handle,
271 (uint64_t *)&generic_ptr, &len_of_buff);
272 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700273 CAM_ERR(CAM_ACTUATOR, "Error in converting command Handle %d",
274 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800275 return rc;
276 }
277
278 if (config.offset > len_of_buff) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700279 CAM_ERR(CAM_ACTUATOR,
280 "offset is out of bounds: offset: %lld len: %zu",
281 config.offset, len_of_buff);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800282 return -EINVAL;
283 }
284
285 csl_packet = (struct cam_packet *)(generic_ptr +
286 config.offset);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700287 CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800288
289 if ((csl_packet->header.op_code & 0xFFFFFF) ==
290 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
291 i2c_data = &(a_ctrl->i2c_data);
292 i2c_reg_settings = &i2c_data->init_settings;
293
294 offset = (uint32_t *)&csl_packet->payload;
295 offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
296 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
297
298 if (csl_packet->num_cmd_buf != 2) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700299 CAM_ERR(CAM_ACTUATOR, "cmd Buffers in Init : %d",
300 csl_packet->num_cmd_buf);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800301 return -EINVAL;
302 }
303
304 rc = cam_mem_get_cpu_buf(cmd_desc[0].mem_handle,
305 (uint64_t *)&generic_ptr, &len_of_buff);
306 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700307 CAM_ERR(CAM_ACTUATOR, "Failed to get cpu buf");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800308 return rc;
309 }
310 cmd_buf = (uint32_t *)generic_ptr;
311 cmd_buf += cmd_desc->offset / sizeof(uint32_t);
312 rc = cam_actuator_slaveInfo_pkt_parser(a_ctrl, cmd_buf);
313 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700314 CAM_ERR(CAM_ACTUATOR, "Failed in parsing the pkt");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800315 return rc;
316 }
317 cmd_buf += (sizeof(struct cam_cmd_i2c_info)/sizeof(uint32_t));
318 i2c_data->init_settings.request_id = 0;
319 i2c_reg_settings->is_settings_valid = 1;
Soundrapandian Jeyaprakash320e75e2017-10-08 07:06:54 -0700320 rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800321 &cmd_desc[1], 1);
322 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700323 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
324 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800325 return rc;
326 }
327 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
328 CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS) {
329 a_ctrl->act_apply_state =
330 ACT_APPLY_SETTINGS_NOW;
331
332 i2c_data = &(a_ctrl->i2c_data);
333 i2c_reg_settings = &i2c_data->init_settings;
334
335 i2c_data->init_settings.request_id =
336 csl_packet->header.request_id;
337 i2c_reg_settings->is_settings_valid = 1;
338 offset = (uint32_t *)&csl_packet->payload;
339 offset += csl_packet->cmd_buf_offset / sizeof(uint32_t);
340 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
Soundrapandian Jeyaprakash320e75e2017-10-08 07:06:54 -0700341 rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800342 cmd_desc, 1);
343 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700344 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
345 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800346 return rc;
347 }
348 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
349 CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS) {
350 i2c_data = &(a_ctrl->i2c_data);
351 i2c_reg_settings =
352 &i2c_data->per_frame
353 [csl_packet->header.request_id % MAX_PER_FRAME_ARRAY];
354
355 i2c_data->init_settings.request_id =
356 csl_packet->header.request_id;
357 i2c_reg_settings->is_settings_valid = 1;
358 offset = (uint32_t *)&csl_packet->payload;
359 offset += csl_packet->cmd_buf_offset / sizeof(uint32_t);
360 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
Soundrapandian Jeyaprakash320e75e2017-10-08 07:06:54 -0700361 rc = cam_sensor_i2c_command_parser(i2c_reg_settings,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800362 cmd_desc, 1);
363 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700364 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
365 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800366 return rc;
367 }
368 }
369
370 if ((csl_packet->header.op_code & 0xFFFFFF) !=
371 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
372 add_req.link_hdl = a_ctrl->bridge_intf.link_hdl;
373 add_req.req_id = csl_packet->header.request_id;
374 add_req.dev_hdl = a_ctrl->bridge_intf.device_hdl;
Sagar Gorea4d7dfd2017-09-13 19:56:24 -0700375 add_req.skip_before_applying = 0;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800376 if (a_ctrl->bridge_intf.crm_cb &&
377 a_ctrl->bridge_intf.crm_cb->add_req)
378 a_ctrl->bridge_intf.crm_cb->add_req(&add_req);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700379 CAM_DBG(CAM_ACTUATOR, "Req Id: %lld added to Bridge",
380 add_req.req_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800381 }
382
383 return rc;
384}
385
Alok Pandey01b1b352017-06-25 20:38:54 +0530386static int32_t cam_actuator_vreg_control(
387 struct cam_actuator_ctrl_t *a_ctrl,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800388 int config)
389{
Alok Pandey01b1b352017-06-25 20:38:54 +0530390 int rc = 0, cnt;
391 struct cam_hw_soc_info *soc_info;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800392
Alok Pandey01b1b352017-06-25 20:38:54 +0530393 soc_info = &a_ctrl->soc_info;
394 cnt = soc_info->num_rgltr;
395
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800396 if (!cnt)
397 return 0;
398
Alok Pandey01b1b352017-06-25 20:38:54 +0530399 if (cnt >= CAM_SOC_MAX_REGULATOR) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700400 CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800401 return -EINVAL;
402 }
403
Shankar Ravi8a8cd382017-09-28 12:29:34 +0530404 if (config) {
405 rc = cam_soc_util_request_platform_resource(soc_info,
406 NULL, NULL);
Alok Pandey01b1b352017-06-25 20:38:54 +0530407 rc = cam_soc_util_enable_platform_resource(soc_info, false, 0,
408 false);
Shankar Ravi8a8cd382017-09-28 12:29:34 +0530409 } else {
Alok Pandey01b1b352017-06-25 20:38:54 +0530410 rc = cam_soc_util_disable_platform_resource(soc_info, false,
411 false);
Jigarkumar Zala4b863ab2017-10-08 12:27:22 -0700412 rc = cam_soc_util_release_platform_resource(soc_info);
Shankar Ravi8a8cd382017-09-28 12:29:34 +0530413 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800414
415 return rc;
416}
417
418static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
419{
420 int rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530421 struct cam_hw_soc_info *soc_info =
422 &a_ctrl->soc_info;
423 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800424
425 rc = cam_actuator_vreg_control(a_ctrl, 1);
426 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700427 CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800428 return rc;
429 }
430
Alok Pandey01b1b352017-06-25 20:38:54 +0530431 gpio_num_info = a_ctrl->gpio_num_info;
432
433 if (soc_info->gpio_data &&
434 gpio_num_info &&
435 gpio_num_info->valid[SENSOR_VAF] == 1) {
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800436 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530437 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800438 1);
439 }
440
441 /* VREG needs some delay to power up */
442 usleep_range(2000, 2050);
443
444 return rc;
445}
446
447static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
448{
449 int32_t rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530450 struct cam_hw_soc_info *soc_info =
451 &a_ctrl->soc_info;
452 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800453
Alok Pandey01b1b352017-06-25 20:38:54 +0530454 gpio_num_info = a_ctrl->gpio_num_info;
455
456 if (soc_info->gpio_data &&
457 gpio_num_info &&
458 gpio_num_info->valid[SENSOR_VAF] == 1) {
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800459
460 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530461 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800462 GPIOF_OUT_INIT_LOW);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800463 }
464
Jigarkumar Zala4b863ab2017-10-08 12:27:22 -0700465 rc = cam_actuator_vreg_control(a_ctrl, 0);
466 if (rc < 0)
467 CAM_ERR(CAM_ACTUATOR, "Disable Regulator Failed: %d", rc);
468
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800469 return rc;
470}
471
472int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
473 void *arg)
474{
475 int rc = 0;
476 struct cam_control *cmd = (struct cam_control *)arg;
477
478 if (!a_ctrl || !cmd) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700479 CAM_ERR(CAM_ACTUATOR, " Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800480 return -EINVAL;
481 }
482
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700483 pr_debug("Opcode to Actuator: %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800484
485 mutex_lock(&(a_ctrl->actuator_mutex));
486 switch (cmd->op_code) {
487 case CAM_ACQUIRE_DEV: {
488 struct cam_sensor_acquire_dev actuator_acq_dev;
489 struct cam_create_dev_hdl bridge_params;
490
491 if (a_ctrl->bridge_intf.device_hdl != -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700492 CAM_ERR(CAM_ACTUATOR, "Device is already acquired");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800493 rc = -EINVAL;
494 goto release_mutex;
495 }
496 rc = copy_from_user(&actuator_acq_dev,
497 (void __user *) cmd->handle,
498 sizeof(actuator_acq_dev));
499 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700500 CAM_ERR(CAM_ACTUATOR, "Failed Copying from user\n");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800501 goto release_mutex;
502 }
503
504 bridge_params.session_hdl = actuator_acq_dev.session_handle;
505 bridge_params.ops = &a_ctrl->bridge_intf.ops;
506 bridge_params.v4l2_sub_dev_flag = 0;
507 bridge_params.media_entity_flag = 0;
508 bridge_params.priv = a_ctrl;
509
510 actuator_acq_dev.device_handle =
511 cam_create_device_hdl(&bridge_params);
512 a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
513 a_ctrl->bridge_intf.session_hdl =
514 actuator_acq_dev.session_handle;
515
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700516 CAM_DBG(CAM_ACTUATOR, "Device Handle: %d",
517 actuator_acq_dev.device_handle);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800518 if (copy_to_user((void __user *) cmd->handle, &actuator_acq_dev,
519 sizeof(struct cam_sensor_acquire_dev))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700520 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800521 rc = -EFAULT;
522 goto release_mutex;
523 }
524
525 }
526 break;
527 case CAM_RELEASE_DEV: {
528 if (a_ctrl->bridge_intf.device_hdl == -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700529 CAM_ERR(CAM_ACTUATOR, "link hdl: %d device hdl: %d",
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800530 a_ctrl->bridge_intf.device_hdl,
531 a_ctrl->bridge_intf.link_hdl);
532 rc = -EINVAL;
533 goto release_mutex;
534 }
535 rc = cam_destroy_device_hdl(a_ctrl->bridge_intf.device_hdl);
536 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700537 CAM_ERR(CAM_ACTUATOR, "destroying the device hdl");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800538 a_ctrl->bridge_intf.device_hdl = -1;
539 a_ctrl->bridge_intf.link_hdl = -1;
540 a_ctrl->bridge_intf.session_hdl = -1;
541 }
542 break;
543 case CAM_QUERY_CAP: {
Soundrapandian Jeyaprakashc22f42a2017-07-28 17:33:44 -0700544 struct cam_actuator_query_cap actuator_cap = {0};
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800545
Depeng Shao0fe56182017-09-25 11:13:48 +0800546 actuator_cap.slot_info = a_ctrl->soc_info.index;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800547 if (copy_to_user((void __user *) cmd->handle, &actuator_cap,
548 sizeof(struct cam_actuator_query_cap))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700549 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800550 rc = -EFAULT;
551 goto release_mutex;
552 }
553 }
554 break;
555 case CAM_START_DEV: {
556 rc = cam_actuator_power_up(a_ctrl);
557 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700558 CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800559 goto release_mutex;
560 }
561 rc = camera_io_init(&a_ctrl->io_master_info);
562 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700563 CAM_ERR(CAM_ACTUATOR, "cci_init failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800564 cam_actuator_power_down(a_ctrl);
565 }
566
567 rc = cam_actuator_apply_settings(a_ctrl,
568 &a_ctrl->i2c_data.init_settings);
569 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700570 CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800571
572 /* Delete the request even if the apply is failed */
573 rc = delete_request(&a_ctrl->i2c_data.init_settings);
574 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700575 CAM_ERR(CAM_ACTUATOR,
576 "Fail in deleting the Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800577 rc = -EINVAL;
578 goto release_mutex;
579 }
580 }
581 break;
582 case CAM_STOP_DEV: {
Soundrapandian Jeyaprakashc88238b2017-10-10 20:28:39 -0700583 struct i2c_settings_array *i2c_set = NULL;
584 int i;
585
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800586 rc = camera_io_release(&a_ctrl->io_master_info);
587 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700588 CAM_ERR(CAM_ACTUATOR, "Failed in releasing CCI");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800589 rc = cam_actuator_power_down(a_ctrl);
590 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700591 CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800592 goto release_mutex;
593 }
Soundrapandian Jeyaprakashc88238b2017-10-10 20:28:39 -0700594 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
595 i2c_set = &(a_ctrl->i2c_data.per_frame[i]);
596
597 if (i2c_set->is_settings_valid == 1) {
598 rc = delete_request(i2c_set);
599 if (rc < 0)
600 CAM_ERR(CAM_SENSOR,
601 "delete request: %lld rc: %d",
602 i2c_set->request_id, rc);
603 }
604 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800605 }
606 break;
607 case CAM_CONFIG_DEV: {
608 a_ctrl->act_apply_state =
609 ACT_APPLY_SETTINGS_LATER;
610 rc = cam_actuator_i2c_pkt_parse(a_ctrl, arg);
611 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700612 CAM_ERR(CAM_ACTUATOR, "Failed in actuator Parsing");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800613 }
614
615 if (a_ctrl->act_apply_state ==
616 ACT_APPLY_SETTINGS_NOW) {
617 rc = cam_actuator_apply_settings(a_ctrl,
618 &a_ctrl->i2c_data.init_settings);
619 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700620 CAM_ERR(CAM_ACTUATOR,
621 "Cannot apply Update settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800622
623 /* Delete the request even if the apply is failed */
624 rc = delete_request(&a_ctrl->i2c_data.init_settings);
625 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700626 CAM_ERR(CAM_ACTUATOR,
627 "Failed in Deleting the Init Pkt: %d",
628 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800629 goto release_mutex;
630 }
631 }
632 }
633 break;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700634 case CAM_SD_SHUTDOWN:
635 break;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800636 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700637 CAM_ERR(CAM_ACTUATOR, "Invalid Opcode %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800638 }
639
640release_mutex:
641 mutex_unlock(&(a_ctrl->actuator_mutex));
642
643 return rc;
644}
Soundrapandian Jeyaprakashc88238b2017-10-10 20:28:39 -0700645
646int32_t cam_actuator_flush_request(struct cam_req_mgr_flush_request *flush_req)
647{
648 int32_t rc = 0, i;
649 uint32_t cancel_req_id_found = 0;
650 struct cam_actuator_ctrl_t *a_ctrl = NULL;
651 struct i2c_settings_array *i2c_set = NULL;
652
653 if (!flush_req)
654 return -EINVAL;
655
656 a_ctrl = (struct cam_actuator_ctrl_t *)
657 cam_get_device_priv(flush_req->dev_hdl);
658 if (!a_ctrl) {
659 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
660 return -EINVAL;
661 }
662
663 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
664 i2c_set = &(a_ctrl->i2c_data.per_frame[i]);
665
666 if ((flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ)
667 && (i2c_set->request_id != flush_req->req_id))
668 continue;
669
670 if (i2c_set->is_settings_valid == 1) {
671 rc = delete_request(i2c_set);
672 if (rc < 0)
673 CAM_ERR(CAM_ACTUATOR,
674 "delete request: %lld rc: %d",
675 i2c_set->request_id, rc);
676
677 if (flush_req->type ==
678 CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
679 cancel_req_id_found = 1;
680 break;
681 }
682 }
683 }
684
685 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ &&
686 !cancel_req_id_found)
687 CAM_DBG(CAM_ACTUATOR,
688 "Flush request id:%lld not found in the pending list",
689 flush_req->req_id);
690 return rc;
691}