blob: bcf4133fc9106ef37d430bb8e2565e62a639d296 [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) {
96 a_ctrl->io_master_info.cci_client->i2c_freq_mode =
97 i2c_info->i2c_freq_mode;
98 a_ctrl->io_master_info.cci_client->sid =
99 i2c_info->slave_addr >> 1;
100 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x Freq Mode: %d",
101 i2c_info->slave_addr, i2c_info->i2c_freq_mode);
102 } else if (a_ctrl->io_master_info.master_type == I2C_MASTER) {
103 a_ctrl->io_master_info.client->addr = i2c_info->slave_addr;
104 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x", i2c_info->slave_addr);
105 } else {
106 CAM_ERR(CAM_ACTUATOR, "Invalid Master type: %d",
107 a_ctrl->io_master_info.master_type);
108 rc = -EINVAL;
109 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800110
111 return rc;
112}
113
114int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
115 struct i2c_settings_array *i2c_set)
116{
117 struct i2c_settings_list *i2c_list;
118 int32_t rc = 0;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800119
120 if (a_ctrl == NULL || i2c_set == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700121 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800122 return -EINVAL;
123 }
124
125 if (i2c_set->is_settings_valid != 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700126 CAM_ERR(CAM_ACTUATOR, " Invalid settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800127 return -EINVAL;
128 }
129
130 list_for_each_entry(i2c_list,
131 &(i2c_set->list_head), list) {
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700132 rc = cam_actuator_i2c_modes_util(
133 &(a_ctrl->io_master_info),
134 i2c_list);
135 if (rc < 0) {
136 CAM_ERR(CAM_ACTUATOR,
137 "Failed to apply settings: %d",
138 rc);
139 return rc;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800140 }
141 }
142
143 return rc;
144}
145
146int32_t cam_actuator_apply_request(struct cam_req_mgr_apply_request *apply)
147{
148 int32_t rc = 0, request_id, del_req_id;
149 struct cam_actuator_ctrl_t *a_ctrl = NULL;
150
151 if (!apply) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700152 CAM_ERR(CAM_ACTUATOR, "Invalid Input Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800153 return -EINVAL;
154 }
155
156 a_ctrl = (struct cam_actuator_ctrl_t *)
157 cam_get_device_priv(apply->dev_hdl);
158 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700159 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800160 return -EINVAL;
161 }
162 request_id = apply->request_id % MAX_PER_FRAME_ARRAY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600163
164 trace_cam_apply_req("Actuator", apply);
165
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700166 CAM_DBG(CAM_ACTUATOR, "Request Id: %lld", apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800167
168 if ((apply->request_id ==
169 a_ctrl->i2c_data.per_frame[request_id].request_id) &&
170 (a_ctrl->i2c_data.per_frame[request_id].is_settings_valid)
171 == 1) {
172 rc = cam_actuator_apply_settings(a_ctrl,
173 &a_ctrl->i2c_data.per_frame[request_id]);
174 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700175 CAM_ERR(CAM_ACTUATOR,
176 "Failed in applying the request: %lld\n",
177 apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800178 return rc;
179 }
180 }
181 del_req_id = (request_id +
182 MAX_PER_FRAME_ARRAY - MAX_SYSTEM_PIPELINE_DELAY) %
183 MAX_PER_FRAME_ARRAY;
184
185 if (apply->request_id >
186 a_ctrl->i2c_data.per_frame[del_req_id].request_id) {
187 a_ctrl->i2c_data.per_frame[del_req_id].request_id = 0;
188 rc = delete_request(&a_ctrl->i2c_data.per_frame[del_req_id]);
189 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700190 CAM_ERR(CAM_ACTUATOR,
191 "Fail deleting the req: %d err: %d\n",
192 del_req_id, rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800193 return rc;
194 }
195 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700196 CAM_DBG(CAM_ACTUATOR, "No Valid Req to clean Up");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800197 }
198
199 return rc;
200}
201
202int32_t cam_actuator_establish_link(
203 struct cam_req_mgr_core_dev_link_setup *link)
204{
205 struct cam_actuator_ctrl_t *a_ctrl = NULL;
206
207 if (!link) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700208 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800209 return -EINVAL;
210 }
211
212 a_ctrl = (struct cam_actuator_ctrl_t *)
213 cam_get_device_priv(link->dev_hdl);
214 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700215 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800216 return -EINVAL;
217 }
218 if (link->link_enable) {
219 a_ctrl->bridge_intf.link_hdl = link->link_hdl;
220 a_ctrl->bridge_intf.crm_cb = link->crm_cb;
221 } else {
222 a_ctrl->bridge_intf.link_hdl = -1;
223 a_ctrl->bridge_intf.crm_cb = NULL;
224 }
225
226 return 0;
227}
228
229int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info)
230{
231 if (!info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700232 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800233 return -EINVAL;
234 }
235
236 info->dev_id = CAM_REQ_MGR_DEVICE_ACTUATOR;
237 strlcpy(info->name, CAM_ACTUATOR_NAME, sizeof(info->name));
238 info->p_delay = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -0700239 info->trigger = CAM_TRIGGER_POINT_SOF;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800240
241 return 0;
242}
243
244int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
245 void *arg)
246{
247 int32_t rc = 0;
248 uint64_t generic_ptr;
249 struct cam_control *ioctl_ctrl = NULL;
250 struct cam_packet *csl_packet = NULL;
251 struct cam_config_dev_cmd config;
252 struct i2c_data_settings *i2c_data = NULL;
253 struct i2c_settings_array *i2c_reg_settings = NULL;
254 struct cam_cmd_buf_desc *cmd_desc = NULL;
255 size_t len_of_buff = 0;
256 uint32_t *offset = NULL, *cmd_buf;
257 struct cam_req_mgr_add_request add_req;
258
259 if (!a_ctrl || !arg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700260 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800261 return -EINVAL;
262 }
263
264 ioctl_ctrl = (struct cam_control *)arg;
265 if (copy_from_user(&config, (void __user *) ioctl_ctrl->handle,
266 sizeof(config)))
267 return -EFAULT;
268 rc = cam_mem_get_cpu_buf(config.packet_handle,
269 (uint64_t *)&generic_ptr, &len_of_buff);
270 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700271 CAM_ERR(CAM_ACTUATOR, "Error in converting command Handle %d",
272 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800273 return rc;
274 }
275
276 if (config.offset > len_of_buff) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700277 CAM_ERR(CAM_ACTUATOR,
278 "offset is out of bounds: offset: %lld len: %zu",
279 config.offset, len_of_buff);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800280 return -EINVAL;
281 }
282
283 csl_packet = (struct cam_packet *)(generic_ptr +
284 config.offset);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700285 CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800286
287 if ((csl_packet->header.op_code & 0xFFFFFF) ==
288 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
289 i2c_data = &(a_ctrl->i2c_data);
290 i2c_reg_settings = &i2c_data->init_settings;
291
292 offset = (uint32_t *)&csl_packet->payload;
293 offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
294 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
295
296 if (csl_packet->num_cmd_buf != 2) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700297 CAM_ERR(CAM_ACTUATOR, "cmd Buffers in Init : %d",
298 csl_packet->num_cmd_buf);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800299 return -EINVAL;
300 }
301
302 rc = cam_mem_get_cpu_buf(cmd_desc[0].mem_handle,
303 (uint64_t *)&generic_ptr, &len_of_buff);
304 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700305 CAM_ERR(CAM_ACTUATOR, "Failed to get cpu buf");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800306 return rc;
307 }
308 cmd_buf = (uint32_t *)generic_ptr;
309 cmd_buf += cmd_desc->offset / sizeof(uint32_t);
310 rc = cam_actuator_slaveInfo_pkt_parser(a_ctrl, cmd_buf);
311 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700312 CAM_ERR(CAM_ACTUATOR, "Failed in parsing the pkt");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800313 return rc;
314 }
315 cmd_buf += (sizeof(struct cam_cmd_i2c_info)/sizeof(uint32_t));
316 i2c_data->init_settings.request_id = 0;
317 i2c_reg_settings->is_settings_valid = 1;
318 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
319 &cmd_desc[1], 1);
320 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700321 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
322 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800323 return rc;
324 }
325 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
326 CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS) {
327 a_ctrl->act_apply_state =
328 ACT_APPLY_SETTINGS_NOW;
329
330 i2c_data = &(a_ctrl->i2c_data);
331 i2c_reg_settings = &i2c_data->init_settings;
332
333 i2c_data->init_settings.request_id =
334 csl_packet->header.request_id;
335 i2c_reg_settings->is_settings_valid = 1;
336 offset = (uint32_t *)&csl_packet->payload;
337 offset += csl_packet->cmd_buf_offset / sizeof(uint32_t);
338 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
339 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
340 cmd_desc, 1);
341 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700342 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
343 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800344 return rc;
345 }
346 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
347 CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS) {
348 i2c_data = &(a_ctrl->i2c_data);
349 i2c_reg_settings =
350 &i2c_data->per_frame
351 [csl_packet->header.request_id % MAX_PER_FRAME_ARRAY];
352
353 i2c_data->init_settings.request_id =
354 csl_packet->header.request_id;
355 i2c_reg_settings->is_settings_valid = 1;
356 offset = (uint32_t *)&csl_packet->payload;
357 offset += csl_packet->cmd_buf_offset / sizeof(uint32_t);
358 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
359 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
360 cmd_desc, 1);
361 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700362 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
363 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800364 return rc;
365 }
366 }
367
368 if ((csl_packet->header.op_code & 0xFFFFFF) !=
369 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
370 add_req.link_hdl = a_ctrl->bridge_intf.link_hdl;
371 add_req.req_id = csl_packet->header.request_id;
372 add_req.dev_hdl = a_ctrl->bridge_intf.device_hdl;
373 if (a_ctrl->bridge_intf.crm_cb &&
374 a_ctrl->bridge_intf.crm_cb->add_req)
375 a_ctrl->bridge_intf.crm_cb->add_req(&add_req);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700376 CAM_DBG(CAM_ACTUATOR, "Req Id: %lld added to Bridge",
377 add_req.req_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800378 }
379
380 return rc;
381}
382
Alok Pandey01b1b352017-06-25 20:38:54 +0530383static int32_t cam_actuator_vreg_control(
384 struct cam_actuator_ctrl_t *a_ctrl,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800385 int config)
386{
Alok Pandey01b1b352017-06-25 20:38:54 +0530387 int rc = 0, cnt;
388 struct cam_hw_soc_info *soc_info;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800389
Alok Pandey01b1b352017-06-25 20:38:54 +0530390 soc_info = &a_ctrl->soc_info;
391 cnt = soc_info->num_rgltr;
392
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800393 if (!cnt)
394 return 0;
395
Alok Pandey01b1b352017-06-25 20:38:54 +0530396 if (cnt >= CAM_SOC_MAX_REGULATOR) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700397 CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800398 return -EINVAL;
399 }
400
Alok Pandey01b1b352017-06-25 20:38:54 +0530401 if (config)
402 rc = cam_soc_util_enable_platform_resource(soc_info, false, 0,
403 false);
404 else
405 rc = cam_soc_util_disable_platform_resource(soc_info, false,
406 false);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800407
408 return rc;
409}
410
411static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
412{
413 int rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530414 struct cam_hw_soc_info *soc_info =
415 &a_ctrl->soc_info;
416 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800417
418 rc = cam_actuator_vreg_control(a_ctrl, 1);
419 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700420 CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800421 return rc;
422 }
423
Alok Pandey01b1b352017-06-25 20:38:54 +0530424 gpio_num_info = a_ctrl->gpio_num_info;
425
426 if (soc_info->gpio_data &&
427 gpio_num_info &&
428 gpio_num_info->valid[SENSOR_VAF] == 1) {
429 rc = cam_soc_util_request_platform_resource(&a_ctrl->soc_info,
430 NULL, NULL);
431 rc = cam_soc_util_enable_platform_resource(&a_ctrl->soc_info,
432 false, 0, false);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800433 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700434 CAM_ERR(CAM_ACTUATOR, "Failed in req gpio: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800435 return rc;
436 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800437
438 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530439 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800440 1);
441 }
442
443 /* VREG needs some delay to power up */
444 usleep_range(2000, 2050);
445
446 return rc;
447}
448
449static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
450{
451 int32_t rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530452 struct cam_hw_soc_info *soc_info =
453 &a_ctrl->soc_info;
454 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800455
456 rc = cam_actuator_vreg_control(a_ctrl, 0);
457 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700458 CAM_ERR(CAM_ACTUATOR, "Failed %d");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800459 return rc;
460 }
461
Alok Pandey01b1b352017-06-25 20:38:54 +0530462 gpio_num_info = a_ctrl->gpio_num_info;
463
464 if (soc_info->gpio_data &&
465 gpio_num_info &&
466 gpio_num_info->valid[SENSOR_VAF] == 1) {
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800467
468 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530469 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800470 GPIOF_OUT_INIT_LOW);
471
Alok Pandey01b1b352017-06-25 20:38:54 +0530472 rc = cam_soc_util_release_platform_resource(&a_ctrl->soc_info);
473 rc |= cam_soc_util_disable_platform_resource(&a_ctrl->soc_info,
474 0, 0);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800475 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700476 CAM_ERR(CAM_ACTUATOR,
477 "Failed to disable platform resources: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800478 }
479
480 return rc;
481}
482
483int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
484 void *arg)
485{
486 int rc = 0;
487 struct cam_control *cmd = (struct cam_control *)arg;
488
489 if (!a_ctrl || !cmd) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700490 CAM_ERR(CAM_ACTUATOR, " Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800491 return -EINVAL;
492 }
493
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700494 pr_debug("Opcode to Actuator: %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800495
496 mutex_lock(&(a_ctrl->actuator_mutex));
497 switch (cmd->op_code) {
498 case CAM_ACQUIRE_DEV: {
499 struct cam_sensor_acquire_dev actuator_acq_dev;
500 struct cam_create_dev_hdl bridge_params;
501
502 if (a_ctrl->bridge_intf.device_hdl != -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700503 CAM_ERR(CAM_ACTUATOR, "Device is already acquired");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800504 rc = -EINVAL;
505 goto release_mutex;
506 }
507 rc = copy_from_user(&actuator_acq_dev,
508 (void __user *) cmd->handle,
509 sizeof(actuator_acq_dev));
510 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700511 CAM_ERR(CAM_ACTUATOR, "Failed Copying from user\n");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800512 goto release_mutex;
513 }
514
515 bridge_params.session_hdl = actuator_acq_dev.session_handle;
516 bridge_params.ops = &a_ctrl->bridge_intf.ops;
517 bridge_params.v4l2_sub_dev_flag = 0;
518 bridge_params.media_entity_flag = 0;
519 bridge_params.priv = a_ctrl;
520
521 actuator_acq_dev.device_handle =
522 cam_create_device_hdl(&bridge_params);
523 a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
524 a_ctrl->bridge_intf.session_hdl =
525 actuator_acq_dev.session_handle;
526
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700527 CAM_DBG(CAM_ACTUATOR, "Device Handle: %d",
528 actuator_acq_dev.device_handle);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800529 if (copy_to_user((void __user *) cmd->handle, &actuator_acq_dev,
530 sizeof(struct cam_sensor_acquire_dev))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700531 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800532 rc = -EFAULT;
533 goto release_mutex;
534 }
535
536 }
537 break;
538 case CAM_RELEASE_DEV: {
539 if (a_ctrl->bridge_intf.device_hdl == -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700540 CAM_ERR(CAM_ACTUATOR, "link hdl: %d device hdl: %d",
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800541 a_ctrl->bridge_intf.device_hdl,
542 a_ctrl->bridge_intf.link_hdl);
543 rc = -EINVAL;
544 goto release_mutex;
545 }
546 rc = cam_destroy_device_hdl(a_ctrl->bridge_intf.device_hdl);
547 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700548 CAM_ERR(CAM_ACTUATOR, "destroying the device hdl");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800549 a_ctrl->bridge_intf.device_hdl = -1;
550 a_ctrl->bridge_intf.link_hdl = -1;
551 a_ctrl->bridge_intf.session_hdl = -1;
552 }
553 break;
554 case CAM_QUERY_CAP: {
Soundrapandian Jeyaprakashc22f42a2017-07-28 17:33:44 -0700555 struct cam_actuator_query_cap actuator_cap = {0};
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800556
557 actuator_cap.slot_info = a_ctrl->id;
558 if (copy_to_user((void __user *) cmd->handle, &actuator_cap,
559 sizeof(struct cam_actuator_query_cap))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700560 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800561 rc = -EFAULT;
562 goto release_mutex;
563 }
564 }
565 break;
566 case CAM_START_DEV: {
567 rc = cam_actuator_power_up(a_ctrl);
568 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700569 CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800570 goto release_mutex;
571 }
572 rc = camera_io_init(&a_ctrl->io_master_info);
573 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700574 CAM_ERR(CAM_ACTUATOR, "cci_init failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800575 cam_actuator_power_down(a_ctrl);
576 }
577
578 rc = cam_actuator_apply_settings(a_ctrl,
579 &a_ctrl->i2c_data.init_settings);
580 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700581 CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800582
583 /* Delete the request even if the apply is failed */
584 rc = delete_request(&a_ctrl->i2c_data.init_settings);
585 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700586 CAM_ERR(CAM_ACTUATOR,
587 "Fail in deleting the Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800588 rc = -EINVAL;
589 goto release_mutex;
590 }
591 }
592 break;
593 case CAM_STOP_DEV: {
594 rc = camera_io_release(&a_ctrl->io_master_info);
595 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700596 CAM_ERR(CAM_ACTUATOR, "Failed in releasing CCI");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800597 rc = cam_actuator_power_down(a_ctrl);
598 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700599 CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800600 goto release_mutex;
601 }
602 }
603 break;
604 case CAM_CONFIG_DEV: {
605 a_ctrl->act_apply_state =
606 ACT_APPLY_SETTINGS_LATER;
607 rc = cam_actuator_i2c_pkt_parse(a_ctrl, arg);
608 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700609 CAM_ERR(CAM_ACTUATOR, "Failed in actuator Parsing");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800610 }
611
612 if (a_ctrl->act_apply_state ==
613 ACT_APPLY_SETTINGS_NOW) {
614 rc = cam_actuator_apply_settings(a_ctrl,
615 &a_ctrl->i2c_data.init_settings);
616 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700617 CAM_ERR(CAM_ACTUATOR,
618 "Cannot apply Update settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800619
620 /* Delete the request even if the apply is failed */
621 rc = delete_request(&a_ctrl->i2c_data.init_settings);
622 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700623 CAM_ERR(CAM_ACTUATOR,
624 "Failed in Deleting the Init Pkt: %d",
625 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800626 goto release_mutex;
627 }
628 }
629 }
630 break;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700631 case CAM_SD_SHUTDOWN:
632 break;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800633 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700634 CAM_ERR(CAM_ACTUATOR, "Invalid Opcode %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800635 }
636
637release_mutex:
638 mutex_unlock(&(a_ctrl->actuator_mutex));
639
640 return rc;
641}