blob: b36fc6862fcdad3495e5dce0d965879dd4e10086 [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
19int32_t cam_actuator_slaveInfo_pkt_parser(struct cam_actuator_ctrl_t *a_ctrl,
20 uint32_t *cmd_buf)
21{
22 int32_t rc = 0;
23 struct cam_cmd_i2c_info *i2c_info;
24
25 if (!a_ctrl || !cmd_buf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070026 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080027 return -EINVAL;
28 }
29
30 i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
Jigarkumar Zalaae152332017-07-18 17:21:48 -070031 if (a_ctrl->io_master_info.master_type == CCI_MASTER) {
32 a_ctrl->io_master_info.cci_client->i2c_freq_mode =
33 i2c_info->i2c_freq_mode;
34 a_ctrl->io_master_info.cci_client->sid =
35 i2c_info->slave_addr >> 1;
36 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x Freq Mode: %d",
37 i2c_info->slave_addr, i2c_info->i2c_freq_mode);
38 } else if (a_ctrl->io_master_info.master_type == I2C_MASTER) {
39 a_ctrl->io_master_info.client->addr = i2c_info->slave_addr;
40 CAM_DBG(CAM_ACTUATOR, "Slave addr: 0x%x", i2c_info->slave_addr);
41 } else {
42 CAM_ERR(CAM_ACTUATOR, "Invalid Master type: %d",
43 a_ctrl->io_master_info.master_type);
44 rc = -EINVAL;
45 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080046
47 return rc;
48}
49
50int32_t cam_actuator_apply_settings(struct cam_actuator_ctrl_t *a_ctrl,
51 struct i2c_settings_array *i2c_set)
52{
53 struct i2c_settings_list *i2c_list;
54 int32_t rc = 0;
55 uint32_t i, size;
56
57 if (a_ctrl == NULL || i2c_set == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070058 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080059 return -EINVAL;
60 }
61
62 if (i2c_set->is_settings_valid != 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070063 CAM_ERR(CAM_ACTUATOR, " Invalid settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080064 return -EINVAL;
65 }
66
67 list_for_each_entry(i2c_list,
68 &(i2c_set->list_head), list) {
69 if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
70 rc = camera_io_dev_write(&(a_ctrl->io_master_info),
71 &(i2c_list->i2c_settings));
72 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070073 CAM_ERR(CAM_ACTUATOR,
74 "Failed in Applying i2c wrt settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080075 return rc;
76 }
77 } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
78 size = i2c_list->i2c_settings.size;
79 for (i = 0; i < size; i++) {
80 rc = camera_io_dev_poll(
81 &(a_ctrl->io_master_info),
82 i2c_list->i2c_settings.
83 reg_setting[i].reg_addr,
84 i2c_list->i2c_settings.
85 reg_setting[i].reg_data,
86 i2c_list->i2c_settings.
87 reg_setting[i].data_mask,
88 i2c_list->i2c_settings.addr_type,
89 i2c_list->i2c_settings.data_type,
90 i2c_list->i2c_settings.
91 reg_setting[i].delay);
92 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070093 CAM_ERR(CAM_ACTUATOR,
94 "i2c poll apply setting Fail");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -080095 return rc;
96 }
97 }
98 }
99 }
100
101 return rc;
102}
103
104int32_t cam_actuator_apply_request(struct cam_req_mgr_apply_request *apply)
105{
106 int32_t rc = 0, request_id, del_req_id;
107 struct cam_actuator_ctrl_t *a_ctrl = NULL;
108
109 if (!apply) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700110 CAM_ERR(CAM_ACTUATOR, "Invalid Input Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800111 return -EINVAL;
112 }
113
114 a_ctrl = (struct cam_actuator_ctrl_t *)
115 cam_get_device_priv(apply->dev_hdl);
116 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700117 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800118 return -EINVAL;
119 }
120 request_id = apply->request_id % MAX_PER_FRAME_ARRAY;
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600121
122 trace_cam_apply_req("Actuator", apply);
123
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700124 CAM_DBG(CAM_ACTUATOR, "Request Id: %lld", apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800125
126 if ((apply->request_id ==
127 a_ctrl->i2c_data.per_frame[request_id].request_id) &&
128 (a_ctrl->i2c_data.per_frame[request_id].is_settings_valid)
129 == 1) {
130 rc = cam_actuator_apply_settings(a_ctrl,
131 &a_ctrl->i2c_data.per_frame[request_id]);
132 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700133 CAM_ERR(CAM_ACTUATOR,
134 "Failed in applying the request: %lld\n",
135 apply->request_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800136 return rc;
137 }
138 }
139 del_req_id = (request_id +
140 MAX_PER_FRAME_ARRAY - MAX_SYSTEM_PIPELINE_DELAY) %
141 MAX_PER_FRAME_ARRAY;
142
143 if (apply->request_id >
144 a_ctrl->i2c_data.per_frame[del_req_id].request_id) {
145 a_ctrl->i2c_data.per_frame[del_req_id].request_id = 0;
146 rc = delete_request(&a_ctrl->i2c_data.per_frame[del_req_id]);
147 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700148 CAM_ERR(CAM_ACTUATOR,
149 "Fail deleting the req: %d err: %d\n",
150 del_req_id, rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800151 return rc;
152 }
153 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700154 CAM_DBG(CAM_ACTUATOR, "No Valid Req to clean Up");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800155 }
156
157 return rc;
158}
159
160int32_t cam_actuator_establish_link(
161 struct cam_req_mgr_core_dev_link_setup *link)
162{
163 struct cam_actuator_ctrl_t *a_ctrl = NULL;
164
165 if (!link) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700166 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800167 return -EINVAL;
168 }
169
170 a_ctrl = (struct cam_actuator_ctrl_t *)
171 cam_get_device_priv(link->dev_hdl);
172 if (!a_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700173 CAM_ERR(CAM_ACTUATOR, "Device data is NULL");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800174 return -EINVAL;
175 }
176 if (link->link_enable) {
177 a_ctrl->bridge_intf.link_hdl = link->link_hdl;
178 a_ctrl->bridge_intf.crm_cb = link->crm_cb;
179 } else {
180 a_ctrl->bridge_intf.link_hdl = -1;
181 a_ctrl->bridge_intf.crm_cb = NULL;
182 }
183
184 return 0;
185}
186
187int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info)
188{
189 if (!info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700190 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800191 return -EINVAL;
192 }
193
194 info->dev_id = CAM_REQ_MGR_DEVICE_ACTUATOR;
195 strlcpy(info->name, CAM_ACTUATOR_NAME, sizeof(info->name));
196 info->p_delay = 0;
Junzhe Zou2df84502017-05-26 13:20:23 -0700197 info->trigger = CAM_TRIGGER_POINT_SOF;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800198
199 return 0;
200}
201
202int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
203 void *arg)
204{
205 int32_t rc = 0;
206 uint64_t generic_ptr;
207 struct cam_control *ioctl_ctrl = NULL;
208 struct cam_packet *csl_packet = NULL;
209 struct cam_config_dev_cmd config;
210 struct i2c_data_settings *i2c_data = NULL;
211 struct i2c_settings_array *i2c_reg_settings = NULL;
212 struct cam_cmd_buf_desc *cmd_desc = NULL;
213 size_t len_of_buff = 0;
214 uint32_t *offset = NULL, *cmd_buf;
215 struct cam_req_mgr_add_request add_req;
216
217 if (!a_ctrl || !arg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700218 CAM_ERR(CAM_ACTUATOR, "Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800219 return -EINVAL;
220 }
221
222 ioctl_ctrl = (struct cam_control *)arg;
223 if (copy_from_user(&config, (void __user *) ioctl_ctrl->handle,
224 sizeof(config)))
225 return -EFAULT;
226 rc = cam_mem_get_cpu_buf(config.packet_handle,
227 (uint64_t *)&generic_ptr, &len_of_buff);
228 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700229 CAM_ERR(CAM_ACTUATOR, "Error in converting command Handle %d",
230 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800231 return rc;
232 }
233
234 if (config.offset > len_of_buff) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700235 CAM_ERR(CAM_ACTUATOR,
236 "offset is out of bounds: offset: %lld len: %zu",
237 config.offset, len_of_buff);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800238 return -EINVAL;
239 }
240
241 csl_packet = (struct cam_packet *)(generic_ptr +
242 config.offset);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700243 CAM_DBG(CAM_ACTUATOR, "Pkt opcode: %d", csl_packet->header.op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800244
245 if ((csl_packet->header.op_code & 0xFFFFFF) ==
246 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
247 i2c_data = &(a_ctrl->i2c_data);
248 i2c_reg_settings = &i2c_data->init_settings;
249
250 offset = (uint32_t *)&csl_packet->payload;
251 offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
252 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
253
254 if (csl_packet->num_cmd_buf != 2) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700255 CAM_ERR(CAM_ACTUATOR, "cmd Buffers in Init : %d",
256 csl_packet->num_cmd_buf);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800257 return -EINVAL;
258 }
259
260 rc = cam_mem_get_cpu_buf(cmd_desc[0].mem_handle,
261 (uint64_t *)&generic_ptr, &len_of_buff);
262 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700263 CAM_ERR(CAM_ACTUATOR, "Failed to get cpu buf");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800264 return rc;
265 }
266 cmd_buf = (uint32_t *)generic_ptr;
267 cmd_buf += cmd_desc->offset / sizeof(uint32_t);
268 rc = cam_actuator_slaveInfo_pkt_parser(a_ctrl, cmd_buf);
269 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700270 CAM_ERR(CAM_ACTUATOR, "Failed in parsing the pkt");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800271 return rc;
272 }
273 cmd_buf += (sizeof(struct cam_cmd_i2c_info)/sizeof(uint32_t));
274 i2c_data->init_settings.request_id = 0;
275 i2c_reg_settings->is_settings_valid = 1;
276 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
277 &cmd_desc[1], 1);
278 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700279 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
280 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800281 return rc;
282 }
283 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
284 CAM_ACTUATOR_PACKET_AUTO_MOVE_LENS) {
285 a_ctrl->act_apply_state =
286 ACT_APPLY_SETTINGS_NOW;
287
288 i2c_data = &(a_ctrl->i2c_data);
289 i2c_reg_settings = &i2c_data->init_settings;
290
291 i2c_data->init_settings.request_id =
292 csl_packet->header.request_id;
293 i2c_reg_settings->is_settings_valid = 1;
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 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
298 cmd_desc, 1);
299 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700300 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
301 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800302 return rc;
303 }
304 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
305 CAM_ACTUATOR_PACKET_MANUAL_MOVE_LENS) {
306 i2c_data = &(a_ctrl->i2c_data);
307 i2c_reg_settings =
308 &i2c_data->per_frame
309 [csl_packet->header.request_id % MAX_PER_FRAME_ARRAY];
310
311 i2c_data->init_settings.request_id =
312 csl_packet->header.request_id;
313 i2c_reg_settings->is_settings_valid = 1;
314 offset = (uint32_t *)&csl_packet->payload;
315 offset += csl_packet->cmd_buf_offset / sizeof(uint32_t);
316 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
317 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings,
318 cmd_desc, 1);
319 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700320 CAM_ERR(CAM_ACTUATOR, "Actuator pkt parsing failed: %d",
321 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800322 return rc;
323 }
324 }
325
326 if ((csl_packet->header.op_code & 0xFFFFFF) !=
327 CAM_ACTUATOR_PACKET_OPCODE_INIT) {
328 add_req.link_hdl = a_ctrl->bridge_intf.link_hdl;
329 add_req.req_id = csl_packet->header.request_id;
330 add_req.dev_hdl = a_ctrl->bridge_intf.device_hdl;
331 if (a_ctrl->bridge_intf.crm_cb &&
332 a_ctrl->bridge_intf.crm_cb->add_req)
333 a_ctrl->bridge_intf.crm_cb->add_req(&add_req);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700334 CAM_DBG(CAM_ACTUATOR, "Req Id: %lld added to Bridge",
335 add_req.req_id);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800336 }
337
338 return rc;
339}
340
Alok Pandey01b1b352017-06-25 20:38:54 +0530341static int32_t cam_actuator_vreg_control(
342 struct cam_actuator_ctrl_t *a_ctrl,
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800343 int config)
344{
Alok Pandey01b1b352017-06-25 20:38:54 +0530345 int rc = 0, cnt;
346 struct cam_hw_soc_info *soc_info;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800347
Alok Pandey01b1b352017-06-25 20:38:54 +0530348 soc_info = &a_ctrl->soc_info;
349 cnt = soc_info->num_rgltr;
350
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800351 if (!cnt)
352 return 0;
353
Alok Pandey01b1b352017-06-25 20:38:54 +0530354 if (cnt >= CAM_SOC_MAX_REGULATOR) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700355 CAM_ERR(CAM_ACTUATOR, "Regulators more than supported %d", cnt);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800356 return -EINVAL;
357 }
358
Alok Pandey01b1b352017-06-25 20:38:54 +0530359 if (config)
360 rc = cam_soc_util_enable_platform_resource(soc_info, false, 0,
361 false);
362 else
363 rc = cam_soc_util_disable_platform_resource(soc_info, false,
364 false);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800365
366 return rc;
367}
368
369static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
370{
371 int rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530372 struct cam_hw_soc_info *soc_info =
373 &a_ctrl->soc_info;
374 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800375
376 rc = cam_actuator_vreg_control(a_ctrl, 1);
377 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700378 CAM_ERR(CAM_ACTUATOR, "Actuator Reg Failed %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800379 return rc;
380 }
381
Alok Pandey01b1b352017-06-25 20:38:54 +0530382 gpio_num_info = a_ctrl->gpio_num_info;
383
384 if (soc_info->gpio_data &&
385 gpio_num_info &&
386 gpio_num_info->valid[SENSOR_VAF] == 1) {
387 rc = cam_soc_util_request_platform_resource(&a_ctrl->soc_info,
388 NULL, NULL);
389 rc = cam_soc_util_enable_platform_resource(&a_ctrl->soc_info,
390 false, 0, false);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800391 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700392 CAM_ERR(CAM_ACTUATOR, "Failed in req gpio: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800393 return rc;
394 }
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800395
396 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530397 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800398 1);
399 }
400
401 /* VREG needs some delay to power up */
402 usleep_range(2000, 2050);
403
404 return rc;
405}
406
407static int32_t cam_actuator_power_down(struct cam_actuator_ctrl_t *a_ctrl)
408{
409 int32_t rc = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530410 struct cam_hw_soc_info *soc_info =
411 &a_ctrl->soc_info;
412 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800413
414 rc = cam_actuator_vreg_control(a_ctrl, 0);
415 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700416 CAM_ERR(CAM_ACTUATOR, "Failed %d");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800417 return rc;
418 }
419
Alok Pandey01b1b352017-06-25 20:38:54 +0530420 gpio_num_info = a_ctrl->gpio_num_info;
421
422 if (soc_info->gpio_data &&
423 gpio_num_info &&
424 gpio_num_info->valid[SENSOR_VAF] == 1) {
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800425
426 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +0530427 gpio_num_info->gpio_num[SENSOR_VAF],
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800428 GPIOF_OUT_INIT_LOW);
429
Alok Pandey01b1b352017-06-25 20:38:54 +0530430 rc = cam_soc_util_release_platform_resource(&a_ctrl->soc_info);
431 rc |= cam_soc_util_disable_platform_resource(&a_ctrl->soc_info,
432 0, 0);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800433 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700434 CAM_ERR(CAM_ACTUATOR,
435 "Failed to disable platform resources: %d", rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800436 }
437
438 return rc;
439}
440
441int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl,
442 void *arg)
443{
444 int rc = 0;
445 struct cam_control *cmd = (struct cam_control *)arg;
446
447 if (!a_ctrl || !cmd) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700448 CAM_ERR(CAM_ACTUATOR, " Invalid Args");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800449 return -EINVAL;
450 }
451
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700452 pr_debug("Opcode to Actuator: %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800453
454 mutex_lock(&(a_ctrl->actuator_mutex));
455 switch (cmd->op_code) {
456 case CAM_ACQUIRE_DEV: {
457 struct cam_sensor_acquire_dev actuator_acq_dev;
458 struct cam_create_dev_hdl bridge_params;
459
460 if (a_ctrl->bridge_intf.device_hdl != -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700461 CAM_ERR(CAM_ACTUATOR, "Device is already acquired");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800462 rc = -EINVAL;
463 goto release_mutex;
464 }
465 rc = copy_from_user(&actuator_acq_dev,
466 (void __user *) cmd->handle,
467 sizeof(actuator_acq_dev));
468 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700469 CAM_ERR(CAM_ACTUATOR, "Failed Copying from user\n");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800470 goto release_mutex;
471 }
472
473 bridge_params.session_hdl = actuator_acq_dev.session_handle;
474 bridge_params.ops = &a_ctrl->bridge_intf.ops;
475 bridge_params.v4l2_sub_dev_flag = 0;
476 bridge_params.media_entity_flag = 0;
477 bridge_params.priv = a_ctrl;
478
479 actuator_acq_dev.device_handle =
480 cam_create_device_hdl(&bridge_params);
481 a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle;
482 a_ctrl->bridge_intf.session_hdl =
483 actuator_acq_dev.session_handle;
484
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700485 CAM_DBG(CAM_ACTUATOR, "Device Handle: %d",
486 actuator_acq_dev.device_handle);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800487 if (copy_to_user((void __user *) cmd->handle, &actuator_acq_dev,
488 sizeof(struct cam_sensor_acquire_dev))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700489 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800490 rc = -EFAULT;
491 goto release_mutex;
492 }
493
494 }
495 break;
496 case CAM_RELEASE_DEV: {
497 if (a_ctrl->bridge_intf.device_hdl == -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700498 CAM_ERR(CAM_ACTUATOR, "link hdl: %d device hdl: %d",
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800499 a_ctrl->bridge_intf.device_hdl,
500 a_ctrl->bridge_intf.link_hdl);
501 rc = -EINVAL;
502 goto release_mutex;
503 }
504 rc = cam_destroy_device_hdl(a_ctrl->bridge_intf.device_hdl);
505 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700506 CAM_ERR(CAM_ACTUATOR, "destroying the device hdl");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800507 a_ctrl->bridge_intf.device_hdl = -1;
508 a_ctrl->bridge_intf.link_hdl = -1;
509 a_ctrl->bridge_intf.session_hdl = -1;
510 }
511 break;
512 case CAM_QUERY_CAP: {
Soundrapandian Jeyaprakashc22f42a2017-07-28 17:33:44 -0700513 struct cam_actuator_query_cap actuator_cap = {0};
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800514
515 actuator_cap.slot_info = a_ctrl->id;
516 if (copy_to_user((void __user *) cmd->handle, &actuator_cap,
517 sizeof(struct cam_actuator_query_cap))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700518 CAM_ERR(CAM_ACTUATOR, "Failed Copy to User");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800519 rc = -EFAULT;
520 goto release_mutex;
521 }
522 }
523 break;
524 case CAM_START_DEV: {
525 rc = cam_actuator_power_up(a_ctrl);
526 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700527 CAM_ERR(CAM_ACTUATOR, " Actuator Power up failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800528 goto release_mutex;
529 }
530 rc = camera_io_init(&a_ctrl->io_master_info);
531 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700532 CAM_ERR(CAM_ACTUATOR, "cci_init failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800533 cam_actuator_power_down(a_ctrl);
534 }
535
536 rc = cam_actuator_apply_settings(a_ctrl,
537 &a_ctrl->i2c_data.init_settings);
538 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700539 CAM_ERR(CAM_ACTUATOR, "Cannot apply Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800540
541 /* Delete the request even if the apply is failed */
542 rc = delete_request(&a_ctrl->i2c_data.init_settings);
543 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700544 CAM_ERR(CAM_ACTUATOR,
545 "Fail in deleting the Init settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800546 rc = -EINVAL;
547 goto release_mutex;
548 }
549 }
550 break;
551 case CAM_STOP_DEV: {
552 rc = camera_io_release(&a_ctrl->io_master_info);
553 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700554 CAM_ERR(CAM_ACTUATOR, "Failed in releasing CCI");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800555 rc = cam_actuator_power_down(a_ctrl);
556 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700557 CAM_ERR(CAM_ACTUATOR, "Actuator Power down failed");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800558 goto release_mutex;
559 }
560 }
561 break;
562 case CAM_CONFIG_DEV: {
563 a_ctrl->act_apply_state =
564 ACT_APPLY_SETTINGS_LATER;
565 rc = cam_actuator_i2c_pkt_parse(a_ctrl, arg);
566 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700567 CAM_ERR(CAM_ACTUATOR, "Failed in actuator Parsing");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800568 }
569
570 if (a_ctrl->act_apply_state ==
571 ACT_APPLY_SETTINGS_NOW) {
572 rc = cam_actuator_apply_settings(a_ctrl,
573 &a_ctrl->i2c_data.init_settings);
574 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700575 CAM_ERR(CAM_ACTUATOR,
576 "Cannot apply Update settings");
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800577
578 /* Delete the request even if the apply is failed */
579 rc = delete_request(&a_ctrl->i2c_data.init_settings);
580 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700581 CAM_ERR(CAM_ACTUATOR,
582 "Failed in Deleting the Init Pkt: %d",
583 rc);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800584 goto release_mutex;
585 }
586 }
587 }
588 break;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700589 case CAM_SD_SHUTDOWN:
590 break;
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800591 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700592 CAM_ERR(CAM_ACTUATOR, "Invalid Opcode %d", cmd->op_code);
Viswanadha Raju Thotakura525e2d12017-02-26 16:12:38 -0800593 }
594
595release_mutex:
596 mutex_unlock(&(a_ctrl->actuator_mutex));
597
598 return rc;
599}