blob: 3abdd80a796f253938b5c0d9503c1d7aacf5f238 [file] [log] [blame]
Vivek Veenam2ad8de12017-04-04 18:56:22 +05301/* 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 <linux/crc32.h>
15#include <media/cam_sensor.h>
16
17#include "cam_eeprom_core.h"
18#include "cam_eeprom_soc.h"
19#include "cam_debug_util.h"
20
21/**
22 * cam_eeprom_read_memory() - read map data into buffer
23 * @e_ctrl: eeprom control struct
24 * @block: block to be read
25 *
26 * This function iterates through blocks stored in block->map, reads each
27 * region and concatenate them into the pre-allocated block->mapdata
28 */
29static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
30 struct cam_eeprom_memory_block_t *block)
31{
32 int rc = 0;
33 int j;
34 struct cam_sensor_i2c_reg_setting i2c_reg_settings;
35 struct cam_sensor_i2c_reg_array i2c_reg_array;
36 struct cam_eeprom_memory_map_t *emap = block->map;
37 struct cam_eeprom_soc_private *eb_info;
38 uint8_t *memptr = block->mapdata;
39
40 if (!e_ctrl) {
41 CAM_ERR(CAM_EEPROM, "e_ctrl is NULL");
42 return -EINVAL;
43 }
44
45 eb_info = (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
46
47 for (j = 0; j < block->num_map; j++) {
48 CAM_DBG(CAM_EEPROM, "slave-addr = 0x%X", emap[j].saddr);
49 if (emap[j].saddr) {
50 eb_info->i2c_info.slave_addr = emap[j].saddr;
51 rc = cam_eeprom_update_i2c_info(e_ctrl,
52 &eb_info->i2c_info);
53 if (rc) {
54 CAM_ERR(CAM_EEPROM,
55 "failed: to update i2c info rc %d",
56 rc);
57 return rc;
58 }
59 }
60
61 if (emap[j].page.valid_size) {
62 i2c_reg_settings.addr_type = emap[j].page.addr_type;
63 i2c_reg_settings.data_type = emap[j].page.data_type;
64 i2c_reg_settings.size = 1;
65 i2c_reg_array.reg_addr = emap[j].page.addr;
66 i2c_reg_array.reg_data = emap[j].page.data;
67 i2c_reg_array.delay = emap[j].page.delay;
68 i2c_reg_settings.reg_setting = &i2c_reg_array;
69 rc = camera_io_dev_write(&e_ctrl->io_master_info,
70 &i2c_reg_settings);
71 if (rc) {
72 CAM_ERR(CAM_EEPROM, "page write failed rc %d",
73 rc);
74 return rc;
75 }
76 }
77
78 if (emap[j].pageen.valid_size) {
79 i2c_reg_settings.addr_type = emap[j].pageen.addr_type;
80 i2c_reg_settings.data_type = emap[j].pageen.data_type;
81 i2c_reg_settings.size = 1;
82 i2c_reg_array.reg_addr = emap[j].pageen.addr;
83 i2c_reg_array.reg_data = emap[j].pageen.data;
84 i2c_reg_array.delay = emap[j].pageen.delay;
85 i2c_reg_settings.reg_setting = &i2c_reg_array;
86 rc = camera_io_dev_write(&e_ctrl->io_master_info,
87 &i2c_reg_settings);
88 if (rc) {
89 CAM_ERR(CAM_EEPROM, "page enable failed rc %d",
90 rc);
91 return rc;
92 }
93 }
94
95 if (emap[j].poll.valid_size) {
96 rc = camera_io_dev_poll(&e_ctrl->io_master_info,
97 emap[j].poll.addr, emap[j].poll.data,
98 0, emap[j].poll.addr_type,
99 emap[j].poll.data_type,
100 emap[j].poll.delay);
101 if (rc) {
102 CAM_ERR(CAM_EEPROM, "poll failed rc %d",
103 rc);
104 return rc;
105 }
106 }
107
108 if (emap[j].mem.valid_size) {
109 rc = camera_io_dev_read_seq(&e_ctrl->io_master_info,
110 emap[j].mem.addr, memptr,
111 emap[j].mem.addr_type,
112 emap[j].mem.valid_size);
113 if (rc) {
114 CAM_ERR(CAM_EEPROM, "read failed rc %d",
115 rc);
116 return rc;
117 }
118 memptr += emap[j].mem.valid_size;
119 }
120
121 if (emap[j].pageen.valid_size) {
122 i2c_reg_settings.addr_type = emap[j].pageen.addr_type;
123 i2c_reg_settings.data_type = emap[j].pageen.data_type;
124 i2c_reg_settings.size = 1;
125 i2c_reg_array.reg_addr = emap[j].pageen.addr;
126 i2c_reg_array.reg_data = 0;
127 i2c_reg_array.delay = emap[j].pageen.delay;
128 i2c_reg_settings.reg_setting = &i2c_reg_array;
129 rc = camera_io_dev_write(&e_ctrl->io_master_info,
130 &i2c_reg_settings);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530131 if (rc) {
132 CAM_ERR(CAM_EEPROM,
133 "page disable failed rc %d",
134 rc);
135 return rc;
136 }
137 }
138 }
139 return rc;
140}
141
142/**
143 * cam_eeprom_power_up - Power up eeprom hardware
144 * @e_ctrl: ctrl structure
145 * @power_info: power up/down info for eeprom
146 *
147 * Returns success or failure
148 */
149static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
150 struct cam_sensor_power_ctrl_t *power_info)
151{
152 int32_t rc = 0;
153 struct cam_hw_soc_info *soc_info =
154 &e_ctrl->soc_info;
155
156 /* Parse and fill vreg params for power up settings */
157 rc = msm_camera_fill_vreg_params(
158 &e_ctrl->soc_info,
159 power_info->power_setting,
160 power_info->power_setting_size);
161 if (rc) {
162 CAM_ERR(CAM_EEPROM,
163 "failed to fill vreg params for power up rc:%d", rc);
164 return rc;
165 }
166
167 /* Parse and fill vreg params for power down settings*/
168 rc = msm_camera_fill_vreg_params(
169 &e_ctrl->soc_info,
170 power_info->power_down_setting,
171 power_info->power_down_setting_size);
172 if (rc) {
173 CAM_ERR(CAM_EEPROM,
174 "failed to fill vreg params power down rc:%d", rc);
175 return rc;
176 }
177
Viswanadha Raju Thotakuraf721c962017-10-08 20:57:51 -0700178 power_info->dev = soc_info->dev;
179
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530180 rc = cam_sensor_core_power_up(power_info, soc_info);
181 if (rc) {
182 CAM_ERR(CAM_EEPROM, "failed in eeprom power up rc %d", rc);
183 return rc;
184 }
185
186 if (e_ctrl->io_master_info.master_type == CCI_MASTER) {
187 rc = camera_io_init(&(e_ctrl->io_master_info));
188 if (rc) {
189 CAM_ERR(CAM_EEPROM, "cci_init failed");
190 return -EINVAL;
191 }
192 }
193 return rc;
194}
195
196/**
197 * cam_eeprom_power_down - Power down eeprom hardware
198 * @e_ctrl: ctrl structure
199 *
200 * Returns success or failure
201 */
202static int cam_eeprom_power_down(struct cam_eeprom_ctrl_t *e_ctrl)
203{
204 struct cam_sensor_power_ctrl_t *power_info;
205 struct cam_hw_soc_info *soc_info;
206 struct cam_eeprom_soc_private *soc_private;
207 int rc = 0;
208
209 if (!e_ctrl) {
210 CAM_ERR(CAM_EEPROM, "failed: e_ctrl %pK", e_ctrl);
211 return -EINVAL;
212 }
213
214 soc_private =
215 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
216 power_info = &soc_private->power_info;
217 soc_info = &e_ctrl->soc_info;
218
219 if (!power_info) {
220 CAM_ERR(CAM_EEPROM, "failed: power_info %pK", power_info);
221 return -EINVAL;
222 }
223 rc = msm_camera_power_down(power_info, soc_info);
224 if (rc) {
225 CAM_ERR(CAM_EEPROM, "power down the core is failed:%d", rc);
226 return rc;
227 }
228
229 if (e_ctrl->io_master_info.master_type == CCI_MASTER)
230 camera_io_release(&(e_ctrl->io_master_info));
231
232 return rc;
233}
234
235/**
236 * cam_eeprom_match_id - match eeprom id
237 * @e_ctrl: ctrl structure
238 *
239 * Returns success or failure
240 */
241static int cam_eeprom_match_id(struct cam_eeprom_ctrl_t *e_ctrl)
242{
243 int rc;
244 struct camera_io_master *client = &e_ctrl->io_master_info;
245 uint8_t id[2];
246
Jigarkumar Zala80a11402017-09-05 16:14:59 -0700247 rc = cam_spi_query_id(client, 0, CAMERA_SENSOR_I2C_TYPE_WORD,
248 &id[0], 2);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530249 if (rc)
250 return rc;
251 CAM_DBG(CAM_EEPROM, "read 0x%x 0x%x, check 0x%x 0x%x",
252 id[0], id[1], client->spi_client->mfr_id0,
253 client->spi_client->device_id0);
254 if (id[0] != client->spi_client->mfr_id0
255 || id[1] != client->spi_client->device_id0)
256 return -ENODEV;
257 return 0;
258}
259
260/**
261 * cam_eeprom_parse_read_memory_map - Parse memory map
262 * @of_node: device node
263 * @e_ctrl: ctrl structure
264 *
265 * Returns success or failure
266 */
267int32_t cam_eeprom_parse_read_memory_map(struct device_node *of_node,
268 struct cam_eeprom_ctrl_t *e_ctrl)
269{
270 int32_t rc = 0;
271 struct cam_eeprom_soc_private *soc_private;
272 struct cam_sensor_power_ctrl_t *power_info;
273
274 if (!e_ctrl) {
275 CAM_ERR(CAM_EEPROM, "failed: e_ctrl is NULL");
276 return -EINVAL;
277 }
278
279 soc_private =
280 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
281 power_info = &soc_private->power_info;
282
283 rc = cam_eeprom_parse_dt_memory_map(of_node, &e_ctrl->cal_data);
284 if (rc) {
285 CAM_ERR(CAM_EEPROM, "failed: eeprom dt parse rc %d", rc);
286 return rc;
287 }
288 rc = cam_eeprom_power_up(e_ctrl, power_info);
289 if (rc) {
290 CAM_ERR(CAM_EEPROM, "failed: eeprom power up rc %d", rc);
291 goto data_mem_free;
292 }
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700293
294 e_ctrl->cam_eeprom_state = CAM_EEPROM_CONFIG;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530295 if (e_ctrl->eeprom_device_type == MSM_CAMERA_SPI_DEVICE) {
296 rc = cam_eeprom_match_id(e_ctrl);
297 if (rc) {
298 CAM_DBG(CAM_EEPROM, "eeprom not matching %d", rc);
299 goto power_down;
300 }
301 }
302 rc = cam_eeprom_read_memory(e_ctrl, &e_ctrl->cal_data);
303 if (rc) {
304 CAM_ERR(CAM_EEPROM, "read_eeprom_memory failed");
305 goto power_down;
306 }
307
308 rc = cam_eeprom_power_down(e_ctrl);
309 if (rc)
310 CAM_ERR(CAM_EEPROM, "failed: eeprom power down rc %d", rc);
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700311
312 e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530313 return rc;
314power_down:
Sureshnaidu Laveti3dc87ea2017-10-15 20:53:42 -0700315 cam_eeprom_power_down(e_ctrl);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530316data_mem_free:
317 kfree(e_ctrl->cal_data.mapdata);
318 kfree(e_ctrl->cal_data.map);
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700319 e_ctrl->cal_data.num_data = 0;
320 e_ctrl->cal_data.num_map = 0;
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700321 e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530322 return rc;
323}
324
325/**
326 * cam_eeprom_get_dev_handle - get device handle
327 * @e_ctrl: ctrl structure
328 * @arg: Camera control command argument
329 *
330 * Returns success or failure
331 */
332static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl,
333 void *arg)
334{
335 struct cam_sensor_acquire_dev eeprom_acq_dev;
336 struct cam_create_dev_hdl bridge_params;
337 struct cam_control *cmd = (struct cam_control *)arg;
338
339 if (e_ctrl->bridge_intf.device_hdl != -1) {
340 CAM_ERR(CAM_EEPROM, "Device is already acquired");
341 return -EFAULT;
342 }
343 if (copy_from_user(&eeprom_acq_dev, (void __user *) cmd->handle,
344 sizeof(eeprom_acq_dev))) {
345 CAM_ERR(CAM_EEPROM,
346 "EEPROM:ACQUIRE_DEV: copy from user failed");
347 return -EFAULT;
348 }
349
350 bridge_params.session_hdl = eeprom_acq_dev.session_handle;
351 bridge_params.ops = &e_ctrl->bridge_intf.ops;
352 bridge_params.v4l2_sub_dev_flag = 0;
353 bridge_params.media_entity_flag = 0;
354 bridge_params.priv = e_ctrl;
355
356 eeprom_acq_dev.device_handle =
357 cam_create_device_hdl(&bridge_params);
358 e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle;
359 e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle;
360
361 CAM_DBG(CAM_EEPROM, "Device Handle: %d", eeprom_acq_dev.device_handle);
362 if (copy_to_user((void __user *) cmd->handle, &eeprom_acq_dev,
363 sizeof(struct cam_sensor_acquire_dev))) {
364 CAM_ERR(CAM_EEPROM, "EEPROM:ACQUIRE_DEV: copy to user failed");
365 return -EFAULT;
366 }
367 return 0;
368}
369
370/**
371 * cam_eeprom_update_slaveInfo - Update slave info
372 * @e_ctrl: ctrl structure
373 * @cmd_buf: command buffer
374 *
375 * Returns success or failure
376 */
377static int32_t cam_eeprom_update_slaveInfo(struct cam_eeprom_ctrl_t *e_ctrl,
378 void *cmd_buf)
379{
380 int32_t rc = 0;
381 struct cam_eeprom_soc_private *soc_private;
382 struct cam_cmd_i2c_info *cmd_i2c_info = NULL;
383
384 soc_private =
385 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
386 cmd_i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
387 soc_private->i2c_info.slave_addr = cmd_i2c_info->slave_addr;
388 soc_private->i2c_info.i2c_freq_mode = cmd_i2c_info->i2c_freq_mode;
389
390 rc = cam_eeprom_update_i2c_info(e_ctrl,
391 &soc_private->i2c_info);
392 CAM_DBG(CAM_EEPROM, "Slave addr: 0x%x Freq Mode: %d",
393 soc_private->i2c_info.slave_addr,
394 soc_private->i2c_info.i2c_freq_mode);
395
396 return rc;
397}
398
399/**
400 * cam_eeprom_parse_memory_map - Parse memory map info
401 * @data: memory block data
402 * @cmd_buf: command buffer
403 * @cmd_length: command buffer length
404 * @num_map: memory map size
405 * @cmd_length_bytes: command length processed in this function
406 *
407 * Returns success or failure
408 */
409static int32_t cam_eeprom_parse_memory_map(
410 struct cam_eeprom_memory_block_t *data,
411 void *cmd_buf, int cmd_length, uint16_t *cmd_length_bytes,
Depeng Shao08176382017-11-20 19:40:09 +0800412 int *num_map)
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530413{
414 int32_t rc = 0;
Depeng Shao08176382017-11-20 19:40:09 +0800415 int32_t cnt = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530416 int32_t processed_size = 0;
Depeng Shao08176382017-11-20 19:40:09 +0800417 uint8_t generic_op_code;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530418 struct cam_eeprom_memory_map_t *map = data->map;
419 struct common_header *cmm_hdr =
420 (struct common_header *)cmd_buf;
421 uint16_t cmd_length_in_bytes = 0;
422 struct cam_cmd_i2c_random_wr *i2c_random_wr = NULL;
423 struct cam_cmd_i2c_continuous_rd *i2c_cont_rd = NULL;
424 struct cam_cmd_conditional_wait *i2c_poll = NULL;
Depeng Shao08176382017-11-20 19:40:09 +0800425 struct cam_cmd_unconditional_wait *i2c_uncond_wait = NULL;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530426
Depeng Shao08176382017-11-20 19:40:09 +0800427 generic_op_code = cmm_hdr->third_byte;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530428 switch (cmm_hdr->cmd_type) {
429 case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
430 i2c_random_wr = (struct cam_cmd_i2c_random_wr *)cmd_buf;
Depeng Shao08176382017-11-20 19:40:09 +0800431 cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_random_wr) +
432 ((i2c_random_wr->header.count - 1) *
433 sizeof(struct i2c_random_wr_payload));
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530434
Depeng Shao08176382017-11-20 19:40:09 +0800435 for (cnt = 0; cnt < (i2c_random_wr->header.count);
436 cnt++) {
437 map[*num_map + cnt].page.addr =
438 i2c_random_wr->random_wr_payload[cnt].reg_addr;
439 map[*num_map + cnt].page.addr_type =
440 i2c_random_wr->header.addr_type;
441 map[*num_map + cnt].page.data =
442 i2c_random_wr->random_wr_payload[cnt].reg_data;
443 map[*num_map + cnt].page.data_type =
444 i2c_random_wr->header.data_type;
445 map[*num_map + cnt].page.valid_size = 1;
446 }
447
448 *num_map += (i2c_random_wr->header.count - 1);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530449 cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
450 processed_size +=
451 cmd_length_in_bytes;
452 break;
453 case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
454 i2c_cont_rd = (struct cam_cmd_i2c_continuous_rd *)cmd_buf;
455 cmd_length_in_bytes = sizeof(struct cam_cmd_i2c_continuous_rd);
456
Depeng Shao08176382017-11-20 19:40:09 +0800457 map[*num_map].mem.addr = i2c_cont_rd->reg_addr;
458 map[*num_map].mem.addr_type = i2c_cont_rd->header.addr_type;
459 map[*num_map].mem.data_type = i2c_cont_rd->header.data_type;
460 map[*num_map].mem.valid_size =
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530461 i2c_cont_rd->header.count;
462 cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
463 processed_size +=
464 cmd_length_in_bytes;
Depeng Shao08176382017-11-20 19:40:09 +0800465 data->num_data += map[*num_map].mem.valid_size;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530466 break;
467 case CAMERA_SENSOR_CMD_TYPE_WAIT:
Depeng Shao08176382017-11-20 19:40:09 +0800468 if (generic_op_code ==
469 CAMERA_SENSOR_WAIT_OP_HW_UCND ||
470 generic_op_code ==
471 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
472 i2c_uncond_wait =
473 (struct cam_cmd_unconditional_wait *)cmd_buf;
474 cmd_length_in_bytes =
475 sizeof(struct cam_cmd_unconditional_wait);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530476
Depeng Shao08176382017-11-20 19:40:09 +0800477 if (*num_map < 1) {
478 CAM_ERR(CAM_EEPROM,
479 "invalid map number, num_map=%d",
480 *num_map);
481 return -EINVAL;
482 }
483
484 /*
485 * Though delay is added all of them, but delay will
486 * be applicable to only one of them as only one of
487 * them will have valid_size set to >= 1.
488 */
489 map[*num_map - 1].mem.delay = i2c_uncond_wait->delay;
490 map[*num_map - 1].page.delay = i2c_uncond_wait->delay;
491 map[*num_map - 1].pageen.delay = i2c_uncond_wait->delay;
492 } else if (generic_op_code ==
493 CAMERA_SENSOR_WAIT_OP_COND) {
494 i2c_poll = (struct cam_cmd_conditional_wait *)cmd_buf;
495 cmd_length_in_bytes =
496 sizeof(struct cam_cmd_conditional_wait);
497
498 map[*num_map].poll.addr = i2c_poll->reg_addr;
499 map[*num_map].poll.addr_type = i2c_poll->addr_type;
500 map[*num_map].poll.data = i2c_poll->reg_data;
501 map[*num_map].poll.data_type = i2c_poll->data_type;
502 map[*num_map].poll.delay = i2c_poll->timeout;
503 map[*num_map].poll.valid_size = 1;
504 }
505 cmd_buf += cmd_length_in_bytes / sizeof(int32_t);
506 processed_size +=
507 cmd_length_in_bytes;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530508 break;
509 default:
510 break;
511 }
Depeng Shao08176382017-11-20 19:40:09 +0800512
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530513 *cmd_length_bytes = processed_size;
514 return rc;
515}
516
517/**
518 * cam_eeprom_init_pkt_parser - Parse eeprom packet
519 * @e_ctrl: ctrl structure
520 * @csl_packet: csl packet received
521 *
522 * Returns success or failure
523 */
524static int32_t cam_eeprom_init_pkt_parser(struct cam_eeprom_ctrl_t *e_ctrl,
525 struct cam_packet *csl_packet)
526{
527 int32_t rc = 0;
528 int i = 0;
529 struct cam_cmd_buf_desc *cmd_desc = NULL;
530 uint32_t *offset = NULL;
531 uint32_t *cmd_buf = NULL;
532 uint64_t generic_pkt_addr;
533 size_t pkt_len = 0;
534 uint32_t total_cmd_buf_in_bytes = 0;
535 uint32_t processed_cmd_buf_in_bytes = 0;
536 struct common_header *cmm_hdr = NULL;
537 uint16_t cmd_length_in_bytes = 0;
538 struct cam_cmd_i2c_info *i2c_info = NULL;
539 int num_map = -1;
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700540 struct cam_eeprom_memory_map_t *map = NULL;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530541 struct cam_eeprom_soc_private *soc_private =
542 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
543 struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
544
545 e_ctrl->cal_data.map = kcalloc((MSM_EEPROM_MEMORY_MAP_MAX_SIZE *
546 MSM_EEPROM_MAX_MEM_MAP_CNT),
547 (sizeof(struct cam_eeprom_memory_map_t)), GFP_KERNEL);
548 if (!e_ctrl->cal_data.map) {
549 rc = -ENOMEM;
550 CAM_ERR(CAM_EEPROM, "failed");
551 return rc;
552 }
553 map = e_ctrl->cal_data.map;
554
555 offset = (uint32_t *)&csl_packet->payload;
556 offset += (csl_packet->cmd_buf_offset / sizeof(uint32_t));
557 cmd_desc = (struct cam_cmd_buf_desc *)(offset);
558
559 /* Loop through multiple command buffers */
560 for (i = 0; i < csl_packet->num_cmd_buf; i++) {
561 total_cmd_buf_in_bytes = cmd_desc[i].length;
562 processed_cmd_buf_in_bytes = 0;
563 if (!total_cmd_buf_in_bytes)
564 continue;
565 rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
566 (uint64_t *)&generic_pkt_addr, &pkt_len);
567 if (rc) {
568 CAM_ERR(CAM_EEPROM, "Failed to get cpu buf");
569 return rc;
570 }
571 cmd_buf = (uint32_t *)generic_pkt_addr;
572 if (!cmd_buf) {
573 CAM_ERR(CAM_EEPROM, "invalid cmd buf");
574 return -EINVAL;
575 }
576 cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
577 /* Loop through multiple cmd formats in one cmd buffer */
578 while (processed_cmd_buf_in_bytes < total_cmd_buf_in_bytes) {
579 cmm_hdr = (struct common_header *)cmd_buf;
580 switch (cmm_hdr->cmd_type) {
581 case CAMERA_SENSOR_CMD_TYPE_I2C_INFO:
582 i2c_info = (struct cam_cmd_i2c_info *)cmd_buf;
Depeng Shao08176382017-11-20 19:40:09 +0800583 /* Configure the following map slave address */
584 map[num_map + 1].saddr = i2c_info->slave_addr;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530585 rc = cam_eeprom_update_slaveInfo(e_ctrl,
586 cmd_buf);
587 cmd_length_in_bytes =
588 sizeof(struct cam_cmd_i2c_info);
589 processed_cmd_buf_in_bytes +=
590 cmd_length_in_bytes;
591 cmd_buf += cmd_length_in_bytes/4;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530592 break;
593 case CAMERA_SENSOR_CMD_TYPE_PWR_UP:
594 case CAMERA_SENSOR_CMD_TYPE_PWR_DOWN:
595 cmd_length_in_bytes =
596 sizeof(struct cam_cmd_power);
597 rc = cam_sensor_update_power_settings(cmd_buf,
598 cmd_length_in_bytes, power_info);
599 processed_cmd_buf_in_bytes +=
Karthik Anantha Ramb63757b2017-11-30 15:12:24 -0800600 total_cmd_buf_in_bytes;
601 cmd_buf += total_cmd_buf_in_bytes/4;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530602 if (rc) {
603 CAM_ERR(CAM_EEPROM, "Failed");
604 return rc;
605 }
606 break;
607 case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR:
608 case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_RD:
609 case CAMERA_SENSOR_CMD_TYPE_WAIT:
Depeng Shao08176382017-11-20 19:40:09 +0800610 num_map++;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530611 rc = cam_eeprom_parse_memory_map(
612 &e_ctrl->cal_data, cmd_buf,
613 total_cmd_buf_in_bytes,
Depeng Shao08176382017-11-20 19:40:09 +0800614 &cmd_length_in_bytes, &num_map);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530615 processed_cmd_buf_in_bytes +=
616 cmd_length_in_bytes;
617 cmd_buf += cmd_length_in_bytes/4;
618 break;
619 default:
620 break;
621 }
622 }
Depeng Shao08176382017-11-20 19:40:09 +0800623 e_ctrl->cal_data.num_map = num_map + 1;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530624 }
625 return rc;
626}
627
628/**
629 * cam_eeprom_get_cal_data - parse the userspace IO config and
630 * copy read data to share with userspace
631 * @e_ctrl: ctrl structure
632 * @csl_packet: csl packet received
633 *
634 * Returns success or failure
635 */
636static int32_t cam_eeprom_get_cal_data(struct cam_eeprom_ctrl_t *e_ctrl,
637 struct cam_packet *csl_packet)
638{
639 struct cam_buf_io_cfg *io_cfg;
640 uint32_t i = 0;
641 int rc = 0;
642 uint64_t buf_addr;
643 size_t buf_size;
644 uint8_t *read_buffer;
645
646 io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
647 &csl_packet->payload +
648 csl_packet->io_configs_offset);
649
650 CAM_DBG(CAM_EEPROM, "number of IO configs: %d:",
651 csl_packet->num_io_configs);
652
653 for (i = 0; i < csl_packet->num_io_configs; i++) {
654 CAM_DBG(CAM_EEPROM, "Direction: %d:", io_cfg->direction);
655 if (io_cfg->direction == CAM_BUF_OUTPUT) {
656 rc = cam_mem_get_cpu_buf(io_cfg->mem_handle[0],
657 (uint64_t *)&buf_addr, &buf_size);
Soundrapandian Jeyaprakashafdca892017-07-27 15:23:13 -0700658 CAM_DBG(CAM_EEPROM, "buf_addr : %pK, buf_size : %zu\n",
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530659 (void *)buf_addr, buf_size);
660
661 read_buffer = (uint8_t *)buf_addr;
662 if (!read_buffer) {
663 CAM_ERR(CAM_EEPROM,
664 "invalid buffer to copy data");
665 return -EINVAL;
666 }
667 read_buffer += io_cfg->offsets[0];
668
669 if (buf_size < e_ctrl->cal_data.num_data) {
670 CAM_ERR(CAM_EEPROM,
671 "failed to copy, Invalid size");
672 return -EINVAL;
673 }
674
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700675 CAM_DBG(CAM_EEPROM, "copy the data, len:%d",
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530676 e_ctrl->cal_data.num_data);
677 memcpy(read_buffer, e_ctrl->cal_data.mapdata,
678 e_ctrl->cal_data.num_data);
679
680 } else {
681 CAM_ERR(CAM_EEPROM, "Invalid direction");
682 rc = -EINVAL;
683 }
684 }
685 return rc;
686}
687
688/**
689 * cam_eeprom_pkt_parse - Parse csl packet
690 * @e_ctrl: ctrl structure
691 * @arg: Camera control command argument
692 *
693 * Returns success or failure
694 */
695static int32_t cam_eeprom_pkt_parse(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
696{
697 int32_t rc = 0;
698 struct cam_control *ioctl_ctrl = NULL;
699 struct cam_config_dev_cmd dev_config;
700 uint64_t generic_pkt_addr;
701 size_t pkt_len;
702 struct cam_packet *csl_packet = NULL;
703 struct cam_eeprom_soc_private *soc_private =
704 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
Depeng Shao6b7576b2017-11-10 16:04:31 +0800705 struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530706
707 ioctl_ctrl = (struct cam_control *)arg;
Jigarkumar Zalad724ec22017-10-24 16:30:01 -0700708
709 if (ioctl_ctrl->handle_type != CAM_HANDLE_USER_POINTER) {
710 CAM_ERR(CAM_EEPROM, "Invalid Handle Type");
711 return -EINVAL;
712 }
713
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530714 if (copy_from_user(&dev_config, (void __user *) ioctl_ctrl->handle,
715 sizeof(dev_config)))
716 return -EFAULT;
717 rc = cam_mem_get_cpu_buf(dev_config.packet_handle,
718 (uint64_t *)&generic_pkt_addr, &pkt_len);
719 if (rc) {
720 CAM_ERR(CAM_EEPROM,
721 "error in converting command Handle Error: %d", rc);
722 return rc;
723 }
Jigarkumar Zalad724ec22017-10-24 16:30:01 -0700724
725 if (dev_config.offset > pkt_len) {
726 CAM_ERR(CAM_EEPROM,
727 "Offset is out of bound: off: %lld, %zu",
728 dev_config.offset, pkt_len);
729 return -EINVAL;
730 }
731
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530732 csl_packet = (struct cam_packet *)
733 (generic_pkt_addr + dev_config.offset);
734 switch (csl_packet->header.op_code & 0xFFFFFF) {
735 case CAM_EEPROM_PACKET_OPCODE_INIT:
736 if (e_ctrl->userspace_probe == false) {
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700737 rc = cam_eeprom_parse_read_memory_map(
Sureshnaidu Lavetid02f7ad2017-10-06 10:58:24 -0700738 e_ctrl->soc_info.dev->of_node, e_ctrl);
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700739 if (rc < 0) {
740 CAM_ERR(CAM_EEPROM, "Failed: rc : %d", rc);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530741 return rc;
742 }
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530743 rc = cam_eeprom_get_cal_data(e_ctrl, csl_packet);
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700744 kfree(e_ctrl->cal_data.mapdata);
745 kfree(e_ctrl->cal_data.map);
746 e_ctrl->cal_data.num_data = 0;
747 e_ctrl->cal_data.num_map = 0;
748 CAM_DBG(CAM_EEPROM,
749 "Returning the data using kernel probe");
Depeng Shao6b7576b2017-11-10 16:04:31 +0800750 break;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530751 }
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700752 rc = cam_eeprom_init_pkt_parser(e_ctrl, csl_packet);
753 if (rc) {
754 CAM_ERR(CAM_EEPROM,
755 "Failed in parsing the pkt");
756 return rc;
757 }
758
759 e_ctrl->cal_data.mapdata =
760 kzalloc(e_ctrl->cal_data.num_data, GFP_KERNEL);
761 if (!e_ctrl->cal_data.mapdata) {
762 rc = -ENOMEM;
763 CAM_ERR(CAM_EEPROM, "failed");
764 goto error;
765 }
766
767 rc = cam_eeprom_power_up(e_ctrl,
768 &soc_private->power_info);
769 if (rc) {
770 CAM_ERR(CAM_EEPROM, "failed rc %d", rc);
771 goto memdata_free;
772 }
773
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700774 e_ctrl->cam_eeprom_state = CAM_EEPROM_CONFIG;
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700775 rc = cam_eeprom_read_memory(e_ctrl, &e_ctrl->cal_data);
776 if (rc) {
777 CAM_ERR(CAM_EEPROM,
778 "read_eeprom_memory failed");
779 goto power_down;
780 }
781
782 rc = cam_eeprom_get_cal_data(e_ctrl, csl_packet);
783 rc = cam_eeprom_power_down(e_ctrl);
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700784 e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700785 kfree(e_ctrl->cal_data.mapdata);
786 kfree(e_ctrl->cal_data.map);
787 e_ctrl->cal_data.num_data = 0;
788 e_ctrl->cal_data.num_map = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530789 break;
790 default:
791 break;
792 }
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530793 return rc;
794power_down:
Sureshnaidu Laveti3dc87ea2017-10-15 20:53:42 -0700795 cam_eeprom_power_down(e_ctrl);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530796memdata_free:
797 kfree(e_ctrl->cal_data.mapdata);
798error:
Depeng Shao6b7576b2017-11-10 16:04:31 +0800799 kfree(power_info->power_setting);
800 kfree(power_info->power_down_setting);
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530801 kfree(e_ctrl->cal_data.map);
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700802 e_ctrl->cal_data.num_data = 0;
803 e_ctrl->cal_data.num_map = 0;
Depeng Shao6b7576b2017-11-10 16:04:31 +0800804 e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530805 return rc;
806}
807
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700808void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl)
809{
810 int rc;
Depeng Shao6b7576b2017-11-10 16:04:31 +0800811 struct cam_eeprom_soc_private *soc_private =
812 (struct cam_eeprom_soc_private *)e_ctrl->soc_info.soc_private;
813 struct cam_sensor_power_ctrl_t *power_info = &soc_private->power_info;
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700814
815 if (e_ctrl->cam_eeprom_state == CAM_EEPROM_INIT)
816 return;
817
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700818 if (e_ctrl->cam_eeprom_state == CAM_EEPROM_CONFIG) {
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700819 rc = cam_eeprom_power_down(e_ctrl);
820 if (rc < 0)
821 CAM_ERR(CAM_EEPROM, "EEPROM Power down failed");
822 e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
823 }
824
825 if (e_ctrl->cam_eeprom_state == CAM_EEPROM_ACQUIRE) {
826 rc = cam_destroy_device_hdl(e_ctrl->bridge_intf.device_hdl);
827 if (rc < 0)
828 CAM_ERR(CAM_EEPROM, "destroying the device hdl");
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700829
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700830 e_ctrl->bridge_intf.device_hdl = -1;
831 e_ctrl->bridge_intf.link_hdl = -1;
832 e_ctrl->bridge_intf.session_hdl = -1;
Depeng Shao6b7576b2017-11-10 16:04:31 +0800833
834 kfree(power_info->power_setting);
835 kfree(power_info->power_down_setting);
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700836 }
837
838 e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
839}
840
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530841/**
842 * cam_eeprom_driver_cmd - Handle eeprom cmds
843 * @e_ctrl: ctrl structure
844 * @arg: Camera control command argument
845 *
846 * Returns success or failure
847 */
848int32_t cam_eeprom_driver_cmd(struct cam_eeprom_ctrl_t *e_ctrl, void *arg)
849{
850 int rc = 0;
Soundrapandian Jeyaprakasha37cb232017-08-22 15:27:23 -0700851 struct cam_eeprom_query_cap_t eeprom_cap = {0};
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530852 struct cam_control *cmd = (struct cam_control *)arg;
853
854 if (!e_ctrl) {
855 CAM_ERR(CAM_EEPROM, "e_ctrl is NULL");
856 return -EINVAL;
857 }
858
859 mutex_lock(&(e_ctrl->eeprom_mutex));
860 switch (cmd->op_code) {
861 case CAM_QUERY_CAP:
Depeng Shao0fe56182017-09-25 11:13:48 +0800862 eeprom_cap.slot_info = e_ctrl->soc_info.index;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530863 if (e_ctrl->userspace_probe == false)
864 eeprom_cap.eeprom_kernel_probe = true;
865 else
866 eeprom_cap.eeprom_kernel_probe = false;
867
868 if (copy_to_user((void __user *) cmd->handle,
869 &eeprom_cap,
870 sizeof(struct cam_eeprom_query_cap_t))) {
871 CAM_ERR(CAM_EEPROM, "Failed Copy to User");
872 return -EFAULT;
873 goto release_mutex;
874 }
875 CAM_DBG(CAM_EEPROM, "eeprom_cap: ID: %d", eeprom_cap.slot_info);
876 break;
877 case CAM_ACQUIRE_DEV:
878 rc = cam_eeprom_get_dev_handle(e_ctrl, arg);
879 if (rc) {
880 CAM_ERR(CAM_EEPROM, "Failed to acquire dev");
881 goto release_mutex;
882 }
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700883 e_ctrl->cam_eeprom_state = CAM_EEPROM_ACQUIRE;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530884 break;
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700885 case CAM_RELEASE_DEV:
Karthik Anantha Ram4f5d66e2017-10-18 13:59:14 -0700886 if (e_ctrl->cam_eeprom_state != CAM_EEPROM_ACQUIRE) {
887 rc = -EINVAL;
888 CAM_WARN(CAM_EEPROM,
889 "Not in right state to release : %d",
890 e_ctrl->cam_eeprom_state);
891 goto release_mutex;
892 }
893
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700894 if (e_ctrl->bridge_intf.device_hdl == -1) {
895 CAM_ERR(CAM_EEPROM,
896 "Invalid Handles: link hdl: %d device hdl: %d",
897 e_ctrl->bridge_intf.device_hdl,
898 e_ctrl->bridge_intf.link_hdl);
899 rc = -EINVAL;
900 goto release_mutex;
901 }
902 rc = cam_destroy_device_hdl(e_ctrl->bridge_intf.device_hdl);
903 if (rc < 0)
904 CAM_ERR(CAM_EEPROM,
905 "failed in destroying the device hdl");
906 e_ctrl->bridge_intf.device_hdl = -1;
907 e_ctrl->bridge_intf.link_hdl = -1;
908 e_ctrl->bridge_intf.session_hdl = -1;
Soundrapandian Jeyaprakash8d16e272017-10-12 11:05:37 -0700909 e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
Sureshnaidu Laveti389cf0d2017-09-25 22:35:55 -0700910 break;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530911 case CAM_CONFIG_DEV:
912 rc = cam_eeprom_pkt_parse(e_ctrl, arg);
913 if (rc) {
914 CAM_ERR(CAM_EEPROM, "Failed in eeprom pkt Parsing");
915 goto release_mutex;
916 }
917 break;
918 default:
919 CAM_DBG(CAM_EEPROM, "invalid opcode");
920 break;
921 }
922
923release_mutex:
924 mutex_unlock(&(e_ctrl->eeprom_mutex));
925
926 return rc;
927}
928