blob: edbb33580cb5717348fd406751be93d80ae7fdf9 [file] [log] [blame]
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -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_sensor_core.h"
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060016#include "cam_sensor_util.h"
Alok Pandey01b1b352017-06-25 20:38:54 +053017#include "cam_soc_util.h"
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -060018#include "cam_trace.h"
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080019
20static int32_t cam_sensor_i2c_pkt_parse(struct cam_sensor_ctrl_t *s_ctrl,
21 void *arg)
22{
23 int32_t rc = 0;
24 uint64_t generic_ptr;
25 struct cam_control *ioctl_ctrl = NULL;
26 struct cam_packet *csl_packet = NULL;
27 struct cam_cmd_buf_desc *cmd_desc = NULL;
28 struct i2c_settings_array *i2c_reg_settings = NULL;
29 size_t len_of_buff = 0;
30 uint32_t *offset = NULL;
31 struct cam_config_dev_cmd config;
32 struct i2c_data_settings *i2c_data = NULL;
33 struct cam_req_mgr_add_request add_req;
34
35 ioctl_ctrl = (struct cam_control *)arg;
36
37 if (ioctl_ctrl->handle_type != CAM_HANDLE_USER_POINTER) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070038 CAM_ERR(CAM_SENSOR, "Invalid Handle Type");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080039 return -EINVAL;
40 }
41
42 if (copy_from_user(&config, (void __user *) ioctl_ctrl->handle,
43 sizeof(config)))
44 return -EFAULT;
45
46 rc = cam_mem_get_cpu_buf(
47 config.packet_handle,
48 (uint64_t *)&generic_ptr,
49 &len_of_buff);
50 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070051 CAM_ERR(CAM_SENSOR, "Failed in getting the buffer: %d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080052 return rc;
53 }
54
55 csl_packet = (struct cam_packet *)(generic_ptr +
56 config.offset);
57 if (config.offset > len_of_buff) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070058 CAM_ERR(CAM_SENSOR,
59 "offset is out of bounds: off: %lld len: %zu",
60 config.offset, len_of_buff);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080061 return -EINVAL;
62 }
63
64 i2c_data = &(s_ctrl->i2c_data);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070065 CAM_DBG(CAM_SENSOR, "Header OpCode: %d", csl_packet->header.op_code);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080066 if ((csl_packet->header.op_code & 0xFFFFFF) ==
67 CAM_SENSOR_PACKET_OPCODE_SENSOR_INITIAL_CONFIG) {
68 i2c_reg_settings = &i2c_data->init_settings;
69 i2c_reg_settings->request_id = 0;
70 i2c_reg_settings->is_settings_valid = 1;
71 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
72 CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE) {
73 i2c_reg_settings =
74 &i2c_data->
75 per_frame[csl_packet->header.request_id %
76 MAX_PER_FRAME_ARRAY];
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070077 CAM_DBG(CAM_SENSOR, "Received Packet: %lld",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080078 csl_packet->header.request_id % MAX_PER_FRAME_ARRAY);
79 if (i2c_reg_settings->is_settings_valid == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070080 CAM_ERR(CAM_SENSOR,
81 "Already some pkt in offset req : %lld",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080082 csl_packet->header.request_id);
83 rc = delete_request(i2c_reg_settings);
84 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070085 CAM_ERR(CAM_SENSOR,
86 "Failed in Deleting the err: %d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080087 return rc;
88 }
89 }
90
91 i2c_reg_settings->request_id =
92 csl_packet->header.request_id;
93 i2c_reg_settings->is_settings_valid = 1;
94 } else if ((csl_packet->header.op_code & 0xFFFFFF) ==
95 CAM_PKT_NOP_OPCODE) {
96 goto update_req_mgr;
97 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070098 CAM_ERR(CAM_SENSOR, "Invalid Packet Header");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -080099 return -EINVAL;
100 }
101
102 offset = (uint32_t *)&csl_packet->payload;
103 offset += csl_packet->cmd_buf_offset / 4;
104 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
105
106 rc = cam_sensor_i2c_pkt_parser(i2c_reg_settings, cmd_desc, 1);
107 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700108 CAM_ERR(CAM_SENSOR, "Fail parsing I2C Pkt: %d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800109 return rc;
110 }
111
112update_req_mgr:
113 if (((csl_packet->header.op_code & 0xFFFFFF) ==
114 CAM_PKT_NOP_OPCODE) || (csl_packet->header.op_code ==
115 CAM_SENSOR_PACKET_OPCODE_SENSOR_UPDATE)) {
116 add_req.link_hdl = s_ctrl->bridge_intf.link_hdl;
117 add_req.req_id = csl_packet->header.request_id;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700118 CAM_DBG(CAM_SENSOR, " Rxed Req Id: %lld",
119 csl_packet->header.request_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800120 add_req.dev_hdl = s_ctrl->bridge_intf.device_hdl;
121 if (s_ctrl->bridge_intf.crm_cb &&
122 s_ctrl->bridge_intf.crm_cb->add_req)
123 s_ctrl->bridge_intf.crm_cb->add_req(&add_req);
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700124 CAM_DBG(CAM_SENSOR, " add req to req mgr: %lld",
125 add_req.req_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800126 }
127 return rc;
128}
129
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700130static int32_t cam_sensor_i2c_modes_util(
131 struct camera_io_master *io_master_info,
132 struct i2c_settings_list *i2c_list)
133{
134 int32_t rc = 0;
135 uint32_t i, size;
136
137 if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_RANDOM) {
138 rc = camera_io_dev_write(io_master_info,
139 &(i2c_list->i2c_settings));
140 if (rc < 0) {
141 CAM_ERR(CAM_SENSOR,
142 "Failed to random write I2C settings: %d",
143 rc);
144 return rc;
145 }
146 } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_SEQ) {
147 rc = camera_io_dev_write_continuous(
148 io_master_info,
149 &(i2c_list->i2c_settings),
150 0);
151 if (rc < 0) {
152 CAM_ERR(CAM_SENSOR,
153 "Failed to seq write I2C settings: %d",
154 rc);
155 return rc;
156 }
157 } else if (i2c_list->op_code == CAM_SENSOR_I2C_WRITE_BURST) {
158 rc = camera_io_dev_write_continuous(
159 io_master_info,
160 &(i2c_list->i2c_settings),
161 1);
162 if (rc < 0) {
163 CAM_ERR(CAM_SENSOR,
164 "Failed to burst write I2C settings: %d",
165 rc);
166 return rc;
167 }
168 } else if (i2c_list->op_code == CAM_SENSOR_I2C_POLL) {
169 size = i2c_list->i2c_settings.size;
170 for (i = 0; i < size; i++) {
171 rc = camera_io_dev_poll(
172 io_master_info,
173 i2c_list->i2c_settings.
174 reg_setting[i].reg_addr,
175 i2c_list->i2c_settings.
176 reg_setting[i].reg_data,
177 i2c_list->i2c_settings.
178 reg_setting[i].data_mask,
179 i2c_list->i2c_settings.addr_type,
180 i2c_list->i2c_settings.data_type,
181 i2c_list->i2c_settings.
182 reg_setting[i].delay);
183 if (rc < 0) {
184 CAM_ERR(CAM_SENSOR,
185 "i2c poll apply setting Fail: %d", rc);
186 return rc;
187 }
188 }
189 }
190
191 return rc;
192}
193
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800194int32_t cam_sensor_update_i2c_info(struct cam_cmd_i2c_info *i2c_info,
195 struct cam_sensor_ctrl_t *s_ctrl)
196{
197 int32_t rc = 0;
198 struct cam_sensor_cci_client *cci_client = NULL;
199
200 if (s_ctrl->io_master_info.master_type == CCI_MASTER) {
201 cci_client = s_ctrl->io_master_info.cci_client;
202 if (!cci_client) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700203 CAM_ERR(CAM_SENSOR, "failed: cci_client %pK",
204 cci_client);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800205 return -EINVAL;
206 }
207 cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
208 cci_client->sid = i2c_info->slave_addr >> 1;
209 cci_client->retries = 3;
210 cci_client->id_map = 0;
211 cci_client->i2c_freq_mode = i2c_info->i2c_freq_mode;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700212 CAM_DBG(CAM_SENSOR, " Master: %d sid: %d freq_mode: %d",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800213 cci_client->cci_i2c_master, i2c_info->slave_addr,
214 i2c_info->i2c_freq_mode);
215 }
216
217 return rc;
218}
219
220int32_t cam_sensor_update_slave_info(struct cam_cmd_probe *probe_info,
221 struct cam_sensor_ctrl_t *s_ctrl)
222{
223 int32_t rc = 0;
224
225 s_ctrl->sensordata->slave_info.sensor_id_reg_addr =
226 probe_info->reg_addr;
227 s_ctrl->sensordata->slave_info.sensor_id =
228 probe_info->expected_data;
229 s_ctrl->sensordata->slave_info.sensor_id_mask =
230 probe_info->data_mask;
231
232 s_ctrl->sensor_probe_addr_type = probe_info->addr_type;
233 s_ctrl->sensor_probe_data_type = probe_info->data_type;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700234 CAM_DBG(CAM_SENSOR,
235 "Sensor Addr: 0x%x sensor_id: 0x%x sensor_mask: 0x%x",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800236 s_ctrl->sensordata->slave_info.sensor_id_reg_addr,
237 s_ctrl->sensordata->slave_info.sensor_id,
238 s_ctrl->sensordata->slave_info.sensor_id_mask);
239 return rc;
240}
241
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800242int32_t cam_handle_cmd_buffers_for_probe(void *cmd_buf,
243 struct cam_sensor_ctrl_t *s_ctrl,
244 int32_t cmd_buf_num, int cmd_buf_length)
245{
246 int32_t rc = 0;
247
248 switch (cmd_buf_num) {
249 case 0: {
250 struct cam_cmd_i2c_info *i2c_info = NULL;
251 struct cam_cmd_probe *probe_info;
252
253 i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
254 rc = cam_sensor_update_i2c_info(i2c_info, s_ctrl);
255 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700256 CAM_ERR(CAM_SENSOR, "Failed in Updating the i2c Info");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800257 return rc;
258 }
259 probe_info = (struct cam_cmd_probe *)
260 (cmd_buf + sizeof(struct cam_cmd_i2c_info));
261 rc = cam_sensor_update_slave_info(probe_info, s_ctrl);
262 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700263 CAM_ERR(CAM_SENSOR, "Updating the slave Info");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800264 return rc;
265 }
266 cmd_buf = probe_info;
267 }
268 break;
269 case 1: {
270 rc = cam_sensor_update_power_settings(cmd_buf,
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530271 cmd_buf_length, &s_ctrl->sensordata->power_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800272 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700273 CAM_ERR(CAM_SENSOR,
274 "Failed in updating power settings");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800275 return rc;
276 }
277 }
278 break;
279 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700280 CAM_ERR(CAM_SENSOR, "Invalid command buffer");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800281 break;
282 }
283 return rc;
284}
285
286int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
287{
288 int rc = 0, i;
289 void *packet = NULL, *cmd_buf1 = NULL;
290 uint32_t *cmd_buf;
291 void *ptr;
292 size_t len;
293 struct cam_packet *pkt;
294 struct cam_cmd_buf_desc *cmd_desc;
295
296 rc = cam_mem_get_cpu_buf(handle,
297 (uint64_t *)&packet, &len);
298 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700299 CAM_ERR(CAM_SENSOR, "Failed to get the command Buffer");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800300 return -EINVAL;
301 }
302 pkt = (struct cam_packet *)packet;
303 cmd_desc = (struct cam_cmd_buf_desc *)
304 ((uint32_t *)&pkt->payload + pkt->cmd_buf_offset/4);
305 if (cmd_desc == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700306 CAM_ERR(CAM_SENSOR, "command descriptor pos is invalid");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800307 return -EINVAL;
308 }
309 if (pkt->num_cmd_buf != 2) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700310 CAM_ERR(CAM_SENSOR, "Expected More Command Buffers : %d",
311 pkt->num_cmd_buf);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800312 return -EINVAL;
313 }
314 for (i = 0; i < pkt->num_cmd_buf; i++) {
315 if (!(cmd_desc[i].length))
316 continue;
317 rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
318 (uint64_t *)&cmd_buf1, &len);
319 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700320 CAM_ERR(CAM_SENSOR,
321 "Failed to parse the command Buffer Header");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800322 return -EINVAL;
323 }
324 cmd_buf = (uint32_t *)cmd_buf1;
325 cmd_buf += cmd_desc[i].offset/4;
326 ptr = (void *) cmd_buf;
327
328 rc = cam_handle_cmd_buffers_for_probe(ptr, s_ctrl,
329 i, cmd_desc[i].length);
330 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700331 CAM_ERR(CAM_SENSOR,
332 "Failed to parse the command Buffer Header");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800333 return -EINVAL;
334 }
335 }
336 return rc;
337}
338
339void cam_sensor_query_cap(struct cam_sensor_ctrl_t *s_ctrl,
340 struct cam_sensor_query_cap *query_cap)
341{
342 query_cap->pos_roll = s_ctrl->sensordata->pos_roll;
343 query_cap->pos_pitch = s_ctrl->sensordata->pos_pitch;
344 query_cap->pos_yaw = s_ctrl->sensordata->pos_yaw;
345 query_cap->secure_camera = 0;
346 query_cap->actuator_slot_id =
347 s_ctrl->sensordata->subdev_id[SUB_MODULE_ACTUATOR];
348 query_cap->csiphy_slot_id =
349 s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY];
350 query_cap->eeprom_slot_id =
351 s_ctrl->sensordata->subdev_id[SUB_MODULE_EEPROM];
352 query_cap->flash_slot_id =
353 s_ctrl->sensordata->subdev_id[SUB_MODULE_LED_FLASH];
354 query_cap->ois_slot_id =
355 s_ctrl->sensordata->subdev_id[SUB_MODULE_OIS];
356 query_cap->slot_info =
Alok Pandey01b1b352017-06-25 20:38:54 +0530357 s_ctrl->soc_info.index;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800358}
359
360static uint16_t cam_sensor_id_by_mask(struct cam_sensor_ctrl_t *s_ctrl,
361 uint32_t chipid)
362{
363 uint16_t sensor_id = (uint16_t)(chipid & 0xFFFF);
364 int16_t sensor_id_mask = s_ctrl->sensordata->slave_info.sensor_id_mask;
365
366 if (!sensor_id_mask)
367 sensor_id_mask = ~sensor_id_mask;
368
369 sensor_id &= sensor_id_mask;
370 sensor_id_mask &= -sensor_id_mask;
371 sensor_id_mask -= 1;
372 while (sensor_id_mask) {
373 sensor_id_mask >>= 1;
374 sensor_id >>= 1;
375 }
376 return sensor_id;
377}
378
379int cam_sensor_match_id(struct cam_sensor_ctrl_t *s_ctrl)
380{
381 int rc = 0;
382 uint32_t chipid = 0;
383 struct cam_camera_slave_info *slave_info;
384
385 slave_info = &(s_ctrl->sensordata->slave_info);
386
387 if (!slave_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700388 CAM_ERR(CAM_SENSOR, " failed: %pK",
389 slave_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800390 return -EINVAL;
391 }
392
393 rc = camera_io_dev_read(
394 &(s_ctrl->io_master_info),
395 slave_info->sensor_id_reg_addr,
Jigarkumar Zala2bb81642017-06-05 15:10:01 -0700396 &chipid, CAMERA_SENSOR_I2C_TYPE_WORD,
397 CAMERA_SENSOR_I2C_TYPE_WORD);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800398
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700399 CAM_DBG(CAM_SENSOR, "read id: 0x%x expected id 0x%x:",
400 chipid, slave_info->sensor_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800401 if (cam_sensor_id_by_mask(s_ctrl, chipid) != slave_info->sensor_id) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700402 CAM_ERR(CAM_SENSOR, "chip id %x does not match %x",
403 chipid, slave_info->sensor_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800404 return -ENODEV;
405 }
406 return rc;
407}
408
409int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
410 void *arg)
411{
412 int rc = 0;
413 struct cam_control *cmd = (struct cam_control *)arg;
414 struct cam_sensor_power_setting *pu = NULL;
415 struct cam_sensor_power_setting *pd = NULL;
416 struct cam_sensor_power_ctrl_t *power_info =
417 &s_ctrl->sensordata->power_info;
418
419 if (!s_ctrl || !arg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700420 CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800421 return -EINVAL;
422 }
423
424 mutex_lock(&(s_ctrl->cam_sensor_mutex));
425 switch (cmd->op_code) {
426 case CAM_SENSOR_PROBE_CMD: {
427 if (s_ctrl->is_probe_succeed == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700428 CAM_ERR(CAM_SENSOR,
429 "Already Sensor Probed in the slot");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800430 break;
431 }
432 /* Allocate memory for power up setting */
433 pu = kzalloc(sizeof(struct cam_sensor_power_setting) *
434 MAX_POWER_CONFIG, GFP_KERNEL);
435 if (!pu) {
436 rc = -ENOMEM;
437 goto release_mutex;
438 }
439
440 pd = kzalloc(sizeof(struct cam_sensor_power_setting) *
441 MAX_POWER_CONFIG, GFP_KERNEL);
442 if (!pd) {
443 kfree(pu);
444 rc = -ENOMEM;
445 goto release_mutex;
446 }
447
448 power_info->power_setting = pu;
449 power_info->power_down_setting = pd;
450
451 if (cmd->handle_type ==
452 CAM_HANDLE_MEM_HANDLE) {
453 rc = cam_handle_mem_ptr(cmd->handle, s_ctrl);
454 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700455 CAM_ERR(CAM_SENSOR, "Get Buffer Handle Failed");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800456 kfree(pu);
457 kfree(pd);
458 goto release_mutex;
459 }
460 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700461 CAM_ERR(CAM_SENSOR, "Invalid Command Type: %d",
462 cmd->handle_type);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800463 }
464
465 /* Parse and fill vreg params for powerup settings */
466 rc = msm_camera_fill_vreg_params(
Alok Pandey01b1b352017-06-25 20:38:54 +0530467 &s_ctrl->soc_info,
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800468 s_ctrl->sensordata->power_info.power_setting,
469 s_ctrl->sensordata->power_info.power_setting_size);
470 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700471 CAM_ERR(CAM_SENSOR,
472 "Fail in filling vreg params for PUP rc %d",
473 rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800474 kfree(pu);
475 kfree(pd);
476 goto release_mutex;
477 }
478
479 /* Parse and fill vreg params for powerdown settings*/
480 rc = msm_camera_fill_vreg_params(
Alok Pandey01b1b352017-06-25 20:38:54 +0530481 &s_ctrl->soc_info,
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800482 s_ctrl->sensordata->power_info.power_down_setting,
483 s_ctrl->sensordata->power_info.power_down_setting_size);
484 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700485 CAM_ERR(CAM_SENSOR,
486 "Fail in filling vreg params for PDOWN rc %d",
487 rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800488 kfree(pu);
489 kfree(pd);
490 goto release_mutex;
491 }
492
493 /* Power up and probe sensor */
494 rc = cam_sensor_power_up(s_ctrl);
495 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700496 CAM_ERR(CAM_SENSOR, "power up failed");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800497 cam_sensor_power_down(s_ctrl);
498 kfree(pu);
499 kfree(pd);
500 goto release_mutex;
501 }
502
503 /* Match sensor ID */
504 rc = cam_sensor_match_id(s_ctrl);
505 if (rc < 0) {
506 cam_sensor_power_down(s_ctrl);
507 msleep(20);
508 kfree(pu);
509 kfree(pd);
510 goto release_mutex;
511 }
512
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700513 CAM_DBG(CAM_SENSOR, "Probe Succeeded on the slot: %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530514 s_ctrl->soc_info.index);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800515 rc = cam_sensor_power_down(s_ctrl);
516 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700517 CAM_ERR(CAM_SENSOR, "fail in Sensor Power Down");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800518 kfree(pu);
519 kfree(pd);
520 goto release_mutex;
521 }
522 /*
523 * Set probe succeeded flag to 1 so that no other camera shall
524 * probed on this slot
525 */
526 s_ctrl->is_probe_succeed = 1;
527 }
528 break;
529 case CAM_ACQUIRE_DEV: {
530 struct cam_sensor_acquire_dev sensor_acq_dev;
531 struct cam_create_dev_hdl bridge_params;
532
533 if (s_ctrl->bridge_intf.device_hdl != -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700534 CAM_ERR(CAM_SENSOR, "Device is already acquired");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800535 rc = -EINVAL;
536 goto release_mutex;
537 }
538 rc = copy_from_user(&sensor_acq_dev,
539 (void __user *) cmd->handle, sizeof(sensor_acq_dev));
540 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700541 CAM_ERR(CAM_SENSOR, "Failed Copying from user");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800542 goto release_mutex;
543 }
544
545 bridge_params.session_hdl = sensor_acq_dev.session_handle;
546 bridge_params.ops = &s_ctrl->bridge_intf.ops;
547 bridge_params.v4l2_sub_dev_flag = 0;
548 bridge_params.media_entity_flag = 0;
549 bridge_params.priv = s_ctrl;
550
551 sensor_acq_dev.device_handle =
552 cam_create_device_hdl(&bridge_params);
553 s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle;
554 s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle;
555
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700556 CAM_DBG(CAM_SENSOR, "Device Handle: %d",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800557 sensor_acq_dev.device_handle);
558 if (copy_to_user((void __user *) cmd->handle, &sensor_acq_dev,
559 sizeof(struct cam_sensor_acquire_dev))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700560 CAM_ERR(CAM_SENSOR, "Failed Copy to User");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800561 rc = -EFAULT;
562 goto release_mutex;
563 }
564 }
565 break;
566 case CAM_RELEASE_DEV: {
567 if (s_ctrl->bridge_intf.device_hdl == -1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700568 CAM_ERR(CAM_SENSOR,
569 "Invalid Handles: link hdl: %d device hdl: %d",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800570 s_ctrl->bridge_intf.device_hdl,
571 s_ctrl->bridge_intf.link_hdl);
572 rc = -EINVAL;
573 goto release_mutex;
574 }
575 rc = cam_destroy_device_hdl(s_ctrl->bridge_intf.device_hdl);
576 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700577 CAM_ERR(CAM_SENSOR,
578 "failed in destroying the device hdl");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800579 s_ctrl->bridge_intf.device_hdl = -1;
580 s_ctrl->bridge_intf.link_hdl = -1;
581 s_ctrl->bridge_intf.session_hdl = -1;
582 }
583 break;
584 case CAM_QUERY_CAP: {
585 struct cam_sensor_query_cap sensor_cap;
586
587 cam_sensor_query_cap(s_ctrl, &sensor_cap);
588 if (copy_to_user((void __user *) cmd->handle, &sensor_cap,
589 sizeof(struct cam_sensor_query_cap))) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700590 CAM_ERR(CAM_SENSOR, "Failed Copy to User");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800591 rc = -EFAULT;
592 goto release_mutex;
593 }
594 break;
595 }
596 case CAM_START_DEV: {
597 rc = cam_sensor_power_up(s_ctrl);
598 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700599 CAM_ERR(CAM_SENSOR, "Sensor Power up failed");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800600 goto release_mutex;
601 }
602 rc = cam_sensor_apply_settings(s_ctrl, 0);
603 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700604 CAM_ERR(CAM_SENSOR, "cannot apply settings");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800605 goto release_mutex;
606 }
607 rc = delete_request(&s_ctrl->i2c_data.init_settings);
608 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700609 CAM_ERR(CAM_SENSOR,
610 "Fail in deleting the Init settings");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800611 rc = -EINVAL;
612 goto release_mutex;
613 }
614 }
615 break;
616 case CAM_STOP_DEV: {
617 rc = cam_sensor_power_down(s_ctrl);
618 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700619 CAM_ERR(CAM_SENSOR, "Sensor Power Down failed");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800620 goto release_mutex;
621 }
622 }
623 break;
624 case CAM_CONFIG_DEV: {
625 rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg);
626 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700627 CAM_ERR(CAM_SENSOR, "Failed CCI Config: %d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800628 goto release_mutex;
629 }
630 }
631 break;
Lakshmi Narayana Kalavalac2fac452017-06-12 12:38:07 -0700632 case CAM_SD_SHUTDOWN:
633 break;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800634 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700635 CAM_ERR(CAM_SENSOR, "Invalid Opcode: %d", cmd->op_code);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800636 rc = -EINVAL;
637 goto release_mutex;
638 }
639
640release_mutex:
641 mutex_unlock(&(s_ctrl->cam_sensor_mutex));
642 return rc;
643}
644
645int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info)
646{
647 int rc = 0;
648
649 if (!info)
650 return -EINVAL;
651
652 info->dev_id = CAM_REQ_MGR_DEVICE_SENSOR;
653 strlcpy(info->name, CAM_SENSOR_NAME, sizeof(info->name));
654 info->p_delay = 2;
Junzhe Zou2df84502017-05-26 13:20:23 -0700655 info->trigger = CAM_TRIGGER_POINT_SOF;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800656
657 return rc;
658}
659
660int cam_sensor_establish_link(struct cam_req_mgr_core_dev_link_setup *link)
661{
662 struct cam_sensor_ctrl_t *s_ctrl = NULL;
663
664 if (!link)
665 return -EINVAL;
666
667 s_ctrl = (struct cam_sensor_ctrl_t *)
668 cam_get_device_priv(link->dev_hdl);
669 if (!s_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700670 CAM_ERR(CAM_SENSOR, "Device data is NULL");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800671 return -EINVAL;
672 }
673 if (link->link_enable) {
674 s_ctrl->bridge_intf.link_hdl = link->link_hdl;
675 s_ctrl->bridge_intf.crm_cb = link->crm_cb;
676 } else {
677 s_ctrl->bridge_intf.link_hdl = -1;
678 s_ctrl->bridge_intf.crm_cb = NULL;
679 }
680
681 return 0;
682}
683
684int cam_sensor_power(struct v4l2_subdev *sd, int on)
685{
686 struct cam_sensor_ctrl_t *s_ctrl = v4l2_get_subdevdata(sd);
687
688 mutex_lock(&(s_ctrl->cam_sensor_mutex));
689 if (!on && s_ctrl->sensor_state == CAM_SENSOR_POWER_UP) {
690 cam_sensor_power_down(s_ctrl);
691 s_ctrl->sensor_state = CAM_SENSOR_POWER_DOWN;
692 }
693 mutex_unlock(&(s_ctrl->cam_sensor_mutex));
694
695 return 0;
696}
697
698int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
699{
700 int rc;
701 struct cam_sensor_power_ctrl_t *power_info;
702 struct cam_camera_slave_info *slave_info;
Alok Pandey01b1b352017-06-25 20:38:54 +0530703 struct cam_hw_soc_info *soc_info =
704 &s_ctrl->soc_info;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800705
706 if (!s_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700707 CAM_ERR(CAM_SENSOR, "failed: %pK", s_ctrl);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800708 return -EINVAL;
709 }
710
711 power_info = &s_ctrl->sensordata->power_info;
712 slave_info = &(s_ctrl->sensordata->slave_info);
713
714 if (!power_info || !slave_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700715 CAM_ERR(CAM_SENSOR, "failed: %pK %pK", power_info, slave_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800716 return -EINVAL;
717 }
718
Alok Pandey01b1b352017-06-25 20:38:54 +0530719 rc = cam_sensor_core_power_up(power_info, soc_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800720 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700721 CAM_ERR(CAM_SENSOR, "power up the core is failed:%d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800722 return rc;
723 }
724
725 if (s_ctrl->io_master_info.master_type == CCI_MASTER) {
726 rc = camera_io_init(&(s_ctrl->io_master_info));
727 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700728 CAM_ERR(CAM_SENSOR, "cci_init failed");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800729 return -EINVAL;
730 }
731 }
732
733 s_ctrl->sensor_state = CAM_SENSOR_POWER_UP;
734
735 return rc;
736}
737
738int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)
739{
740 struct cam_sensor_power_ctrl_t *power_info;
Alok Pandey01b1b352017-06-25 20:38:54 +0530741 struct cam_hw_soc_info *soc_info;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800742 int rc = 0;
743
744 if (!s_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700745 CAM_ERR(CAM_SENSOR, "failed: s_ctrl %pK", s_ctrl);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800746 return -EINVAL;
747 }
748
749 power_info = &s_ctrl->sensordata->power_info;
Alok Pandey01b1b352017-06-25 20:38:54 +0530750 soc_info = &s_ctrl->soc_info;
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800751
752 if (!power_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700753 CAM_ERR(CAM_SENSOR, "failed: power_info %pK", power_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800754 return -EINVAL;
755 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530756 rc = msm_camera_power_down(power_info, soc_info);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800757 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700758 CAM_ERR(CAM_SENSOR, "power down the core is failed:%d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800759 return rc;
760 }
761
762 if (s_ctrl->io_master_info.master_type == CCI_MASTER)
763 camera_io_release(&(s_ctrl->io_master_info));
764
765 s_ctrl->sensor_state = CAM_SENSOR_POWER_DOWN;
766
767 return rc;
768}
769
770int cam_sensor_apply_settings(struct cam_sensor_ctrl_t *s_ctrl,
771 int64_t req_id)
772{
773 int rc = 0, offset, del_req_id;
774 struct i2c_settings_array *i2c_set = NULL;
775 struct i2c_settings_list *i2c_list;
776
777 if (req_id == 0) {
778 i2c_set = &s_ctrl->i2c_data.init_settings;
779 if (i2c_set->is_settings_valid == 1) {
780 list_for_each_entry(i2c_list,
781 &(i2c_set->list_head), list) {
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700782 rc = cam_sensor_i2c_modes_util(
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800783 &(s_ctrl->io_master_info),
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700784 i2c_list);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800785 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700786 CAM_ERR(CAM_SENSOR,
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700787 "Failed to apply settings: %d",
788 rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800789 return rc;
790 }
791 }
792 rc = delete_request(&(s_ctrl->i2c_data.init_settings));
793 i2c_set->is_settings_valid = 0;
794 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700795 CAM_ERR(CAM_SENSOR,
796 "Failed in deleting the Init request: %d", rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800797 }
798 }
799 } else {
800 offset = req_id % MAX_PER_FRAME_ARRAY;
801 i2c_set = &(s_ctrl->i2c_data.per_frame[offset]);
802 if (i2c_set->is_settings_valid == 1 &&
803 i2c_set->request_id == req_id) {
804 list_for_each_entry(i2c_list,
805 &(i2c_set->list_head), list) {
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700806 rc = cam_sensor_i2c_modes_util(
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800807 &(s_ctrl->io_master_info),
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700808 i2c_list);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800809 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700810 CAM_ERR(CAM_SENSOR,
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700811 "Failed to apply settings: %d",
812 rc);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800813 return rc;
814 }
815 }
816 del_req_id = (req_id +
817 MAX_PER_FRAME_ARRAY -
818 MAX_SYSTEM_PIPELINE_DELAY) %
819 MAX_PER_FRAME_ARRAY;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700820 CAM_DBG(CAM_SENSOR, "Deleting the Request: %d",
821 del_req_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800822 if (req_id >
823 s_ctrl->i2c_data.per_frame[del_req_id].
824 request_id) {
825 s_ctrl->i2c_data.per_frame[del_req_id].
826 request_id = 0;
827 rc = delete_request(
828 &(s_ctrl->i2c_data.
829 per_frame[del_req_id]));
830 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700831 CAM_ERR(CAM_SENSOR,
832 "Delete request Fail:%d rc:%d",
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800833 del_req_id, rc);
834 }
835 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700836 CAM_DBG(CAM_SENSOR,
837 "Invalid/NOP request to apply: %lld", req_id);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800838 }
839 }
840 return rc;
841}
842
843int32_t cam_sensor_apply_request(struct cam_req_mgr_apply_request *apply)
844{
845 int32_t rc = 0;
846 struct cam_sensor_ctrl_t *s_ctrl = NULL;
847
848 if (!apply)
849 return -EINVAL;
850
851 s_ctrl = (struct cam_sensor_ctrl_t *)
852 cam_get_device_priv(apply->dev_hdl);
853 if (!s_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700854 CAM_ERR(CAM_SENSOR, "Device data is NULL");
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800855 return -EINVAL;
856 }
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700857 CAM_DBG(CAM_SENSOR, " Req Id: %lld", apply->request_id);
Gregory Bergschneider5164f3a2017-07-07 10:26:17 -0600858 trace_cam_apply_req("Sensor", apply);
Viswanadha Raju Thotakura7208eb72017-02-26 16:56:34 -0800859 rc = cam_sensor_apply_settings(s_ctrl, apply->request_id);
860 return rc;
861}
Vivek Veenamd5e39cd2017-05-23 15:48:03 +0530862
863int32_t cam_sensor_flush_request(struct cam_req_mgr_flush_request *flush_req)
864{
865 int32_t rc = 0, i;
866 uint32_t cancel_req_id_found = 0;
867 struct cam_sensor_ctrl_t *s_ctrl = NULL;
868 struct i2c_settings_array *i2c_set = NULL;
869
870 if (!flush_req)
871 return -EINVAL;
872
873 s_ctrl = (struct cam_sensor_ctrl_t *)
874 cam_get_device_priv(flush_req->dev_hdl);
875 if (!s_ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700876 CAM_ERR(CAM_SENSOR, "Device data is NULL");
Vivek Veenamd5e39cd2017-05-23 15:48:03 +0530877 return -EINVAL;
878 }
879
880 for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
881 i2c_set = &(s_ctrl->i2c_data.per_frame[i]);
882
883 if ((flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ)
884 && (i2c_set->request_id != flush_req->req_id))
885 continue;
886
887 if (i2c_set->is_settings_valid == 1) {
888 rc = delete_request(i2c_set);
889 if (rc < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700890 CAM_ERR(CAM_SENSOR,
891 "delete request: %lld rc: %d",
Vivek Veenamd5e39cd2017-05-23 15:48:03 +0530892 i2c_set->request_id, rc);
893
894 if (flush_req->type ==
895 CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ) {
896 cancel_req_id_found = 1;
897 break;
898 }
899 }
900 }
901
902 if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_CANCEL_REQ &&
903 !cancel_req_id_found)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700904 CAM_DBG(CAM_SENSOR,
905 "Flush request id:%lld not found in the pending list",
906 flush_req->req_id);
Vivek Veenamd5e39cd2017-05-23 15:48:03 +0530907 return rc;
908}