blob: bcdaf6d9e2f55bad16f4946ef9bf1801812e233c [file] [log] [blame]
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001/* 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/kernel.h>
14#include "cam_sensor_util.h"
Vivek Veenam2ad8de12017-04-04 18:56:22 +053015#include <cam_mem_mgr.h>
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -070016
17#define CAM_SENSOR_PINCTRL_STATE_SLEEP "cam_suspend"
18#define CAM_SENSOR_PINCTRL_STATE_DEFAULT "cam_default"
19
20#define VALIDATE_VOLTAGE(min, max, config_val) ((config_val) && \
21 (config_val >= min) && (config_val <= max))
22
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -070023static struct i2c_settings_list*
24 cam_sensor_get_i2c_ptr(struct i2c_settings_array *i2c_reg_settings,
25 uint32_t size)
26{
27 struct i2c_settings_list *tmp;
28
29 tmp = (struct i2c_settings_list *)
30 kzalloc(sizeof(struct i2c_settings_list), GFP_KERNEL);
31
32 if (tmp != NULL)
33 list_add_tail(&(tmp->list),
34 &(i2c_reg_settings->list_head));
35 else
36 return NULL;
37
38 tmp->i2c_settings.reg_setting = (struct cam_sensor_i2c_reg_array *)
39 kzalloc(sizeof(struct cam_sensor_i2c_reg_array) *
40 size, GFP_KERNEL);
41 if (tmp->i2c_settings.reg_setting == NULL) {
42 list_del(&(tmp->list));
43 kfree(tmp);
44 return NULL;
45 }
46 tmp->i2c_settings.size = size;
47
48 return tmp;
49}
50
51int32_t delete_request(struct i2c_settings_array *i2c_array)
52{
53 struct i2c_settings_list *i2c_list = NULL, *i2c_next = NULL;
54 int32_t rc = 0;
55
56 if (i2c_array == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070057 CAM_ERR(CAM_SENSOR, "FATAL:: Invalid argument");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -070058 return -EINVAL;
59 }
60
61 list_for_each_entry_safe(i2c_list, i2c_next,
62 &(i2c_array->list_head), list) {
63 kfree(i2c_list->i2c_settings.reg_setting);
64 list_del(&(i2c_list->list));
65 kfree(i2c_list);
66 }
67 INIT_LIST_HEAD(&(i2c_array->list_head));
68 i2c_array->is_settings_valid = 0;
69
70 return rc;
71}
72
73int32_t cam_sensor_handle_delay(
74 uint32_t **cmd_buf,
75 uint16_t generic_op_code,
76 struct i2c_settings_array *i2c_reg_settings,
77 uint32_t offset, uint32_t *byte_cnt,
78 struct list_head *list_ptr)
79{
80 int32_t rc = 0;
81 struct cam_cmd_unconditional_wait *cmd_uncond_wait =
82 (struct cam_cmd_unconditional_wait *) *cmd_buf;
83 struct i2c_settings_list *i2c_list = NULL;
84
Viswanadha Raju Thotakura3bf35c22017-08-31 10:48:30 -070085 if (list_ptr == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -070086 CAM_ERR(CAM_SENSOR, "Invalid list ptr");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -070087 return -EINVAL;
88 }
89
90 if (offset > 0) {
91 i2c_list =
92 list_entry(list_ptr, struct i2c_settings_list, list);
93 if (generic_op_code ==
94 CAMERA_SENSOR_WAIT_OP_HW_UCND)
95 i2c_list->i2c_settings.
96 reg_setting[offset - 1].delay =
97 cmd_uncond_wait->delay;
98 else
99 i2c_list->i2c_settings.delay =
100 cmd_uncond_wait->delay;
101 (*cmd_buf) +=
102 sizeof(
103 struct cam_cmd_unconditional_wait) / sizeof(uint32_t);
104 (*byte_cnt) +=
105 sizeof(
106 struct cam_cmd_unconditional_wait);
107 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700108 CAM_ERR(CAM_SENSOR, "Delay Rxed Before any buffer: %d", offset);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700109 return -EINVAL;
110 }
111
112 return rc;
113}
114
115int32_t cam_sensor_handle_poll(
116 uint32_t **cmd_buf,
117 struct i2c_settings_array *i2c_reg_settings,
118 uint32_t *byte_cnt, int32_t *offset,
119 struct list_head **list_ptr)
120{
121 struct i2c_settings_list *i2c_list;
122 int32_t rc = 0;
123 struct cam_cmd_conditional_wait *cond_wait
124 = (struct cam_cmd_conditional_wait *) *cmd_buf;
125
126 i2c_list =
127 cam_sensor_get_i2c_ptr(i2c_reg_settings, 1);
128 if (!i2c_list || !i2c_list->i2c_settings.reg_setting) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700129 CAM_ERR(CAM_SENSOR, "Failed in allocating mem for list");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700130 return -ENOMEM;
131 }
132
133 i2c_list->op_code = CAM_SENSOR_I2C_POLL;
134 i2c_list->i2c_settings.data_type =
135 cond_wait->data_type;
136 i2c_list->i2c_settings.addr_type =
137 cond_wait->addr_type;
138 i2c_list->i2c_settings.reg_setting->reg_addr =
139 cond_wait->reg_addr;
140 i2c_list->i2c_settings.reg_setting->reg_data =
141 cond_wait->reg_data;
142 i2c_list->i2c_settings.reg_setting->delay =
143 cond_wait->timeout;
144
145 (*cmd_buf) += sizeof(struct cam_cmd_conditional_wait) /
146 sizeof(uint32_t);
147 (*byte_cnt) += sizeof(struct cam_cmd_conditional_wait);
148
149 (*offset) += 1;
150 *list_ptr = &(i2c_list->list);
151
152 return rc;
153}
154
155int32_t cam_sensor_handle_random_write(
156 struct cam_cmd_i2c_random_wr *cam_cmd_i2c_random_wr,
157 struct i2c_settings_array *i2c_reg_settings,
158 uint16_t *cmd_length_in_bytes, int32_t *offset,
159 struct list_head **list)
160{
161 struct i2c_settings_list *i2c_list;
162 int32_t rc = 0, cnt;
163
164 i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
165 cam_cmd_i2c_random_wr->header.count);
166 if (i2c_list == NULL ||
167 i2c_list->i2c_settings.reg_setting == NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700168 CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700169 return -ENOMEM;
170 }
171
172 *cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
173 sizeof(struct i2c_random_wr_payload) *
174 (cam_cmd_i2c_random_wr->header.count));
175 i2c_list->op_code = CAM_SENSOR_I2C_WRITE_RANDOM;
176 i2c_list->i2c_settings.addr_type =
177 cam_cmd_i2c_random_wr->header.addr_type;
178 i2c_list->i2c_settings.data_type =
179 cam_cmd_i2c_random_wr->header.data_type;
180
181 for (cnt = 0; cnt < (cam_cmd_i2c_random_wr->header.count);
182 cnt++) {
183 i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
184 cam_cmd_i2c_random_wr->
185 random_wr_payload[cnt].reg_addr;
186 i2c_list->i2c_settings.
187 reg_setting[cnt].reg_data =
188 cam_cmd_i2c_random_wr->
189 random_wr_payload[cnt].reg_data;
190 i2c_list->i2c_settings.
191 reg_setting[cnt].data_mask = 0;
192 }
193 (*offset) += cnt;
194 *list = &(i2c_list->list);
195
196 return rc;
197}
198
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700199static int32_t cam_sensor_handle_continuous_write(
200 struct cam_cmd_i2c_continuous_wr *cam_cmd_i2c_continuous_wr,
201 struct i2c_settings_array *i2c_reg_settings,
202 uint16_t *cmd_length_in_bytes, int32_t *offset,
203 struct list_head **list)
204{
205 struct i2c_settings_list *i2c_list;
206 int32_t rc = 0, cnt;
207
208 i2c_list = cam_sensor_get_i2c_ptr(i2c_reg_settings,
209 cam_cmd_i2c_continuous_wr->header.count);
210 if (i2c_list == NULL ||
211 i2c_list->i2c_settings.reg_setting == NULL) {
212 CAM_ERR(CAM_SENSOR, "Failed in allocating i2c_list");
213 return -ENOMEM;
214 }
215
216 *cmd_length_in_bytes = (sizeof(struct i2c_rdwr_header) +
217 sizeof(cam_cmd_i2c_continuous_wr->reg_addr) +
218 sizeof(struct cam_cmd_read) *
219 (cam_cmd_i2c_continuous_wr->header.count));
Karthik Anantha Ram3d846ad2017-09-26 10:21:33 -0700220 if (cam_cmd_i2c_continuous_wr->header.op_code ==
221 CAMERA_SENSOR_I2C_OP_CONT_WR_BRST)
222 i2c_list->op_code = CAM_SENSOR_I2C_WRITE_BURST;
223 else if (cam_cmd_i2c_continuous_wr->header.op_code ==
224 CAMERA_SENSOR_I2C_OP_CONT_WR_SEQN)
225 i2c_list->op_code = CAM_SENSOR_I2C_WRITE_SEQ;
226 else
227 return -EINVAL;
228
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700229 i2c_list->i2c_settings.addr_type =
230 cam_cmd_i2c_continuous_wr->header.addr_type;
Karthik Anantha Ram3d846ad2017-09-26 10:21:33 -0700231 i2c_list->i2c_settings.data_type =
232 cam_cmd_i2c_continuous_wr->header.data_type;
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700233
234 for (cnt = 0; cnt < (cam_cmd_i2c_continuous_wr->header.count);
235 cnt++) {
236 i2c_list->i2c_settings.reg_setting[cnt].reg_addr =
237 cam_cmd_i2c_continuous_wr->
238 reg_addr;
239 i2c_list->i2c_settings.
240 reg_setting[cnt].reg_data =
241 cam_cmd_i2c_continuous_wr->
242 data_read[cnt].reg_data;
243 i2c_list->i2c_settings.
244 reg_setting[cnt].data_mask = 0;
245 }
246 (*offset) += cnt;
247 *list = &(i2c_list->list);
248
249 return rc;
250}
251
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700252/**
253 * Name : cam_sensor_i2c_pkt_parser
254 * Description : Parse CSL CCI packet and apply register settings
255 * Parameters : s_ctrl input/output sub_device
256 * arg input cam_control
257 * Description :
258 * Handle multiple I2C RD/WR and WAIT cmd formats in one command
259 * buffer, for example, a command buffer of m x RND_WR + 1 x HW_
260 * WAIT + n x RND_WR with num_cmd_buf = 1. Do not exepect RD/WR
261 * with different cmd_type and op_code in one command buffer.
262 */
263int cam_sensor_i2c_pkt_parser(struct i2c_settings_array *i2c_reg_settings,
264 struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers)
265{
266 int16_t rc = 0, i = 0;
267 size_t len_of_buff = 0;
268 uint64_t generic_ptr;
269
270 for (i = 0; i < num_cmd_buffers; i++) {
271 uint32_t *cmd_buf = NULL;
272 struct common_header *cmm_hdr;
273 uint16_t generic_op_code;
274 uint32_t byte_cnt = 0;
275 uint32_t j = 0;
276 struct list_head *list = NULL;
277
278 /*
279 * It is not expected the same settings to
280 * be spread across multiple cmd buffers
281 */
282
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700283 CAM_DBG(CAM_SENSOR, "Total cmd Buf in Bytes: %d",
284 cmd_desc[i].length);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700285
286 if (!cmd_desc[i].length)
287 continue;
288
289 rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
290 (uint64_t *)&generic_ptr, &len_of_buff);
291 cmd_buf = (uint32_t *)generic_ptr;
292 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700293 CAM_ERR(CAM_SENSOR,
294 "cmd hdl failed:%d, Err: %d, Buffer_len: %ld",
295 cmd_desc[i].mem_handle, rc, len_of_buff);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700296 return rc;
297 }
298 cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
299
300 while (byte_cnt < cmd_desc[i].length) {
301 cmm_hdr = (struct common_header *)cmd_buf;
302 generic_op_code = cmm_hdr->third_byte;
303 switch (cmm_hdr->cmd_type) {
304 case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: {
305 uint16_t cmd_length_in_bytes = 0;
306 struct cam_cmd_i2c_random_wr
307 *cam_cmd_i2c_random_wr =
308 (struct cam_cmd_i2c_random_wr *)cmd_buf;
309
310 rc = cam_sensor_handle_random_write(
311 cam_cmd_i2c_random_wr,
312 i2c_reg_settings,
313 &cmd_length_in_bytes, &j, &list);
314 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700315 CAM_ERR(CAM_SENSOR,
Karthik Anantha Ram0fb02a32017-08-23 11:52:50 -0700316 "Failed in random write %d", rc);
317 return rc;
318 }
319
320 cmd_buf += cmd_length_in_bytes /
321 sizeof(uint32_t);
322 byte_cnt += cmd_length_in_bytes;
323 break;
324 }
325 case CAMERA_SENSOR_CMD_TYPE_I2C_CONT_WR: {
326 uint16_t cmd_length_in_bytes = 0;
327 struct cam_cmd_i2c_continuous_wr
328 *cam_cmd_i2c_continuous_wr =
329 (struct cam_cmd_i2c_continuous_wr *)
330 cmd_buf;
331
332 rc = cam_sensor_handle_continuous_write(
333 cam_cmd_i2c_continuous_wr,
334 i2c_reg_settings,
335 &cmd_length_in_bytes, &j, &list);
336 if (rc < 0) {
337 CAM_ERR(CAM_SENSOR,
338 "Failed in continuous write %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700339 return rc;
340 }
341
342 cmd_buf += cmd_length_in_bytes /
343 sizeof(uint32_t);
344 byte_cnt += cmd_length_in_bytes;
345 break;
346 }
347 case CAMERA_SENSOR_CMD_TYPE_WAIT: {
348 if (generic_op_code ==
349 CAMERA_SENSOR_WAIT_OP_HW_UCND ||
350 generic_op_code ==
351 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
352
353 rc = cam_sensor_handle_delay(
354 &cmd_buf, generic_op_code,
355 i2c_reg_settings, j, &byte_cnt,
356 list);
357 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700358 CAM_ERR(CAM_SENSOR,
359 "delay hdl failed: %d",
360 rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700361 return rc;
362 }
363
364 } else if (generic_op_code ==
365 CAMERA_SENSOR_WAIT_OP_COND) {
366 rc = cam_sensor_handle_poll(
367 &cmd_buf, i2c_reg_settings,
368 &byte_cnt, &j, &list);
369 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700370 CAM_ERR(CAM_SENSOR,
371 "Random read fail: %d",
372 rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700373 return rc;
374 }
375 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700376 CAM_ERR(CAM_SENSOR,
377 "Wrong Wait Command: %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700378 generic_op_code);
379 return -EINVAL;
380 }
381 break;
382 }
383 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700384 CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
385 cmm_hdr->cmd_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700386 return -EINVAL;
387 }
388 }
389 i2c_reg_settings->is_settings_valid = 1;
390 }
391
392 return rc;
393}
394
Alok Pandey01b1b352017-06-25 20:38:54 +0530395int32_t msm_camera_fill_vreg_params(
396 struct cam_hw_soc_info *soc_info,
397 struct cam_sensor_power_setting *power_setting,
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700398 uint16_t power_setting_size)
399{
400 int32_t rc = 0, j = 0, i = 0;
Jigarkumar Zalac6c090b2017-09-21 15:04:56 -0700401 int num_vreg;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700402
403 /* Validate input parameters */
Alok Pandey01b1b352017-06-25 20:38:54 +0530404 if (!soc_info || !power_setting) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700405 CAM_ERR(CAM_SENSOR, "failed: soc_info %pK power_setting %pK",
406 soc_info, power_setting);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700407 return -EINVAL;
408 }
409
Alok Pandey01b1b352017-06-25 20:38:54 +0530410 num_vreg = soc_info->num_rgltr;
411
Jigarkumar Zalac6c090b2017-09-21 15:04:56 -0700412 if ((num_vreg <= 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700413 CAM_ERR(CAM_SENSOR, "failed: num_vreg %d", num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700414 return -EINVAL;
415 }
416
417 for (i = 0; i < power_setting_size; i++) {
Viswanadha Raju Thotakura2c5c1a12017-08-23 15:56:22 -0700418
419 if (power_setting[i].seq_type < SENSOR_MCLK ||
420 power_setting[i].seq_type >= SENSOR_SEQ_TYPE_MAX) {
421 CAM_ERR(CAM_SENSOR, "failed: Invalid Seq type\n",
422 power_setting[i].seq_type);
423 return -EINVAL;
424 }
425
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700426 switch (power_setting[i].seq_type) {
427 case SENSOR_VDIG:
428 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530429 if (!strcmp(soc_info->rgltr_name[j],
430 "cam_vdig")) {
431
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700432 CAM_DBG(CAM_SENSOR,
433 "i: %d j: %d cam_vdig", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700434 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530435
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700436 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530437 soc_info->rgltr_min_volt[j],
438 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700439 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530440 soc_info->rgltr_min_volt[j] =
441 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700442 power_setting[i].config_val;
443 }
444 break;
445 }
446 }
447 if (j == num_vreg)
448 power_setting[i].seq_val = INVALID_VREG;
449 break;
450
451 case SENSOR_VIO:
452 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530453
454 if (!strcmp(soc_info->rgltr_name[j],
455 "cam_vio")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700456 CAM_DBG(CAM_SENSOR,
457 "i: %d j: %d cam_vio", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700458 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530459
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700460 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530461 soc_info->rgltr_min_volt[j],
462 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700463 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530464 soc_info->rgltr_min_volt[j] =
465 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700466 power_setting[i].config_val;
467 }
468 break;
469 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530470
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700471 }
472 if (j == num_vreg)
473 power_setting[i].seq_val = INVALID_VREG;
474 break;
475
476 case SENSOR_VANA:
477 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530478
479 if (!strcmp(soc_info->rgltr_name[j],
480 "cam_vana")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700481 CAM_DBG(CAM_SENSOR,
482 "i: %d j: %d cam_vana", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700483 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530484
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700485 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530486 soc_info->rgltr_min_volt[j],
487 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700488 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530489 soc_info->rgltr_min_volt[j] =
490 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700491 power_setting[i].config_val;
492 }
493 break;
494 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530495
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700496 }
497 if (j == num_vreg)
498 power_setting[i].seq_val = INVALID_VREG;
499 break;
500
501 case SENSOR_VAF:
502 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530503
504 if (!strcmp(soc_info->rgltr_name[j],
505 "cam_vaf")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700506 CAM_DBG(CAM_SENSOR,
507 "i: %d j: %d cam_vaf", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700508 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530509
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700510 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530511 soc_info->rgltr_min_volt[j],
512 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700513 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530514 soc_info->rgltr_min_volt[j] =
515 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700516 power_setting[i].config_val;
517 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530518
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700519 break;
520 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530521
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700522 }
523 if (j == num_vreg)
524 power_setting[i].seq_val = INVALID_VREG;
525 break;
526
527 case SENSOR_CUSTOM_REG1:
528 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530529
530 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700531 "cam_v_custom1")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700532 CAM_DBG(CAM_SENSOR,
533 "i:%d j:%d cam_vcustom1", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700534 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530535
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700536 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530537 soc_info->rgltr_min_volt[j],
538 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700539 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530540 soc_info->rgltr_min_volt[j] =
541 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700542 power_setting[i].config_val;
543 }
544 break;
545 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530546
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700547 }
548 if (j == num_vreg)
549 power_setting[i].seq_val = INVALID_VREG;
550 break;
551 case SENSOR_CUSTOM_REG2:
552 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530553
554 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700555 "cam_v_custom2")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700556 CAM_DBG(CAM_SENSOR,
557 "i:%d j:%d cam_vcustom2", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700558 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530559
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700560 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530561 soc_info->rgltr_min_volt[j],
562 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700563 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530564 soc_info->rgltr_min_volt[j] =
565 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700566 power_setting[i].config_val;
567 }
568 break;
569 }
570 }
571 if (j == num_vreg)
572 power_setting[i].seq_val = INVALID_VREG;
573 break;
Viswanadha Raju Thotakura2c5c1a12017-08-23 15:56:22 -0700574 default:
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700575 break;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700576 }
577 }
578
579 return rc;
580}
581
Alok Pandey01b1b352017-06-25 20:38:54 +0530582int cam_sensor_util_request_gpio_table(
583 struct cam_hw_soc_info *soc_info, int gpio_en)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700584{
Alok Pandey01b1b352017-06-25 20:38:54 +0530585 int rc = 0, i = 0;
586 uint8_t size = 0;
587 struct cam_soc_gpio_data *gpio_conf =
588 soc_info->gpio_data;
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700589 struct gpio *gpio_tbl = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700590
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700591 if (!gpio_conf) {
592 CAM_INFO(CAM_SENSOR, "No GPIO data");
593 return 0;
594 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700595
Alok Pandey01b1b352017-06-25 20:38:54 +0530596 if (gpio_conf->cam_gpio_common_tbl_size <= 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700597 CAM_INFO(CAM_SENSOR, "No GPIO entry");
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700598 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700599 }
600
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700601 gpio_tbl = gpio_conf->cam_gpio_req_tbl;
602 size = gpio_conf->cam_gpio_req_tbl_size;
603
Alok Pandey01b1b352017-06-25 20:38:54 +0530604 if (!gpio_tbl || !size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700605 CAM_ERR(CAM_SENSOR, "invalid gpio_tbl %pK / size %d",
606 gpio_tbl, size);
Alok Pandey01b1b352017-06-25 20:38:54 +0530607 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700608 }
609
Alok Pandey01b1b352017-06-25 20:38:54 +0530610 for (i = 0; i < size; i++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700611 CAM_DBG(CAM_SENSOR, "i: %d, gpio %d dir %ld", i,
612 gpio_tbl[i].gpio, gpio_tbl[i].flags);
Alok Pandey01b1b352017-06-25 20:38:54 +0530613 }
614
615 if (gpio_en) {
616 for (i = 0; i < size; i++) {
617 rc = gpio_request_one(gpio_tbl[i].gpio,
618 gpio_tbl[i].flags, gpio_tbl[i].label);
619 if (rc) {
620 /*
621 * After GPIO request fails, contine to
622 * apply new gpios, outout a error message
623 * for driver bringup debug
624 */
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700625 CAM_ERR(CAM_SENSOR, "gpio %d:%s request fails",
Alok Pandey01b1b352017-06-25 20:38:54 +0530626 gpio_tbl[i].gpio, gpio_tbl[i].label);
627 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700628 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530629 } else {
630 gpio_free_array(gpio_tbl, size);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700631 }
632
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700633 return rc;
634}
635
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530636int32_t cam_sensor_update_power_settings(void *cmd_buf,
637 int cmd_length, struct cam_sensor_power_ctrl_t *power_info)
638{
639 int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
640 int32_t i = 0, pwr_up = 0, pwr_down = 0;
641 void *ptr = cmd_buf, *scr;
642 struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
643 struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
644
645 if (!pwr_cmd || !cmd_length) {
646 CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d",
647 pwr_cmd, cmd_length);
648 return -EINVAL;
649 }
650
651 power_info->power_setting_size = 0;
652 power_info->power_setting =
653 (struct cam_sensor_power_setting *)
654 kzalloc(sizeof(struct cam_sensor_power_setting) *
655 MAX_POWER_CONFIG, GFP_KERNEL);
656 if (!power_info->power_setting)
657 return -ENOMEM;
658
Soundrapandian Jeyaprakash687b32e2017-07-28 14:38:56 -0700659 power_info->power_down_setting_size = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530660 power_info->power_down_setting =
661 (struct cam_sensor_power_setting *)
662 kzalloc(sizeof(struct cam_sensor_power_setting) *
663 MAX_POWER_CONFIG, GFP_KERNEL);
664 if (!power_info->power_down_setting) {
665 rc = -ENOMEM;
666 goto free_power_settings;
667 }
668
669 while (tot_size < cmd_length) {
670 if (cmm_hdr->cmd_type ==
671 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
672 struct cam_cmd_power *pwr_cmd =
673 (struct cam_cmd_power *)ptr;
674
675 power_info->
676 power_setting_size +=
677 pwr_cmd->count;
678 scr = ptr + sizeof(struct cam_cmd_power);
679 tot_size = tot_size + sizeof(struct cam_cmd_power);
680
681 if (pwr_cmd->count == 0)
682 CAM_DBG(CAM_SENSOR, "Un expected Command");
683
684 for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
685 power_info->
686 power_setting[pwr_up].seq_type =
687 pwr_cmd->power_settings[i].
688 power_seq_type;
689 power_info->
690 power_setting[pwr_up].config_val =
691 pwr_cmd->power_settings[i].
692 config_val_low;
693 power_info->power_setting[pwr_up].delay = 0;
694 if (i) {
695 scr = scr +
696 sizeof(
697 struct cam_power_settings);
698 tot_size = tot_size +
699 sizeof(
700 struct cam_power_settings);
701 }
702 if (tot_size > cmd_length) {
703 CAM_ERR(CAM_SENSOR,
704 "Error: Cmd Buffer is wrong");
705 rc = -EINVAL;
706 goto free_power_down_settings;
707 }
708 CAM_DBG(CAM_SENSOR,
709 "Seq Type[%d]: %d Config_val: %ld",
710 pwr_up,
711 power_info->
712 power_setting[pwr_up].seq_type,
713 power_info->
714 power_setting[pwr_up].
715 config_val);
716 }
717 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
718 ptr = (void *) scr;
719 cmm_hdr = (struct common_header *)ptr;
720 } else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
721 struct cam_cmd_unconditional_wait *wait_cmd =
722 (struct cam_cmd_unconditional_wait *)ptr;
723 if (wait_cmd->op_code ==
724 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
725 if (last_cmd_type ==
726 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
727 if (pwr_up > 0)
728 power_info->
729 power_setting
730 [pwr_up - 1].delay +=
731 wait_cmd->delay;
732 else
733 CAM_ERR(CAM_SENSOR,
734 "Delay is expected only after valid power up setting");
735 } else if (last_cmd_type ==
736 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
737 if (pwr_down > 0)
738 power_info->
739 power_down_setting
740 [pwr_down - 1].delay +=
741 wait_cmd->delay;
742 else
743 CAM_ERR(CAM_SENSOR,
744 "Delay is expected only after valid power up setting");
745 }
746 } else
747 CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
748 wait_cmd->op_code);
749 tot_size = tot_size +
750 sizeof(struct cam_cmd_unconditional_wait);
751 if (tot_size > cmd_length) {
752 CAM_ERR(CAM_SENSOR, "Command Buffer is wrong");
753 return -EINVAL;
754 }
755 scr = (void *) (wait_cmd);
756 ptr = (void *)
757 (scr +
758 sizeof(struct cam_cmd_unconditional_wait));
759 CAM_DBG(CAM_SENSOR, "ptr: %pK sizeof: %d Next: %pK",
760 scr, (int32_t)sizeof(
761 struct cam_cmd_unconditional_wait), ptr);
762
763 cmm_hdr = (struct common_header *)ptr;
764 } else if (cmm_hdr->cmd_type ==
765 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
766 struct cam_cmd_power *pwr_cmd =
767 (struct cam_cmd_power *)ptr;
768
769 scr = ptr + sizeof(struct cam_cmd_power);
770 tot_size = tot_size + sizeof(struct cam_cmd_power);
771 power_info->power_down_setting_size += pwr_cmd->count;
772
773 if (pwr_cmd->count == 0)
774 CAM_ERR(CAM_SENSOR, "Invalid Command");
775
776 for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
777 power_info->
778 power_down_setting[pwr_down].
779 seq_type =
780 pwr_cmd->power_settings[i].
781 power_seq_type;
782 power_info->
783 power_down_setting[pwr_down].
784 config_val =
785 pwr_cmd->power_settings[i].
786 config_val_low;
787 power_info->
788 power_down_setting[pwr_down].delay = 0;
789 if (i) {
790 scr = scr +
791 sizeof(
792 struct cam_power_settings);
793 tot_size =
794 tot_size +
795 sizeof(
796 struct cam_power_settings);
797 }
798 if (tot_size > cmd_length) {
799 CAM_ERR(CAM_SENSOR,
800 "Command Buffer is wrong");
801 rc = -EINVAL;
802 goto free_power_down_settings;
803 }
804 CAM_DBG(CAM_SENSOR,
805 "Seq Type[%d]: %d Config_val: %ld",
806 pwr_down,
807 power_info->
808 power_down_setting[pwr_down].
809 seq_type,
810 power_info->
811 power_down_setting[pwr_down].
812 config_val);
813 }
814 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
815 ptr = (void *) scr;
816 cmm_hdr = (struct common_header *)ptr;
817 } else {
818 CAM_ERR(CAM_SENSOR,
819 "Error: Un expected Header Type: %d",
820 cmm_hdr->cmd_type);
821 }
822 }
823
824 return rc;
825free_power_down_settings:
826 kfree(power_info->power_down_setting);
827free_power_settings:
828 kfree(power_info->power_setting);
829 return rc;
830}
831
832int cam_get_dt_power_setting_data(struct device_node *of_node,
833 struct cam_hw_soc_info *soc_info,
834 struct cam_sensor_power_ctrl_t *power_info)
835{
836 int rc = 0, i;
837 int count = 0;
838 const char *seq_name = NULL;
839 uint32_t *array = NULL;
840 struct cam_sensor_power_setting *ps;
841 int c, end;
842
843 if (!power_info)
844 return -EINVAL;
845
846 count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
847 power_info->power_setting_size = count;
848
849 CAM_DBG(CAM_SENSOR, "qcom,cam-power-seq-type count %d", count);
850
851 if (count <= 0)
852 return 0;
853
854 ps = kcalloc(count, sizeof(*ps), GFP_KERNEL);
855 if (!ps)
856 return -ENOMEM;
857 power_info->power_setting = ps;
858
859 for (i = 0; i < count; i++) {
860 rc = of_property_read_string_index(of_node,
861 "qcom,cam-power-seq-type", i, &seq_name);
862 if (rc < 0) {
863 CAM_ERR(CAM_SENSOR, "failed");
864 goto ERROR1;
865 }
866 CAM_DBG(CAM_SENSOR, "seq_name[%d] = %s", i, seq_name);
867 if (!strcmp(seq_name, "cam_vio")) {
868 ps[i].seq_type = SENSOR_VIO;
869 } else if (!strcmp(seq_name, "cam_vana")) {
870 ps[i].seq_type = SENSOR_VANA;
871 } else if (!strcmp(seq_name, "cam_clk")) {
872 ps[i].seq_type = SENSOR_MCLK;
873 } else {
874 CAM_ERR(CAM_SENSOR, "unrecognized seq-type %s",
875 seq_name);
876 rc = -EILSEQ;
877 goto ERROR1;
878 }
879 CAM_DBG(CAM_SENSOR, "seq_type[%d] %d", i, ps[i].seq_type);
880 }
881
882 array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
883 if (!array) {
884 rc = -ENOMEM;
885 goto ERROR1;
886 }
887
888 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val",
889 array, count);
890 if (rc < 0) {
891 CAM_ERR(CAM_SENSOR, "failed ");
892 goto ERROR2;
893 }
894
895 for (i = 0; i < count; i++) {
896 ps[i].config_val = array[i];
897 CAM_DBG(CAM_SENSOR, "power_setting[%d].config_val = %ld", i,
898 ps[i].config_val);
899 }
900
901 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay",
902 array, count);
903 if (rc < 0) {
904 CAM_ERR(CAM_SENSOR, "failed");
905 goto ERROR2;
906 }
907 for (i = 0; i < count; i++) {
908 ps[i].delay = array[i];
909 CAM_DBG(CAM_SENSOR, "power_setting[%d].delay = %d", i,
910 ps[i].delay);
911 }
912 kfree(array);
913
914 power_info->power_down_setting =
915 kzalloc(sizeof(*ps) * count, GFP_KERNEL);
916
917 if (!power_info->power_down_setting) {
918 CAM_ERR(CAM_SENSOR, "failed");
919 rc = -ENOMEM;
920 goto ERROR1;
921 }
922
923 power_info->power_down_setting_size = count;
924
925 end = count - 1;
926
927 for (c = 0; c < count; c++) {
928 power_info->power_down_setting[c] = ps[end];
929 end--;
930 }
931 return rc;
932ERROR2:
933 kfree(array);
934ERROR1:
935 kfree(ps);
936 return rc;
937}
Alok Pandey01b1b352017-06-25 20:38:54 +0530938
939int cam_sensor_util_init_gpio_pin_tbl(
940 struct cam_hw_soc_info *soc_info,
941 struct msm_camera_gpio_num_info **pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700942{
943 int rc = 0, val = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530944 uint32_t gpio_array_size;
Alok Pandey01b1b352017-06-25 20:38:54 +0530945 struct device_node *of_node = NULL;
946 struct cam_soc_gpio_data *gconf = NULL;
947 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700948
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700949 if (!soc_info->dev) {
950 CAM_ERR(CAM_SENSOR, "device node NULL");
951 return -EINVAL;
952 }
953
954 of_node = soc_info->dev->of_node;
Alok Pandey01b1b352017-06-25 20:38:54 +0530955
956 gconf = soc_info->gpio_data;
957 if (!gconf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700958 CAM_ERR(CAM_SENSOR, "No gpio_common_table is found");
Alok Pandey01b1b352017-06-25 20:38:54 +0530959 return -EINVAL;
960 }
961
962 if (!gconf->cam_gpio_common_tbl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700963 CAM_ERR(CAM_SENSOR, "gpio_common_table is not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +0530964 return -EINVAL;
965 }
966
967 gpio_array_size = gconf->cam_gpio_common_tbl_size;
968
969 if (!gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700970 CAM_ERR(CAM_SENSOR, "invalid size of gpio table");
Alok Pandey01b1b352017-06-25 20:38:54 +0530971 return -EINVAL;
972 }
973
974 *pgpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700975 GFP_KERNEL);
Alok Pandey01b1b352017-06-25 20:38:54 +0530976 if (!*pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700977 return -ENOMEM;
Alok Pandey01b1b352017-06-25 20:38:54 +0530978 gpio_num_info = *pgpio_num_info;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700979
Alok Pandey01b1b352017-06-25 20:38:54 +0530980 rc = of_property_read_u32(of_node, "gpio-vana", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700981 if (rc != -EINVAL) {
982 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700983 CAM_ERR(CAM_SENSOR, "read gpio-vana failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700984 goto free_gpio_info;
985 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700986 CAM_ERR(CAM_SENSOR, "gpio-vana invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700987 rc = -EINVAL;
988 goto free_gpio_info;
989 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530990 gpio_num_info->gpio_num[SENSOR_VANA] =
991 gconf->cam_gpio_common_tbl[val].gpio;
992 gpio_num_info->valid[SENSOR_VANA] = 1;
993
Jigarkumar Zala22223f92017-07-28 12:46:27 -0700994 CAM_DBG(CAM_SENSOR, "gpio-vana %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530995 gpio_num_info->gpio_num[SENSOR_VANA]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700996 }
997
Alok Pandey01b1b352017-06-25 20:38:54 +0530998 rc = of_property_read_u32(of_node, "gpio-vio", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700999 if (rc != -EINVAL) {
1000 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001001 CAM_ERR(CAM_SENSOR, "read gpio-vio failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001002 goto free_gpio_info;
1003 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001004 CAM_ERR(CAM_SENSOR, "gpio-vio invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001005 goto free_gpio_info;
1006 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301007 gpio_num_info->gpio_num[SENSOR_VIO] =
1008 gconf->cam_gpio_common_tbl[val].gpio;
1009 gpio_num_info->valid[SENSOR_VIO] = 1;
1010
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001011 CAM_DBG(CAM_SENSOR, "gpio-vio %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301012 gpio_num_info->gpio_num[SENSOR_VIO]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001013 }
1014
Alok Pandey01b1b352017-06-25 20:38:54 +05301015 rc = of_property_read_u32(of_node, "gpio-vaf", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001016 if (rc != -EINVAL) {
1017 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001018 CAM_ERR(CAM_SENSOR, "read gpio-vaf failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001019 goto free_gpio_info;
1020 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001021 CAM_ERR(CAM_SENSOR, "gpio-vaf invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001022 rc = -EINVAL;
1023 goto free_gpio_info;
1024 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301025 gpio_num_info->gpio_num[SENSOR_VAF] =
1026 gconf->cam_gpio_common_tbl[val].gpio;
1027 gpio_num_info->valid[SENSOR_VAF] = 1;
1028
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001029 CAM_DBG(CAM_SENSOR, "gpio-vaf %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301030 gpio_num_info->gpio_num[SENSOR_VAF]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001031 }
1032
Alok Pandey01b1b352017-06-25 20:38:54 +05301033 rc = of_property_read_u32(of_node, "gpio-vdig", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001034 if (rc != -EINVAL) {
1035 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001036 CAM_ERR(CAM_SENSOR, "read gpio-vdig failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001037 goto free_gpio_info;
1038 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001039 CAM_ERR(CAM_SENSOR, "gpio-vdig invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001040 rc = -EINVAL;
1041 goto free_gpio_info;
1042 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301043 gpio_num_info->gpio_num[SENSOR_VDIG] =
1044 gconf->cam_gpio_common_tbl[val].gpio;
1045 gpio_num_info->valid[SENSOR_VDIG] = 1;
1046
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001047 CAM_DBG(CAM_SENSOR, "gpio-vdig %d",
1048 gpio_num_info->gpio_num[SENSOR_VDIG]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001049 }
1050
Alok Pandey01b1b352017-06-25 20:38:54 +05301051 rc = of_property_read_u32(of_node, "gpio-reset", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001052 if (rc != -EINVAL) {
1053 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001054 CAM_ERR(CAM_SENSOR, "read gpio-reset failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001055 goto free_gpio_info;
1056 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001057 CAM_ERR(CAM_SENSOR, "gpio-reset invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001058 rc = -EINVAL;
1059 goto free_gpio_info;
1060 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301061 gpio_num_info->gpio_num[SENSOR_RESET] =
1062 gconf->cam_gpio_common_tbl[val].gpio;
1063 gpio_num_info->valid[SENSOR_RESET] = 1;
1064
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001065 CAM_DBG(CAM_SENSOR, "gpio-reset %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301066 gpio_num_info->gpio_num[SENSOR_RESET]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001067 }
1068
Alok Pandey01b1b352017-06-25 20:38:54 +05301069 rc = of_property_read_u32(of_node, "gpio-standby", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001070 if (rc != -EINVAL) {
1071 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001072 CAM_ERR(CAM_SENSOR,
1073 "read gpio-standby failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001074 goto free_gpio_info;
1075 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001076 CAM_ERR(CAM_SENSOR, "gpio-standby invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001077 rc = -EINVAL;
1078 goto free_gpio_info;
1079 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301080 gpio_num_info->gpio_num[SENSOR_STANDBY] =
1081 gconf->cam_gpio_common_tbl[val].gpio;
1082 gpio_num_info->valid[SENSOR_STANDBY] = 1;
1083
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001084 CAM_DBG(CAM_SENSOR, "gpio-standby %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301085 gpio_num_info->gpio_num[SENSOR_STANDBY]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001086 }
1087
Alok Pandey01b1b352017-06-25 20:38:54 +05301088 rc = of_property_read_u32(of_node, "gpio-af-pwdm", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001089 if (rc != -EINVAL) {
1090 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001091 CAM_ERR(CAM_SENSOR,
1092 "read gpio-af-pwdm failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001093 goto free_gpio_info;
1094 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001095 CAM_ERR(CAM_SENSOR, "gpio-af-pwdm invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001096 rc = -EINVAL;
1097 goto free_gpio_info;
1098 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301099 gpio_num_info->gpio_num[SENSOR_VAF_PWDM] =
1100 gconf->cam_gpio_common_tbl[val].gpio;
1101 gpio_num_info->valid[SENSOR_VAF_PWDM] = 1;
1102
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001103 CAM_DBG(CAM_SENSOR, "gpio-af-pwdm %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301104 gpio_num_info->gpio_num[SENSOR_VAF_PWDM]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001105 }
1106
Alok Pandey01b1b352017-06-25 20:38:54 +05301107 rc = of_property_read_u32(of_node, "gpio-custom1", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001108 if (rc != -EINVAL) {
1109 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001110 CAM_ERR(CAM_SENSOR,
1111 "read gpio-custom1 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001112 goto free_gpio_info;
1113 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001114 CAM_ERR(CAM_SENSOR, "gpio-custom1 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001115 rc = -EINVAL;
1116 goto free_gpio_info;
1117 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301118 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1] =
1119 gconf->cam_gpio_common_tbl[val].gpio;
1120 gpio_num_info->valid[SENSOR_CUSTOM_GPIO1] = 1;
1121
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001122 CAM_DBG(CAM_SENSOR, "gpio-custom1 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301123 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001124 }
1125
Alok Pandey01b1b352017-06-25 20:38:54 +05301126 rc = of_property_read_u32(of_node, "gpio-custom2", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001127 if (rc != -EINVAL) {
1128 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001129 CAM_ERR(CAM_SENSOR,
1130 "read gpio-custom2 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001131 goto free_gpio_info;
1132 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001133 CAM_ERR(CAM_SENSOR, "gpio-custom2 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001134 rc = -EINVAL;
1135 goto free_gpio_info;
1136 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301137 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2] =
1138 gconf->cam_gpio_common_tbl[val].gpio;
1139 gpio_num_info->valid[SENSOR_CUSTOM_GPIO2] = 1;
1140
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001141 CAM_DBG(CAM_SENSOR, "gpio-custom2 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301142 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001143 } else {
1144 rc = 0;
1145 }
1146
1147 return rc;
1148
1149free_gpio_info:
Alok Pandey01b1b352017-06-25 20:38:54 +05301150 kfree(gpio_num_info);
1151 gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001152 return rc;
1153}
1154
1155int msm_camera_pinctrl_init(
1156 struct msm_pinctrl_info *sensor_pctrl, struct device *dev) {
1157
1158 sensor_pctrl->pinctrl = devm_pinctrl_get(dev);
1159 if (IS_ERR_OR_NULL(sensor_pctrl->pinctrl)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001160 CAM_ERR(CAM_SENSOR, "Getting pinctrl handle failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001161 return -EINVAL;
1162 }
1163 sensor_pctrl->gpio_state_active =
1164 pinctrl_lookup_state(sensor_pctrl->pinctrl,
1165 CAM_SENSOR_PINCTRL_STATE_DEFAULT);
1166 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_active)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001167 CAM_ERR(CAM_SENSOR,
1168 "Failed to get the active state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001169 return -EINVAL;
1170 }
1171 sensor_pctrl->gpio_state_suspend
1172 = pinctrl_lookup_state(sensor_pctrl->pinctrl,
1173 CAM_SENSOR_PINCTRL_STATE_SLEEP);
1174 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_suspend)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001175 CAM_ERR(CAM_SENSOR,
1176 "Failed to get the suspend state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001177 return -EINVAL;
1178 }
1179 return 0;
1180}
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001181int msm_cam_sensor_handle_reg_gpio(int seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301182 struct msm_camera_gpio_num_info *gpio_num_info, int val)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001183{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001184 int gpio_offset = -1;
1185
Alok Pandey01b1b352017-06-25 20:38:54 +05301186 if (!gpio_num_info) {
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001187 CAM_INFO(CAM_SENSOR, "Input Parameters are not proper");
1188 return 0;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001189 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301190
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001191 CAM_DBG(CAM_SENSOR, "Seq type: %d, config: %d", seq_type, val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001192
1193 gpio_offset = seq_type;
1194
Alok Pandey01b1b352017-06-25 20:38:54 +05301195 if (gpio_num_info->valid[gpio_offset] == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001196 CAM_DBG(CAM_SENSOR, "VALID GPIO offset: %d, seqtype: %d",
1197 gpio_offset, seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001198 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301199 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001200 [gpio_offset], val);
1201 }
1202
1203 return 0;
1204}
1205
Alok Pandey01b1b352017-06-25 20:38:54 +05301206int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
1207 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001208{
1209 int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301210 int32_t vreg_idx = -1;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001211 struct cam_sensor_power_setting *power_setting = NULL;
Alok Pandey01b1b352017-06-25 20:38:54 +05301212 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001213
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001214 CAM_DBG(CAM_SENSOR, "Enter");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001215 if (!ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001216 CAM_ERR(CAM_SENSOR, "Invalid ctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001217 return -EINVAL;
1218 }
1219
Alok Pandey01b1b352017-06-25 20:38:54 +05301220 gpio_num_info = ctrl->gpio_num_info;
1221 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001222
Jigarkumar Zalac6c090b2017-09-21 15:04:56 -07001223 if ((num_vreg <= 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Soundrapandian Jeyaprakash63045552017-09-20 16:55:34 -07001224 CAM_ERR(CAM_SENSOR, "failed: num_vreg %d", num_vreg);
Alok Pandey01b1b352017-06-25 20:38:54 +05301225 return -EINVAL;
1226 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001227
1228 ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
1229 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001230 CAM_ERR(CAM_SENSOR, "Initialization of pinctrl failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001231 ctrl->cam_pinctrl_status = 0;
1232 } else {
1233 ctrl->cam_pinctrl_status = 1;
1234 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301235
1236 rc = cam_sensor_util_request_gpio_table(soc_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001237 if (rc < 0)
1238 no_gpio = rc;
Alok Pandey01b1b352017-06-25 20:38:54 +05301239
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001240 if (ctrl->cam_pinctrl_status) {
1241 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1242 ctrl->pinctrl_info.gpio_state_active);
1243 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001244 CAM_ERR(CAM_SENSOR, "cannot set pin to active state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001245 }
1246
1247 for (index = 0; index < ctrl->power_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001248 CAM_DBG(CAM_SENSOR, "index: %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001249 power_setting = &ctrl->power_setting[index];
Vivek Veenam2ad8de12017-04-04 18:56:22 +05301250 CAM_DBG(CAM_SENSOR, "seq_type %d", power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001251
1252 switch (power_setting->seq_type) {
1253 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301254 if (power_setting->seq_val >= soc_info->num_clk) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001255 CAM_ERR(CAM_SENSOR, "clk index %d >= max %u",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001256 power_setting->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301257 soc_info->num_clk);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001258 goto power_up_failed;
1259 }
1260 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301261 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001262 "cam_clk")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001263 CAM_DBG(CAM_SENSOR,
1264 "Enable cam_clk: %d", j);
Alok Pandey01b1b352017-06-25 20:38:54 +05301265
1266 soc_info->rgltr[j] =
1267 regulator_get(
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001268 soc_info->dev,
Alok Pandey01b1b352017-06-25 20:38:54 +05301269 soc_info->rgltr_name[j]);
1270
1271 if (IS_ERR_OR_NULL(
1272 soc_info->rgltr[j])) {
1273 rc = PTR_ERR(
1274 soc_info->rgltr[j]);
1275 rc = rc ? rc : -EINVAL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001276 CAM_ERR(CAM_SENSOR,
1277 "vreg %s %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301278 soc_info->rgltr_name[j],
1279 rc);
1280 soc_info->rgltr[j] = NULL;
1281 }
1282
1283 rc = cam_soc_util_regulator_enable(
1284 soc_info->rgltr[j],
1285 soc_info->rgltr_name[j],
1286 soc_info->rgltr_min_volt[j],
1287 soc_info->rgltr_max_volt[j],
1288 soc_info->rgltr_op_mode[j],
1289 soc_info->rgltr_delay[j]);
1290
1291 power_setting->data[0] =
1292 soc_info->rgltr[j];
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001293 }
1294 }
1295 if (power_setting->config_val)
Alok Pandey01b1b352017-06-25 20:38:54 +05301296 soc_info->clk_rate[0][power_setting->seq_val] =
1297 power_setting->config_val;
1298
1299 for (j = 0; j < soc_info->num_clk; j++) {
1300 rc = cam_soc_util_clk_enable(soc_info->clk[j],
1301 soc_info->clk_name[j],
1302 soc_info->clk_rate[0][j]);
1303 if (rc)
1304 break;
1305 }
1306
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001307 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001308 CAM_ERR(CAM_SENSOR, "clk enable failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001309 goto power_up_failed;
1310 }
1311 break;
1312 case SENSOR_RESET:
1313 case SENSOR_STANDBY:
1314 case SENSOR_CUSTOM_GPIO1:
1315 case SENSOR_CUSTOM_GPIO2:
1316 if (no_gpio) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001317 CAM_ERR(CAM_SENSOR, "request gpio failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001318 return no_gpio;
1319 }
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001320 if (!gpio_num_info) {
1321 CAM_ERR(CAM_SENSOR, "Invalid gpio_num_info");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001322 goto power_up_failed;
1323 }
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001324 CAM_DBG(CAM_SENSOR, "gpio set val %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301325 gpio_num_info->gpio_num
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001326 [power_setting->seq_type]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001327
1328 rc = msm_cam_sensor_handle_reg_gpio(
1329 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301330 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001331 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001332 CAM_ERR(CAM_SENSOR,
1333 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001334 goto power_up_failed;
1335 }
1336 break;
1337 case SENSOR_VANA:
1338 case SENSOR_VDIG:
1339 case SENSOR_VIO:
1340 case SENSOR_VAF:
1341 case SENSOR_VAF_PWDM:
1342 case SENSOR_CUSTOM_REG1:
1343 case SENSOR_CUSTOM_REG2:
1344 if (power_setting->seq_val == INVALID_VREG)
1345 break;
1346
1347 if (power_setting->seq_val >= CAM_VREG_MAX) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001348 CAM_ERR(CAM_SENSOR, "vreg index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001349 power_setting->seq_val,
1350 CAM_VREG_MAX);
1351 goto power_up_failed;
1352 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301353 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001354 CAM_DBG(CAM_SENSOR, "Enable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301355 vreg_idx = power_setting->seq_val;
1356
1357 soc_info->rgltr[vreg_idx] =
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001358 regulator_get(soc_info->dev,
Alok Pandey01b1b352017-06-25 20:38:54 +05301359 soc_info->rgltr_name[vreg_idx]);
1360 if (IS_ERR_OR_NULL(
1361 soc_info->rgltr[vreg_idx])) {
1362 rc = PTR_ERR(soc_info->rgltr[vreg_idx]);
1363 rc = rc ? rc : -EINVAL;
1364
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001365 CAM_ERR(CAM_SENSOR, "%s get failed %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301366 soc_info->rgltr_name[vreg_idx],
1367 rc);
1368
1369 soc_info->rgltr[vreg_idx] = NULL;
1370 }
1371
1372 rc = cam_soc_util_regulator_enable(
1373 soc_info->rgltr[vreg_idx],
1374 soc_info->rgltr_name[vreg_idx],
1375 soc_info->rgltr_min_volt[vreg_idx],
1376 soc_info->rgltr_max_volt[vreg_idx],
1377 soc_info->rgltr_op_mode[vreg_idx],
1378 soc_info->rgltr_delay[vreg_idx]);
1379
1380 power_setting->data[0] =
1381 soc_info->rgltr[vreg_idx];
1382 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001383 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001384 CAM_ERR(CAM_SENSOR, "usr_idx:%d dts_idx:%d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301385 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001386
1387 rc = msm_cam_sensor_handle_reg_gpio(
1388 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301389 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001390 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001391 CAM_ERR(CAM_SENSOR,
1392 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001393 goto power_up_failed;
1394 }
1395 break;
1396 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001397 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1398 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001399 break;
1400 }
1401 if (power_setting->delay > 20)
1402 msleep(power_setting->delay);
1403 else if (power_setting->delay)
1404 usleep_range(power_setting->delay * 1000,
1405 (power_setting->delay * 1000) + 1000);
1406 }
1407
1408 return 0;
1409power_up_failed:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001410 CAM_ERR(CAM_SENSOR, "failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001411 for (index--; index >= 0; index--) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001412 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001413 power_setting = &ctrl->power_setting[index];
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001414 CAM_DBG(CAM_SENSOR, "type %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301415 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001416 switch (power_setting->seq_type) {
1417 case SENSOR_RESET:
1418 case SENSOR_STANDBY:
1419 case SENSOR_CUSTOM_GPIO1:
1420 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301421 if (!gpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001422 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301423 if (!gpio_num_info->valid
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001424 [power_setting->seq_type])
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001425 continue;
1426 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301427 gpio_num_info->gpio_num
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001428 [power_setting->seq_type], GPIOF_OUT_INIT_LOW);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001429 break;
1430 case SENSOR_VANA:
1431 case SENSOR_VDIG:
1432 case SENSOR_VIO:
1433 case SENSOR_VAF:
1434 case SENSOR_VAF_PWDM:
1435 case SENSOR_CUSTOM_REG1:
1436 case SENSOR_CUSTOM_REG2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301437 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001438 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301439 vreg_idx = power_setting->seq_val;
1440
1441 rc = cam_soc_util_regulator_disable(
1442 soc_info->rgltr[vreg_idx],
1443 soc_info->rgltr_name[vreg_idx],
1444 soc_info->rgltr_min_volt[vreg_idx],
1445 soc_info->rgltr_max_volt[vreg_idx],
1446 soc_info->rgltr_op_mode[vreg_idx],
1447 soc_info->rgltr_delay[vreg_idx]);
1448
1449 power_setting->data[0] =
1450 soc_info->rgltr[vreg_idx];
1451
1452 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001453 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001454 CAM_ERR(CAM_SENSOR, "seq_val:%d > num_vreg: %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301455 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001456
1457 msm_cam_sensor_handle_reg_gpio(power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301458 gpio_num_info, GPIOF_OUT_INIT_LOW);
1459
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001460 break;
1461 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001462 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1463 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001464 break;
1465 }
1466 if (power_setting->delay > 20) {
1467 msleep(power_setting->delay);
1468 } else if (power_setting->delay) {
1469 usleep_range(power_setting->delay * 1000,
1470 (power_setting->delay * 1000) + 1000);
1471 }
1472 }
1473 if (ctrl->cam_pinctrl_status) {
1474 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1475 ctrl->pinctrl_info.gpio_state_suspend);
1476 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001477 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001478 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1479 }
1480 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301481
1482 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001483
1484 return rc;
1485}
1486
1487static struct cam_sensor_power_setting*
1488msm_camera_get_power_settings(struct cam_sensor_power_ctrl_t *ctrl,
1489 enum msm_camera_power_seq_type seq_type,
1490 uint16_t seq_val)
1491{
1492 struct cam_sensor_power_setting *power_setting, *ps = NULL;
1493 int idx;
1494
1495 for (idx = 0; idx < ctrl->power_setting_size; idx++) {
1496 power_setting = &ctrl->power_setting[idx];
1497 if (power_setting->seq_type == seq_type &&
1498 power_setting->seq_val == seq_val) {
1499 ps = power_setting;
1500 return ps;
1501 }
1502
1503 }
1504
1505 return ps;
1506}
1507
1508static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
Alok Pandey01b1b352017-06-25 20:38:54 +05301509 struct cam_hw_soc_info *soc_info, int32_t index)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001510{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001511 int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
1512 struct cam_sensor_power_setting *ps = NULL;
1513 struct cam_sensor_power_setting *pd = NULL;
1514
Alok Pandey01b1b352017-06-25 20:38:54 +05301515 num_vreg = soc_info->num_rgltr;
1516
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001517 pd = &ctrl->power_down_setting[index];
1518
1519 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301520 if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001521
1522 ps = NULL;
1523 for (idx = 0; idx <
1524 ctrl->power_setting_size; idx++) {
1525 if (ctrl->power_setting[idx].
1526 seq_type == pd->seq_type) {
1527 ps = &ctrl->power_setting[idx];
1528 break;
1529 }
1530 }
1531
Alok Pandey01b1b352017-06-25 20:38:54 +05301532 if (ps != NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001533 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301534
1535 rc = cam_soc_util_regulator_disable(
1536 soc_info->rgltr[j],
1537 soc_info->rgltr_name[j],
1538 soc_info->rgltr_min_volt[j],
1539 soc_info->rgltr_max_volt[j],
1540 soc_info->rgltr_op_mode[j],
1541 soc_info->rgltr_delay[j]);
1542
1543 ps->data[0] =
1544 soc_info->rgltr[j];
1545 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001546 }
1547 }
1548
1549 return rc;
1550}
1551
Alok Pandey01b1b352017-06-25 20:38:54 +05301552int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
1553 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001554{
Alok Pandey01b1b352017-06-25 20:38:54 +05301555 int index = 0, ret = 0, num_vreg = 0, i;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001556 struct cam_sensor_power_setting *pd = NULL;
1557 struct cam_sensor_power_setting *ps;
Alok Pandey01b1b352017-06-25 20:38:54 +05301558 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001559
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001560 CAM_DBG(CAM_SENSOR, "Enter");
Alok Pandey01b1b352017-06-25 20:38:54 +05301561 if (!ctrl || !soc_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001562 CAM_ERR(CAM_SENSOR, "failed ctrl %pK", ctrl);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001563 return -EINVAL;
1564 }
1565
Alok Pandey01b1b352017-06-25 20:38:54 +05301566 gpio_num_info = ctrl->gpio_num_info;
1567 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001568
Jigarkumar Zalac6c090b2017-09-21 15:04:56 -07001569 if ((num_vreg <= 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Soundrapandian Jeyaprakash63045552017-09-20 16:55:34 -07001570 CAM_ERR(CAM_SENSOR, "failed: num_vreg %d", num_vreg);
1571 return -EINVAL;
1572 }
1573
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001574 for (index = 0; index < ctrl->power_down_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001575 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001576 pd = &ctrl->power_down_setting[index];
1577 ps = NULL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001578 CAM_DBG(CAM_SENSOR, "type %d", pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001579 switch (pd->seq_type) {
1580 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301581 ret = cam_config_mclk_reg(ctrl, soc_info, index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001582 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001583 CAM_ERR(CAM_SENSOR,
1584 "config clk reg failed rc: %d", ret);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001585 return ret;
1586 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301587 //cam_soc_util_clk_disable_default(soc_info);
1588 for (i = soc_info->num_clk - 1; i >= 0; i--) {
1589 cam_soc_util_clk_disable(soc_info->clk[i],
1590 soc_info->clk_name[i]);
1591 }
1592
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001593 break;
1594 case SENSOR_RESET:
1595 case SENSOR_STANDBY:
1596 case SENSOR_CUSTOM_GPIO1:
1597 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301598
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001599 if (!gpio_num_info->valid[pd->seq_type])
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001600 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301601
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001602 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301603 gpio_num_info->gpio_num
Viswanadha Raju Thotakura94406ce2017-09-01 15:20:54 -07001604 [pd->seq_type],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001605 (int) pd->config_val);
Alok Pandey01b1b352017-06-25 20:38:54 +05301606
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001607 break;
1608 case SENSOR_VANA:
1609 case SENSOR_VDIG:
1610 case SENSOR_VIO:
1611 case SENSOR_VAF:
1612 case SENSOR_VAF_PWDM:
1613 case SENSOR_CUSTOM_REG1:
1614 case SENSOR_CUSTOM_REG2:
1615 if (pd->seq_val == INVALID_VREG)
1616 break;
Alok Pandey01b1b352017-06-25 20:38:54 +05301617
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001618 ps = msm_camera_get_power_settings(
1619 ctrl, pd->seq_type,
1620 pd->seq_val);
1621 if (ps) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301622 if (pd->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001623 CAM_DBG(CAM_SENSOR,
1624 "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301625 ret = cam_soc_util_regulator_disable(
1626 soc_info->rgltr[ps->seq_val],
1627 soc_info->rgltr_name[ps->seq_val],
1628 soc_info->rgltr_min_volt[ps->seq_val],
1629 soc_info->rgltr_max_volt[ps->seq_val],
1630 soc_info->rgltr_op_mode[ps->seq_val],
1631 soc_info->rgltr_delay[ps->seq_val]);
1632
1633 ps->data[0] =
1634 soc_info->rgltr[ps->seq_val];
1635 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001636 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001637 CAM_ERR(CAM_SENSOR,
1638 "seq_val:%d > num_vreg: %d",
1639 pd->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301640 num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001641 } else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001642 CAM_ERR(CAM_SENSOR,
1643 "error in power up/down seq");
Alok Pandey01b1b352017-06-25 20:38:54 +05301644
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001645 ret = msm_cam_sensor_handle_reg_gpio(pd->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301646 gpio_num_info, GPIOF_OUT_INIT_LOW);
1647
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001648 if (ret < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001649 CAM_ERR(CAM_SENSOR,
1650 "Error disabling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001651 break;
1652 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001653 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1654 pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001655 break;
1656 }
1657 if (pd->delay > 20)
1658 msleep(pd->delay);
1659 else if (pd->delay)
1660 usleep_range(pd->delay * 1000,
1661 (pd->delay * 1000) + 1000);
1662 }
1663
1664 if (ctrl->cam_pinctrl_status) {
1665 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1666 ctrl->pinctrl_info.gpio_state_suspend);
1667 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001668 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001669 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1670 }
1671
1672 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301673
1674 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001675
1676 return 0;
1677}
1678