blob: f8947e70a21be3d73ced7376f246f272d2d9c12a [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 {
410 rc = cam_soc_util_release_platform_resource(soc_info);
Alok Pandey01b1b352017-06-25 20:38:54 +0530411 rc = cam_soc_util_disable_platform_resource(soc_info, false,
412 false);
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) {
436 rc = cam_soc_util_request_platform_resource(&a_ctrl->soc_info,
437 NULL, NULL);
438 rc = cam_soc_util_enable_platform_resource(&a_ctrl->soc_info,
439 false, 0, false);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800440 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700441 CAM_ERR(CAM_ACTUATOR, "Failed in req gpio: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800442 return rc;
443 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800444
445 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530446 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800447 1);
448 }
449
450 /* VREG needs some delay to power up */
451 usleep_range(2000, 2050);
452
453 return rc;
454}
455
456static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
457{
458 int32_t rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530459 struct cam_hw_soc_info *soc_info =
460 &a_ctrl->soc_info;
461 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800462
463 rc = cam_actuator_vreg_control(a_ctrl, 0);
464 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700465 CAM_ERR(CAM_ACTUATOR, "Failed %d");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800466 return rc;
467 }
468
Alok Pandey01b1b352017-06-25 20:38:54 +0530469 gpio_num_info = a_ctrl->gpio_num_info;
470
471 if (soc_info->gpio_data &&
472 gpio_num_info &&
473 gpio_num_info->valid[SENSOR_VAF] == 1) {
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800474
475 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530476 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800477 GPIOF_OUT_INIT_LOW);
478
Alok Pandey01b1b352017-06-25 20:38:54 +0530479 rc = cam_soc_util_release_platform_resource(&a_ctrl->soc_info);
480 rc |= cam_soc_util_disable_platform_resource(&a_ctrl->soc_info,
481 0, 0);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800482 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700483 CAM_ERR(CAM_ACTUATOR,
484 "Failed to disable platform resources: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800485 }
486
487 return rc;
488}
489
490int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
491 void *arg)
492{
493 int rc = 0;
494 struct cam_control *cmd = (struct cam_control *)arg;
495
496 if (!a_ctrl || !cmd) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700497 CAM_ERR(CAM_ACTUATOR, " Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800498 return -EINVAL;
499 }
500
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700501 pr_debug("Opcode to Actuator: %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800502
503 mutex_lock(&(a_ctrl->actuator_mutex));
504 switch (cmd->op_code) {
505 case CAM_ACQUIRE_DEV: {
506 struct cam_sensor_acquire_dev actuator_acq_dev;
507 struct cam_create_dev_hdl bridge_params;
508
509 if (a_ctrl->bridge_intf.device_hdl != -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700510 CAM_ERR(CAM_ACTUATOR, "Device is already acquired");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800511 rc = -EINVAL;
512 goto release_mutex;
513 }
514 rc = copy_from_user(&actuator_acq_dev,
515 (void __user *) cmd->handle,
516 sizeof(actuator_acq_dev));
517 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700518 CAM_ERR(CAM_ACTUATOR, "Failed Copying from user\n");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800519 goto release_mutex;
520 }
521
522 bridge_params.session_hdl = actuator_acq_dev.session_handle;
523 bridge_params.ops = &a_ctrl->bridge_intf.ops;
524 bridge_params.v4l2_sub_dev_flag = 0;
525 bridge_params.media_entity_flag = 0;
526 bridge_params.priv = a_ctrl;
527
528 actuator_acq_dev.device_handle =
529 cam_create_device_hdl(&bridge_params);
530 a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
531 a_ctrl->bridge_intf.session_hdl =
532 actuator_acq_dev.session_handle;
533
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700534 CAM_DBG(CAM_ACTUATOR, "Device Handle: %d",
535 actuator_acq_dev.device_handle);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800536 if (copy_to_user((void __user *) cmd->handle, &actuator_acq_dev,
537 sizeof(struct cam_sensor_acquire_dev))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700538 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800539 rc = -EFAULT;
540 goto release_mutex;
541 }
542
543 }
544 break;
545 case CAM_RELEASE_DEV: {
546 if (a_ctrl->bridge_intf.device_hdl == -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700547 CAM_ERR(CAM_ACTUATOR, "link hdl: %d device hdl: %d",
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800548 a_ctrl->bridge_intf.device_hdl,
549 a_ctrl->bridge_intf.link_hdl);
550 rc = -EINVAL;
551 goto release_mutex;
552 }
553 rc = cam_destroy_device_hdl(a_ctrl->bridge_intf.device_hdl);
554 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700555 CAM_ERR(CAM_ACTUATOR, "destroying the device hdl");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800556 a_ctrl->bridge_intf.device_hdl = -1;
557 a_ctrl->bridge_intf.link_hdl = -1;
558 a_ctrl->bridge_intf.session_hdl = -1;
559 }
560 break;
561 case CAM_QUERY_CAP: {
Soundrapandian Jeyaprakashc22f42a2017-07-28 17:33:44 -0700562 struct cam_actuator_query_cap actuator_cap = {0};
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800563
Depeng Shao0fe56182017-09-25 11:13:48 +0800564 actuator_cap.slot_info = a_ctrl->soc_info.index;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800565 if (copy_to_user((void __user *) cmd->handle, &actuator_cap,
566 sizeof(struct cam_actuator_query_cap))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700567 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800568 rc = -EFAULT;
569 goto release_mutex;
570 }
571 }
572 break;
573 case CAM_START_DEV: {
574 rc = cam_actuator_power_up(a_ctrl);
575 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700576 CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800577 goto release_mutex;
578 }
579 rc = camera_io_init(&a_ctrl->io_master_info);
580 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700581 CAM_ERR(CAM_ACTUATOR, "cci_init failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800582 cam_actuator_power_down(a_ctrl);
583 }
584
585 rc = cam_actuator_apply_settings(a_ctrl,
586 &a_ctrl->i2c_data.init_settings);
587 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700588 CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800589
590 /* Delete the request even if the apply is failed */
591 rc = delete_request(&a_ctrl->i2c_data.init_settings);
592 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700593 CAM_ERR(CAM_ACTUATOR,
594 "Fail in deleting the Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800595 rc = -EINVAL;
596 goto release_mutex;
597 }
598 }
599 break;
600 case CAM_STOP_DEV: {
601 rc = camera_io_release(&a_ctrl->io_master_info);
602 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700603 CAM_ERR(CAM_ACTUATOR, "Failed in releasing CCI");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800604 rc = cam_actuator_power_down(a_ctrl);
605 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700606 CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800607 goto release_mutex;
608 }
609 }
610 break;
611 case CAM_CONFIG_DEV: {
612 a_ctrl->act_apply_state =
613 ACT_APPLY_SETTINGS_LATER;
614 rc = cam_actuator_i2c_pkt_parse(a_ctrl, arg);
615 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700616 CAM_ERR(CAM_ACTUATOR, "Failed in actuator Parsing");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800617 }
618
619 if (a_ctrl->act_apply_state ==
620 ACT_APPLY_SETTINGS_NOW) {
621 rc = cam_actuator_apply_settings(a_ctrl,
622 &a_ctrl->i2c_data.init_settings);
623 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700624 CAM_ERR(CAM_ACTUATOR,
625 "Cannot apply Update settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800626
627 /* Delete the request even if the apply is failed */
628 rc = delete_request(&a_ctrl->i2c_data.init_settings);
629 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700630 CAM_ERR(CAM_ACTUATOR,
631 "Failed in Deleting the Init Pkt: %d",
632 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800633 goto release_mutex;
634 }
635 }
636 }
637 break;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700638 case CAM_SD_SHUTDOWN:
639 break;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800640 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700641 CAM_ERR(CAM_ACTUATOR, "Invalid Opcode %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800642 }
643
644release_mutex:
645 mutex_unlock(&(a_ctrl->actuator_mutex));
646
647 return rc;
648}