blob: 878ce73641c260364990281061da8c70649e56df [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
85 if (i2c_list == 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
199/**
200 * Name : cam_sensor_i2c_pkt_parser
201 * Description : Parse CSL CCI packet and apply register settings
202 * Parameters : s_ctrl input/output sub_device
203 * arg input cam_control
204 * Description :
205 * Handle multiple I2C RD/WR and WAIT cmd formats in one command
206 * buffer, for example, a command buffer of m x RND_WR + 1 x HW_
207 * WAIT + n x RND_WR with num_cmd_buf = 1. Do not exepect RD/WR
208 * with different cmd_type and op_code in one command buffer.
209 */
210int cam_sensor_i2c_pkt_parser(struct i2c_settings_array *i2c_reg_settings,
211 struct cam_cmd_buf_desc *cmd_desc, int32_t num_cmd_buffers)
212{
213 int16_t rc = 0, i = 0;
214 size_t len_of_buff = 0;
215 uint64_t generic_ptr;
216
217 for (i = 0; i < num_cmd_buffers; i++) {
218 uint32_t *cmd_buf = NULL;
219 struct common_header *cmm_hdr;
220 uint16_t generic_op_code;
221 uint32_t byte_cnt = 0;
222 uint32_t j = 0;
223 struct list_head *list = NULL;
224
225 /*
226 * It is not expected the same settings to
227 * be spread across multiple cmd buffers
228 */
229
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700230 CAM_DBG(CAM_SENSOR, "Total cmd Buf in Bytes: %d",
231 cmd_desc[i].length);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700232
233 if (!cmd_desc[i].length)
234 continue;
235
236 rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
237 (uint64_t *)&generic_ptr, &len_of_buff);
238 cmd_buf = (uint32_t *)generic_ptr;
239 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700240 CAM_ERR(CAM_SENSOR,
241 "cmd hdl failed:%d, Err: %d, Buffer_len: %ld",
242 cmd_desc[i].mem_handle, rc, len_of_buff);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700243 return rc;
244 }
245 cmd_buf += cmd_desc[i].offset / sizeof(uint32_t);
246
247 while (byte_cnt < cmd_desc[i].length) {
248 cmm_hdr = (struct common_header *)cmd_buf;
249 generic_op_code = cmm_hdr->third_byte;
250 switch (cmm_hdr->cmd_type) {
251 case CAMERA_SENSOR_CMD_TYPE_I2C_RNDM_WR: {
252 uint16_t cmd_length_in_bytes = 0;
253 struct cam_cmd_i2c_random_wr
254 *cam_cmd_i2c_random_wr =
255 (struct cam_cmd_i2c_random_wr *)cmd_buf;
256
257 rc = cam_sensor_handle_random_write(
258 cam_cmd_i2c_random_wr,
259 i2c_reg_settings,
260 &cmd_length_in_bytes, &j, &list);
261 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700262 CAM_ERR(CAM_SENSOR,
263 "Failed in random read %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700264 return rc;
265 }
266
267 cmd_buf += cmd_length_in_bytes /
268 sizeof(uint32_t);
269 byte_cnt += cmd_length_in_bytes;
270 break;
271 }
272 case CAMERA_SENSOR_CMD_TYPE_WAIT: {
273 if (generic_op_code ==
274 CAMERA_SENSOR_WAIT_OP_HW_UCND ||
275 generic_op_code ==
276 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
277
278 rc = cam_sensor_handle_delay(
279 &cmd_buf, generic_op_code,
280 i2c_reg_settings, j, &byte_cnt,
281 list);
282 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700283 CAM_ERR(CAM_SENSOR,
284 "delay hdl failed: %d",
285 rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700286 return rc;
287 }
288
289 } else if (generic_op_code ==
290 CAMERA_SENSOR_WAIT_OP_COND) {
291 rc = cam_sensor_handle_poll(
292 &cmd_buf, i2c_reg_settings,
293 &byte_cnt, &j, &list);
294 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700295 CAM_ERR(CAM_SENSOR,
296 "Random read fail: %d",
297 rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700298 return rc;
299 }
300 } else {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700301 CAM_ERR(CAM_SENSOR,
302 "Wrong Wait Command: %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700303 generic_op_code);
304 return -EINVAL;
305 }
306 break;
307 }
308 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700309 CAM_ERR(CAM_SENSOR, "Invalid Command Type:%d",
310 cmm_hdr->cmd_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700311 return -EINVAL;
312 }
313 }
314 i2c_reg_settings->is_settings_valid = 1;
315 }
316
317 return rc;
318}
319
Alok Pandey01b1b352017-06-25 20:38:54 +0530320int32_t msm_camera_fill_vreg_params(
321 struct cam_hw_soc_info *soc_info,
322 struct cam_sensor_power_setting *power_setting,
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700323 uint16_t power_setting_size)
324{
325 int32_t rc = 0, j = 0, i = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530326 uint32_t num_vreg;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700327
328 /* Validate input parameters */
Alok Pandey01b1b352017-06-25 20:38:54 +0530329 if (!soc_info || !power_setting) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700330 CAM_ERR(CAM_SENSOR, "failed: soc_info %pK power_setting %pK",
331 soc_info, power_setting);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700332 return -EINVAL;
333 }
334
Alok Pandey01b1b352017-06-25 20:38:54 +0530335 num_vreg = soc_info->num_rgltr;
336
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700337 if (num_vreg <= 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700338 CAM_ERR(CAM_SENSOR, "failed: num_vreg %d", num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700339 return -EINVAL;
340 }
341
342 for (i = 0; i < power_setting_size; i++) {
Viswanadha Raju Thotakura2c5c1a12017-08-23 15:56:22 -0700343
344 if (power_setting[i].seq_type < SENSOR_MCLK ||
345 power_setting[i].seq_type >= SENSOR_SEQ_TYPE_MAX) {
346 CAM_ERR(CAM_SENSOR, "failed: Invalid Seq type\n",
347 power_setting[i].seq_type);
348 return -EINVAL;
349 }
350
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700351 switch (power_setting[i].seq_type) {
352 case SENSOR_VDIG:
353 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530354 if (!strcmp(soc_info->rgltr_name[j],
355 "cam_vdig")) {
356
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700357 CAM_DBG(CAM_SENSOR,
358 "i: %d j: %d cam_vdig", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700359 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530360
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700361 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530362 soc_info->rgltr_min_volt[j],
363 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700364 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530365 soc_info->rgltr_min_volt[j] =
366 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700367 power_setting[i].config_val;
368 }
369 break;
370 }
371 }
372 if (j == num_vreg)
373 power_setting[i].seq_val = INVALID_VREG;
374 break;
375
376 case SENSOR_VIO:
377 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530378
379 if (!strcmp(soc_info->rgltr_name[j],
380 "cam_vio")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700381 CAM_DBG(CAM_SENSOR,
382 "i: %d j: %d cam_vio", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700383 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530384
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700385 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530386 soc_info->rgltr_min_volt[j],
387 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700388 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530389 soc_info->rgltr_min_volt[j] =
390 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700391 power_setting[i].config_val;
392 }
393 break;
394 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530395
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700396 }
397 if (j == num_vreg)
398 power_setting[i].seq_val = INVALID_VREG;
399 break;
400
401 case SENSOR_VANA:
402 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530403
404 if (!strcmp(soc_info->rgltr_name[j],
405 "cam_vana")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700406 CAM_DBG(CAM_SENSOR,
407 "i: %d j: %d cam_vana", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700408 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530409
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700410 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530411 soc_info->rgltr_min_volt[j],
412 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700413 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530414 soc_info->rgltr_min_volt[j] =
415 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700416 power_setting[i].config_val;
417 }
418 break;
419 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530420
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700421 }
422 if (j == num_vreg)
423 power_setting[i].seq_val = INVALID_VREG;
424 break;
425
426 case SENSOR_VAF:
427 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530428
429 if (!strcmp(soc_info->rgltr_name[j],
430 "cam_vaf")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700431 CAM_DBG(CAM_SENSOR,
432 "i: %d j: %d cam_vaf", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700433 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530434
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700435 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530436 soc_info->rgltr_min_volt[j],
437 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700438 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530439 soc_info->rgltr_min_volt[j] =
440 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700441 power_setting[i].config_val;
442 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530443
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700444 break;
445 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530446
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700447 }
448 if (j == num_vreg)
449 power_setting[i].seq_val = INVALID_VREG;
450 break;
451
452 case SENSOR_CUSTOM_REG1:
453 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530454
455 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700456 "cam_v_custom1")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700457 CAM_DBG(CAM_SENSOR,
458 "i:%d j:%d cam_vcustom1", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700459 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530460
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700461 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530462 soc_info->rgltr_min_volt[j],
463 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700464 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530465 soc_info->rgltr_min_volt[j] =
466 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700467 power_setting[i].config_val;
468 }
469 break;
470 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530471
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700472 }
473 if (j == num_vreg)
474 power_setting[i].seq_val = INVALID_VREG;
475 break;
476 case SENSOR_CUSTOM_REG2:
477 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530478
479 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700480 "cam_v_custom2")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700481 CAM_DBG(CAM_SENSOR,
482 "i:%d j:%d cam_vcustom2", 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 }
495 }
496 if (j == num_vreg)
497 power_setting[i].seq_val = INVALID_VREG;
498 break;
Viswanadha Raju Thotakura2c5c1a12017-08-23 15:56:22 -0700499 default:
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700500 break;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700501 }
502 }
503
504 return rc;
505}
506
Alok Pandey01b1b352017-06-25 20:38:54 +0530507int cam_sensor_util_request_gpio_table(
508 struct cam_hw_soc_info *soc_info, int gpio_en)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700509{
Alok Pandey01b1b352017-06-25 20:38:54 +0530510 int rc = 0, i = 0;
511 uint8_t size = 0;
512 struct cam_soc_gpio_data *gpio_conf =
513 soc_info->gpio_data;
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700514 struct gpio *gpio_tbl = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700515
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700516 if (!gpio_conf) {
517 CAM_INFO(CAM_SENSOR, "No GPIO data");
518 return 0;
519 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700520
Alok Pandey01b1b352017-06-25 20:38:54 +0530521 if (gpio_conf->cam_gpio_common_tbl_size <= 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700522 CAM_INFO(CAM_SENSOR, "No GPIO entry");
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700523 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700524 }
525
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700526 gpio_tbl = gpio_conf->cam_gpio_req_tbl;
527 size = gpio_conf->cam_gpio_req_tbl_size;
528
Alok Pandey01b1b352017-06-25 20:38:54 +0530529 if (!gpio_tbl || !size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700530 CAM_ERR(CAM_SENSOR, "invalid gpio_tbl %pK / size %d",
531 gpio_tbl, size);
Alok Pandey01b1b352017-06-25 20:38:54 +0530532 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700533 }
534
Alok Pandey01b1b352017-06-25 20:38:54 +0530535 for (i = 0; i < size; i++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700536 CAM_DBG(CAM_SENSOR, "i: %d, gpio %d dir %ld", i,
537 gpio_tbl[i].gpio, gpio_tbl[i].flags);
Alok Pandey01b1b352017-06-25 20:38:54 +0530538 }
539
540 if (gpio_en) {
541 for (i = 0; i < size; i++) {
542 rc = gpio_request_one(gpio_tbl[i].gpio,
543 gpio_tbl[i].flags, gpio_tbl[i].label);
544 if (rc) {
545 /*
546 * After GPIO request fails, contine to
547 * apply new gpios, outout a error message
548 * for driver bringup debug
549 */
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700550 CAM_ERR(CAM_SENSOR, "gpio %d:%s request fails",
Alok Pandey01b1b352017-06-25 20:38:54 +0530551 gpio_tbl[i].gpio, gpio_tbl[i].label);
552 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700553 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530554 } else {
555 gpio_free_array(gpio_tbl, size);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700556 }
557
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700558 return rc;
559}
560
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530561int32_t cam_sensor_update_power_settings(void *cmd_buf,
562 int cmd_length, struct cam_sensor_power_ctrl_t *power_info)
563{
564 int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
565 int32_t i = 0, pwr_up = 0, pwr_down = 0;
566 void *ptr = cmd_buf, *scr;
567 struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
568 struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
569
570 if (!pwr_cmd || !cmd_length) {
571 CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d",
572 pwr_cmd, cmd_length);
573 return -EINVAL;
574 }
575
576 power_info->power_setting_size = 0;
577 power_info->power_setting =
578 (struct cam_sensor_power_setting *)
579 kzalloc(sizeof(struct cam_sensor_power_setting) *
580 MAX_POWER_CONFIG, GFP_KERNEL);
581 if (!power_info->power_setting)
582 return -ENOMEM;
583
Soundrapandian Jeyaprakash687b32e2017-07-28 14:38:56 -0700584 power_info->power_down_setting_size = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530585 power_info->power_down_setting =
586 (struct cam_sensor_power_setting *)
587 kzalloc(sizeof(struct cam_sensor_power_setting) *
588 MAX_POWER_CONFIG, GFP_KERNEL);
589 if (!power_info->power_down_setting) {
590 rc = -ENOMEM;
591 goto free_power_settings;
592 }
593
594 while (tot_size < cmd_length) {
595 if (cmm_hdr->cmd_type ==
596 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
597 struct cam_cmd_power *pwr_cmd =
598 (struct cam_cmd_power *)ptr;
599
600 power_info->
601 power_setting_size +=
602 pwr_cmd->count;
603 scr = ptr + sizeof(struct cam_cmd_power);
604 tot_size = tot_size + sizeof(struct cam_cmd_power);
605
606 if (pwr_cmd->count == 0)
607 CAM_DBG(CAM_SENSOR, "Un expected Command");
608
609 for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
610 power_info->
611 power_setting[pwr_up].seq_type =
612 pwr_cmd->power_settings[i].
613 power_seq_type;
614 power_info->
615 power_setting[pwr_up].config_val =
616 pwr_cmd->power_settings[i].
617 config_val_low;
618 power_info->power_setting[pwr_up].delay = 0;
619 if (i) {
620 scr = scr +
621 sizeof(
622 struct cam_power_settings);
623 tot_size = tot_size +
624 sizeof(
625 struct cam_power_settings);
626 }
627 if (tot_size > cmd_length) {
628 CAM_ERR(CAM_SENSOR,
629 "Error: Cmd Buffer is wrong");
630 rc = -EINVAL;
631 goto free_power_down_settings;
632 }
633 CAM_DBG(CAM_SENSOR,
634 "Seq Type[%d]: %d Config_val: %ld",
635 pwr_up,
636 power_info->
637 power_setting[pwr_up].seq_type,
638 power_info->
639 power_setting[pwr_up].
640 config_val);
641 }
642 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
643 ptr = (void *) scr;
644 cmm_hdr = (struct common_header *)ptr;
645 } else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
646 struct cam_cmd_unconditional_wait *wait_cmd =
647 (struct cam_cmd_unconditional_wait *)ptr;
648 if (wait_cmd->op_code ==
649 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
650 if (last_cmd_type ==
651 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
652 if (pwr_up > 0)
653 power_info->
654 power_setting
655 [pwr_up - 1].delay +=
656 wait_cmd->delay;
657 else
658 CAM_ERR(CAM_SENSOR,
659 "Delay is expected only after valid power up setting");
660 } else if (last_cmd_type ==
661 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
662 if (pwr_down > 0)
663 power_info->
664 power_down_setting
665 [pwr_down - 1].delay +=
666 wait_cmd->delay;
667 else
668 CAM_ERR(CAM_SENSOR,
669 "Delay is expected only after valid power up setting");
670 }
671 } else
672 CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
673 wait_cmd->op_code);
674 tot_size = tot_size +
675 sizeof(struct cam_cmd_unconditional_wait);
676 if (tot_size > cmd_length) {
677 CAM_ERR(CAM_SENSOR, "Command Buffer is wrong");
678 return -EINVAL;
679 }
680 scr = (void *) (wait_cmd);
681 ptr = (void *)
682 (scr +
683 sizeof(struct cam_cmd_unconditional_wait));
684 CAM_DBG(CAM_SENSOR, "ptr: %pK sizeof: %d Next: %pK",
685 scr, (int32_t)sizeof(
686 struct cam_cmd_unconditional_wait), ptr);
687
688 cmm_hdr = (struct common_header *)ptr;
689 } else if (cmm_hdr->cmd_type ==
690 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
691 struct cam_cmd_power *pwr_cmd =
692 (struct cam_cmd_power *)ptr;
693
694 scr = ptr + sizeof(struct cam_cmd_power);
695 tot_size = tot_size + sizeof(struct cam_cmd_power);
696 power_info->power_down_setting_size += pwr_cmd->count;
697
698 if (pwr_cmd->count == 0)
699 CAM_ERR(CAM_SENSOR, "Invalid Command");
700
701 for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
702 power_info->
703 power_down_setting[pwr_down].
704 seq_type =
705 pwr_cmd->power_settings[i].
706 power_seq_type;
707 power_info->
708 power_down_setting[pwr_down].
709 config_val =
710 pwr_cmd->power_settings[i].
711 config_val_low;
712 power_info->
713 power_down_setting[pwr_down].delay = 0;
714 if (i) {
715 scr = scr +
716 sizeof(
717 struct cam_power_settings);
718 tot_size =
719 tot_size +
720 sizeof(
721 struct cam_power_settings);
722 }
723 if (tot_size > cmd_length) {
724 CAM_ERR(CAM_SENSOR,
725 "Command Buffer is wrong");
726 rc = -EINVAL;
727 goto free_power_down_settings;
728 }
729 CAM_DBG(CAM_SENSOR,
730 "Seq Type[%d]: %d Config_val: %ld",
731 pwr_down,
732 power_info->
733 power_down_setting[pwr_down].
734 seq_type,
735 power_info->
736 power_down_setting[pwr_down].
737 config_val);
738 }
739 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
740 ptr = (void *) scr;
741 cmm_hdr = (struct common_header *)ptr;
742 } else {
743 CAM_ERR(CAM_SENSOR,
744 "Error: Un expected Header Type: %d",
745 cmm_hdr->cmd_type);
746 }
747 }
748
749 return rc;
750free_power_down_settings:
751 kfree(power_info->power_down_setting);
752free_power_settings:
753 kfree(power_info->power_setting);
754 return rc;
755}
756
757int cam_get_dt_power_setting_data(struct device_node *of_node,
758 struct cam_hw_soc_info *soc_info,
759 struct cam_sensor_power_ctrl_t *power_info)
760{
761 int rc = 0, i;
762 int count = 0;
763 const char *seq_name = NULL;
764 uint32_t *array = NULL;
765 struct cam_sensor_power_setting *ps;
766 int c, end;
767
768 if (!power_info)
769 return -EINVAL;
770
771 count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
772 power_info->power_setting_size = count;
773
774 CAM_DBG(CAM_SENSOR, "qcom,cam-power-seq-type count %d", count);
775
776 if (count <= 0)
777 return 0;
778
779 ps = kcalloc(count, sizeof(*ps), GFP_KERNEL);
780 if (!ps)
781 return -ENOMEM;
782 power_info->power_setting = ps;
783
784 for (i = 0; i < count; i++) {
785 rc = of_property_read_string_index(of_node,
786 "qcom,cam-power-seq-type", i, &seq_name);
787 if (rc < 0) {
788 CAM_ERR(CAM_SENSOR, "failed");
789 goto ERROR1;
790 }
791 CAM_DBG(CAM_SENSOR, "seq_name[%d] = %s", i, seq_name);
792 if (!strcmp(seq_name, "cam_vio")) {
793 ps[i].seq_type = SENSOR_VIO;
794 } else if (!strcmp(seq_name, "cam_vana")) {
795 ps[i].seq_type = SENSOR_VANA;
796 } else if (!strcmp(seq_name, "cam_clk")) {
797 ps[i].seq_type = SENSOR_MCLK;
798 } else {
799 CAM_ERR(CAM_SENSOR, "unrecognized seq-type %s",
800 seq_name);
801 rc = -EILSEQ;
802 goto ERROR1;
803 }
804 CAM_DBG(CAM_SENSOR, "seq_type[%d] %d", i, ps[i].seq_type);
805 }
806
807 array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
808 if (!array) {
809 rc = -ENOMEM;
810 goto ERROR1;
811 }
812
813 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val",
814 array, count);
815 if (rc < 0) {
816 CAM_ERR(CAM_SENSOR, "failed ");
817 goto ERROR2;
818 }
819
820 for (i = 0; i < count; i++) {
821 ps[i].config_val = array[i];
822 CAM_DBG(CAM_SENSOR, "power_setting[%d].config_val = %ld", i,
823 ps[i].config_val);
824 }
825
826 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay",
827 array, count);
828 if (rc < 0) {
829 CAM_ERR(CAM_SENSOR, "failed");
830 goto ERROR2;
831 }
832 for (i = 0; i < count; i++) {
833 ps[i].delay = array[i];
834 CAM_DBG(CAM_SENSOR, "power_setting[%d].delay = %d", i,
835 ps[i].delay);
836 }
837 kfree(array);
838
839 power_info->power_down_setting =
840 kzalloc(sizeof(*ps) * count, GFP_KERNEL);
841
842 if (!power_info->power_down_setting) {
843 CAM_ERR(CAM_SENSOR, "failed");
844 rc = -ENOMEM;
845 goto ERROR1;
846 }
847
848 power_info->power_down_setting_size = count;
849
850 end = count - 1;
851
852 for (c = 0; c < count; c++) {
853 power_info->power_down_setting[c] = ps[end];
854 end--;
855 }
856 return rc;
857ERROR2:
858 kfree(array);
859ERROR1:
860 kfree(ps);
861 return rc;
862}
Alok Pandey01b1b352017-06-25 20:38:54 +0530863
864int cam_sensor_util_init_gpio_pin_tbl(
865 struct cam_hw_soc_info *soc_info,
866 struct msm_camera_gpio_num_info **pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700867{
868 int rc = 0, val = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530869 uint32_t gpio_array_size;
Alok Pandey01b1b352017-06-25 20:38:54 +0530870 struct device_node *of_node = NULL;
871 struct cam_soc_gpio_data *gconf = NULL;
872 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700873
Jigarkumar Zalaae152332017-07-18 17:21:48 -0700874 if (!soc_info->dev) {
875 CAM_ERR(CAM_SENSOR, "device node NULL");
876 return -EINVAL;
877 }
878
879 of_node = soc_info->dev->of_node;
Alok Pandey01b1b352017-06-25 20:38:54 +0530880
881 gconf = soc_info->gpio_data;
882 if (!gconf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700883 CAM_ERR(CAM_SENSOR, "No gpio_common_table is found");
Alok Pandey01b1b352017-06-25 20:38:54 +0530884 return -EINVAL;
885 }
886
887 if (!gconf->cam_gpio_common_tbl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700888 CAM_ERR(CAM_SENSOR, "gpio_common_table is not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +0530889 return -EINVAL;
890 }
891
892 gpio_array_size = gconf->cam_gpio_common_tbl_size;
893
894 if (!gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700895 CAM_ERR(CAM_SENSOR, "invalid size of gpio table");
Alok Pandey01b1b352017-06-25 20:38:54 +0530896 return -EINVAL;
897 }
898
899 *pgpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700900 GFP_KERNEL);
Alok Pandey01b1b352017-06-25 20:38:54 +0530901 if (!*pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700902 return -ENOMEM;
Alok Pandey01b1b352017-06-25 20:38:54 +0530903 gpio_num_info = *pgpio_num_info;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700904
Alok Pandey01b1b352017-06-25 20:38:54 +0530905 rc = of_property_read_u32(of_node, "gpio-vana", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700906 if (rc != -EINVAL) {
907 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700908 CAM_ERR(CAM_SENSOR, "read gpio-vana failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700909 goto free_gpio_info;
910 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700911 CAM_ERR(CAM_SENSOR, "gpio-vana invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700912 rc = -EINVAL;
913 goto free_gpio_info;
914 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530915 gpio_num_info->gpio_num[SENSOR_VANA] =
916 gconf->cam_gpio_common_tbl[val].gpio;
917 gpio_num_info->valid[SENSOR_VANA] = 1;
918
Jigarkumar Zala22223f92017-07-28 12:46:27 -0700919 CAM_DBG(CAM_SENSOR, "gpio-vana %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530920 gpio_num_info->gpio_num[SENSOR_VANA]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700921 }
922
Alok Pandey01b1b352017-06-25 20:38:54 +0530923 rc = of_property_read_u32(of_node, "gpio-vio", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700924 if (rc != -EINVAL) {
925 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700926 CAM_ERR(CAM_SENSOR, "read gpio-vio failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700927 goto free_gpio_info;
928 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700929 CAM_ERR(CAM_SENSOR, "gpio-vio invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700930 goto free_gpio_info;
931 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530932 gpio_num_info->gpio_num[SENSOR_VIO] =
933 gconf->cam_gpio_common_tbl[val].gpio;
934 gpio_num_info->valid[SENSOR_VIO] = 1;
935
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700936 CAM_DBG(CAM_SENSOR, "gpio-vio %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530937 gpio_num_info->gpio_num[SENSOR_VIO]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700938 }
939
Alok Pandey01b1b352017-06-25 20:38:54 +0530940 rc = of_property_read_u32(of_node, "gpio-vaf", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700941 if (rc != -EINVAL) {
942 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700943 CAM_ERR(CAM_SENSOR, "read gpio-vaf failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700944 goto free_gpio_info;
945 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700946 CAM_ERR(CAM_SENSOR, "gpio-vaf invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700947 rc = -EINVAL;
948 goto free_gpio_info;
949 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530950 gpio_num_info->gpio_num[SENSOR_VAF] =
951 gconf->cam_gpio_common_tbl[val].gpio;
952 gpio_num_info->valid[SENSOR_VAF] = 1;
953
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700954 CAM_DBG(CAM_SENSOR, "gpio-vaf %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530955 gpio_num_info->gpio_num[SENSOR_VAF]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700956 }
957
Alok Pandey01b1b352017-06-25 20:38:54 +0530958 rc = of_property_read_u32(of_node, "gpio-vdig", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700959 if (rc != -EINVAL) {
960 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700961 CAM_ERR(CAM_SENSOR, "read gpio-vdig failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700962 goto free_gpio_info;
963 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700964 CAM_ERR(CAM_SENSOR, "gpio-vdig invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700965 rc = -EINVAL;
966 goto free_gpio_info;
967 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530968 gpio_num_info->gpio_num[SENSOR_VDIG] =
969 gconf->cam_gpio_common_tbl[val].gpio;
970 gpio_num_info->valid[SENSOR_VDIG] = 1;
971
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700972 CAM_DBG(CAM_SENSOR, "gpio-vdig %d",
973 gpio_num_info->gpio_num[SENSOR_VDIG]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700974 }
975
Alok Pandey01b1b352017-06-25 20:38:54 +0530976 rc = of_property_read_u32(of_node, "gpio-reset", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700977 if (rc != -EINVAL) {
978 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700979 CAM_ERR(CAM_SENSOR, "read gpio-reset failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700980 goto free_gpio_info;
981 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700982 CAM_ERR(CAM_SENSOR, "gpio-reset invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700983 rc = -EINVAL;
984 goto free_gpio_info;
985 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530986 gpio_num_info->gpio_num[SENSOR_RESET] =
987 gconf->cam_gpio_common_tbl[val].gpio;
988 gpio_num_info->valid[SENSOR_RESET] = 1;
989
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700990 CAM_DBG(CAM_SENSOR, "gpio-reset %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530991 gpio_num_info->gpio_num[SENSOR_RESET]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700992 }
993
Alok Pandey01b1b352017-06-25 20:38:54 +0530994 rc = of_property_read_u32(of_node, "gpio-standby", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700995 if (rc != -EINVAL) {
996 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700997 CAM_ERR(CAM_SENSOR,
998 "read gpio-standby failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700999 goto free_gpio_info;
1000 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001001 CAM_ERR(CAM_SENSOR, "gpio-standby invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001002 rc = -EINVAL;
1003 goto free_gpio_info;
1004 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301005 gpio_num_info->gpio_num[SENSOR_STANDBY] =
1006 gconf->cam_gpio_common_tbl[val].gpio;
1007 gpio_num_info->valid[SENSOR_STANDBY] = 1;
1008
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001009 CAM_DBG(CAM_SENSOR, "gpio-standby %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301010 gpio_num_info->gpio_num[SENSOR_STANDBY]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001011 }
1012
Alok Pandey01b1b352017-06-25 20:38:54 +05301013 rc = of_property_read_u32(of_node, "gpio-af-pwdm", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001014 if (rc != -EINVAL) {
1015 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001016 CAM_ERR(CAM_SENSOR,
1017 "read gpio-af-pwdm failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001018 goto free_gpio_info;
1019 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001020 CAM_ERR(CAM_SENSOR, "gpio-af-pwdm invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001021 rc = -EINVAL;
1022 goto free_gpio_info;
1023 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301024 gpio_num_info->gpio_num[SENSOR_VAF_PWDM] =
1025 gconf->cam_gpio_common_tbl[val].gpio;
1026 gpio_num_info->valid[SENSOR_VAF_PWDM] = 1;
1027
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001028 CAM_DBG(CAM_SENSOR, "gpio-af-pwdm %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301029 gpio_num_info->gpio_num[SENSOR_VAF_PWDM]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001030 }
1031
Alok Pandey01b1b352017-06-25 20:38:54 +05301032 rc = of_property_read_u32(of_node, "gpio-custom1", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001033 if (rc != -EINVAL) {
1034 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001035 CAM_ERR(CAM_SENSOR,
1036 "read gpio-custom1 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-custom1 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_CUSTOM_GPIO1] =
1044 gconf->cam_gpio_common_tbl[val].gpio;
1045 gpio_num_info->valid[SENSOR_CUSTOM_GPIO1] = 1;
1046
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001047 CAM_DBG(CAM_SENSOR, "gpio-custom1 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301048 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1]);
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-custom2", &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,
1055 "read gpio-custom2 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001056 goto free_gpio_info;
1057 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001058 CAM_ERR(CAM_SENSOR, "gpio-custom2 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001059 rc = -EINVAL;
1060 goto free_gpio_info;
1061 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301062 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2] =
1063 gconf->cam_gpio_common_tbl[val].gpio;
1064 gpio_num_info->valid[SENSOR_CUSTOM_GPIO2] = 1;
1065
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001066 CAM_DBG(CAM_SENSOR, "gpio-custom2 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301067 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001068 } else {
1069 rc = 0;
1070 }
1071
1072 return rc;
1073
1074free_gpio_info:
Alok Pandey01b1b352017-06-25 20:38:54 +05301075 kfree(gpio_num_info);
1076 gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001077 return rc;
1078}
1079
1080int msm_camera_pinctrl_init(
1081 struct msm_pinctrl_info *sensor_pctrl, struct device *dev) {
1082
1083 sensor_pctrl->pinctrl = devm_pinctrl_get(dev);
1084 if (IS_ERR_OR_NULL(sensor_pctrl->pinctrl)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001085 CAM_ERR(CAM_SENSOR, "Getting pinctrl handle failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001086 return -EINVAL;
1087 }
1088 sensor_pctrl->gpio_state_active =
1089 pinctrl_lookup_state(sensor_pctrl->pinctrl,
1090 CAM_SENSOR_PINCTRL_STATE_DEFAULT);
1091 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_active)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001092 CAM_ERR(CAM_SENSOR,
1093 "Failed to get the active state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001094 return -EINVAL;
1095 }
1096 sensor_pctrl->gpio_state_suspend
1097 = pinctrl_lookup_state(sensor_pctrl->pinctrl,
1098 CAM_SENSOR_PINCTRL_STATE_SLEEP);
1099 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_suspend)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001100 CAM_ERR(CAM_SENSOR,
1101 "Failed to get the suspend state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001102 return -EINVAL;
1103 }
1104 return 0;
1105}
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001106int msm_cam_sensor_handle_reg_gpio(int seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301107 struct msm_camera_gpio_num_info *gpio_num_info, int val)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001108{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001109 int gpio_offset = -1;
1110
Alok Pandey01b1b352017-06-25 20:38:54 +05301111 if (!gpio_num_info) {
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001112 CAM_INFO(CAM_SENSOR, "Input Parameters are not proper");
1113 return 0;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001114 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301115
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001116 CAM_DBG(CAM_SENSOR, "Seq type: %d, config: %d", seq_type, val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001117
1118 gpio_offset = seq_type;
1119
Alok Pandey01b1b352017-06-25 20:38:54 +05301120 if (gpio_num_info->valid[gpio_offset] == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001121 CAM_DBG(CAM_SENSOR, "VALID GPIO offset: %d, seqtype: %d",
1122 gpio_offset, seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001123 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301124 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001125 [gpio_offset], val);
1126 }
1127
1128 return 0;
1129}
1130
Alok Pandey01b1b352017-06-25 20:38:54 +05301131int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
1132 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001133{
1134 int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301135 int32_t vreg_idx = -1;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001136 struct cam_sensor_power_setting *power_setting = NULL;
Alok Pandey01b1b352017-06-25 20:38:54 +05301137 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001138
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001139 CAM_DBG(CAM_SENSOR, "Enter");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001140 if (!ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001141 CAM_ERR(CAM_SENSOR, "Invalid ctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001142 return -EINVAL;
1143 }
1144
Alok Pandey01b1b352017-06-25 20:38:54 +05301145 gpio_num_info = ctrl->gpio_num_info;
1146 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001147
Alok Pandey01b1b352017-06-25 20:38:54 +05301148 if ((num_vreg == 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001149 CAM_ERR(CAM_SENSOR, "Regulators are not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +05301150 return -EINVAL;
1151 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001152
1153 ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
1154 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001155 CAM_ERR(CAM_SENSOR, "Initialization of pinctrl failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001156 ctrl->cam_pinctrl_status = 0;
1157 } else {
1158 ctrl->cam_pinctrl_status = 1;
1159 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301160
1161 rc = cam_sensor_util_request_gpio_table(soc_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001162 if (rc < 0)
1163 no_gpio = rc;
Alok Pandey01b1b352017-06-25 20:38:54 +05301164
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001165 if (ctrl->cam_pinctrl_status) {
1166 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1167 ctrl->pinctrl_info.gpio_state_active);
1168 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001169 CAM_ERR(CAM_SENSOR, "cannot set pin to active state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001170 }
1171
1172 for (index = 0; index < ctrl->power_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001173 CAM_DBG(CAM_SENSOR, "index: %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001174 power_setting = &ctrl->power_setting[index];
Vivek Veenam2ad8de12017-04-04 18:56:22 +05301175 CAM_DBG(CAM_SENSOR, "seq_type %d", power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001176
1177 switch (power_setting->seq_type) {
1178 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301179 if (power_setting->seq_val >= soc_info->num_clk) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001180 CAM_ERR(CAM_SENSOR, "clk index %d >= max %u",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001181 power_setting->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301182 soc_info->num_clk);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001183 goto power_up_failed;
1184 }
1185 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301186 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001187 "cam_clk")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001188 CAM_DBG(CAM_SENSOR,
1189 "Enable cam_clk: %d", j);
Alok Pandey01b1b352017-06-25 20:38:54 +05301190
1191 soc_info->rgltr[j] =
1192 regulator_get(
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001193 soc_info->dev,
Alok Pandey01b1b352017-06-25 20:38:54 +05301194 soc_info->rgltr_name[j]);
1195
1196 if (IS_ERR_OR_NULL(
1197 soc_info->rgltr[j])) {
1198 rc = PTR_ERR(
1199 soc_info->rgltr[j]);
1200 rc = rc ? rc : -EINVAL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001201 CAM_ERR(CAM_SENSOR,
1202 "vreg %s %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301203 soc_info->rgltr_name[j],
1204 rc);
1205 soc_info->rgltr[j] = NULL;
1206 }
1207
1208 rc = cam_soc_util_regulator_enable(
1209 soc_info->rgltr[j],
1210 soc_info->rgltr_name[j],
1211 soc_info->rgltr_min_volt[j],
1212 soc_info->rgltr_max_volt[j],
1213 soc_info->rgltr_op_mode[j],
1214 soc_info->rgltr_delay[j]);
1215
1216 power_setting->data[0] =
1217 soc_info->rgltr[j];
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001218 }
1219 }
1220 if (power_setting->config_val)
Alok Pandey01b1b352017-06-25 20:38:54 +05301221 soc_info->clk_rate[0][power_setting->seq_val] =
1222 power_setting->config_val;
1223
1224 for (j = 0; j < soc_info->num_clk; j++) {
1225 rc = cam_soc_util_clk_enable(soc_info->clk[j],
1226 soc_info->clk_name[j],
1227 soc_info->clk_rate[0][j]);
1228 if (rc)
1229 break;
1230 }
1231
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001232 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001233 CAM_ERR(CAM_SENSOR, "clk enable failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001234 goto power_up_failed;
1235 }
1236 break;
1237 case SENSOR_RESET:
1238 case SENSOR_STANDBY:
1239 case SENSOR_CUSTOM_GPIO1:
1240 case SENSOR_CUSTOM_GPIO2:
1241 if (no_gpio) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001242 CAM_ERR(CAM_SENSOR, "request gpio failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001243 return no_gpio;
1244 }
1245 if (power_setting->seq_val >= CAM_VREG_MAX ||
Alok Pandey01b1b352017-06-25 20:38:54 +05301246 !gpio_num_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001247 CAM_ERR(CAM_SENSOR, "gpio index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001248 power_setting->seq_val,
1249 CAM_VREG_MAX);
1250 goto power_up_failed;
1251 }
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001252 CAM_DBG(CAM_SENSOR, "gpio set val %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301253 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001254 [power_setting->seq_val]);
1255
1256 rc = msm_cam_sensor_handle_reg_gpio(
1257 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301258 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001259 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001260 CAM_ERR(CAM_SENSOR,
1261 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001262 goto power_up_failed;
1263 }
1264 break;
1265 case SENSOR_VANA:
1266 case SENSOR_VDIG:
1267 case SENSOR_VIO:
1268 case SENSOR_VAF:
1269 case SENSOR_VAF_PWDM:
1270 case SENSOR_CUSTOM_REG1:
1271 case SENSOR_CUSTOM_REG2:
1272 if (power_setting->seq_val == INVALID_VREG)
1273 break;
1274
1275 if (power_setting->seq_val >= CAM_VREG_MAX) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001276 CAM_ERR(CAM_SENSOR, "vreg index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001277 power_setting->seq_val,
1278 CAM_VREG_MAX);
1279 goto power_up_failed;
1280 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301281 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001282 CAM_DBG(CAM_SENSOR, "Enable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301283 vreg_idx = power_setting->seq_val;
1284
1285 soc_info->rgltr[vreg_idx] =
Jigarkumar Zalaae152332017-07-18 17:21:48 -07001286 regulator_get(soc_info->dev,
Alok Pandey01b1b352017-06-25 20:38:54 +05301287 soc_info->rgltr_name[vreg_idx]);
1288 if (IS_ERR_OR_NULL(
1289 soc_info->rgltr[vreg_idx])) {
1290 rc = PTR_ERR(soc_info->rgltr[vreg_idx]);
1291 rc = rc ? rc : -EINVAL;
1292
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001293 CAM_ERR(CAM_SENSOR, "%s get failed %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301294 soc_info->rgltr_name[vreg_idx],
1295 rc);
1296
1297 soc_info->rgltr[vreg_idx] = NULL;
1298 }
1299
1300 rc = cam_soc_util_regulator_enable(
1301 soc_info->rgltr[vreg_idx],
1302 soc_info->rgltr_name[vreg_idx],
1303 soc_info->rgltr_min_volt[vreg_idx],
1304 soc_info->rgltr_max_volt[vreg_idx],
1305 soc_info->rgltr_op_mode[vreg_idx],
1306 soc_info->rgltr_delay[vreg_idx]);
1307
1308 power_setting->data[0] =
1309 soc_info->rgltr[vreg_idx];
1310 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001311 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001312 CAM_ERR(CAM_SENSOR, "usr_idx:%d dts_idx:%d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301313 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001314
1315 rc = msm_cam_sensor_handle_reg_gpio(
1316 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301317 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001318 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001319 CAM_ERR(CAM_SENSOR,
1320 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001321 goto power_up_failed;
1322 }
1323 break;
1324 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001325 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1326 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001327 break;
1328 }
1329 if (power_setting->delay > 20)
1330 msleep(power_setting->delay);
1331 else if (power_setting->delay)
1332 usleep_range(power_setting->delay * 1000,
1333 (power_setting->delay * 1000) + 1000);
1334 }
1335
1336 return 0;
1337power_up_failed:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001338 CAM_ERR(CAM_SENSOR, "failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001339 for (index--; index >= 0; index--) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001340 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001341 power_setting = &ctrl->power_setting[index];
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001342 CAM_DBG(CAM_SENSOR, "type %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301343 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001344 switch (power_setting->seq_type) {
1345 case SENSOR_RESET:
1346 case SENSOR_STANDBY:
1347 case SENSOR_CUSTOM_GPIO1:
1348 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301349 if (!gpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001350 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301351 if (!gpio_num_info->valid
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001352 [power_setting->seq_val])
1353 continue;
1354 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301355 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001356 [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
1357 break;
1358 case SENSOR_VANA:
1359 case SENSOR_VDIG:
1360 case SENSOR_VIO:
1361 case SENSOR_VAF:
1362 case SENSOR_VAF_PWDM:
1363 case SENSOR_CUSTOM_REG1:
1364 case SENSOR_CUSTOM_REG2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301365 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001366 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301367 vreg_idx = power_setting->seq_val;
1368
1369 rc = cam_soc_util_regulator_disable(
1370 soc_info->rgltr[vreg_idx],
1371 soc_info->rgltr_name[vreg_idx],
1372 soc_info->rgltr_min_volt[vreg_idx],
1373 soc_info->rgltr_max_volt[vreg_idx],
1374 soc_info->rgltr_op_mode[vreg_idx],
1375 soc_info->rgltr_delay[vreg_idx]);
1376
1377 power_setting->data[0] =
1378 soc_info->rgltr[vreg_idx];
1379
1380 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001381 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001382 CAM_ERR(CAM_SENSOR, "seq_val:%d > num_vreg: %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301383 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001384
1385 msm_cam_sensor_handle_reg_gpio(power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301386 gpio_num_info, GPIOF_OUT_INIT_LOW);
1387
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001388 break;
1389 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001390 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1391 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001392 break;
1393 }
1394 if (power_setting->delay > 20) {
1395 msleep(power_setting->delay);
1396 } else if (power_setting->delay) {
1397 usleep_range(power_setting->delay * 1000,
1398 (power_setting->delay * 1000) + 1000);
1399 }
1400 }
1401 if (ctrl->cam_pinctrl_status) {
1402 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1403 ctrl->pinctrl_info.gpio_state_suspend);
1404 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001405 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001406 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1407 }
1408 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301409
1410 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001411
1412 return rc;
1413}
1414
1415static struct cam_sensor_power_setting*
1416msm_camera_get_power_settings(struct cam_sensor_power_ctrl_t *ctrl,
1417 enum msm_camera_power_seq_type seq_type,
1418 uint16_t seq_val)
1419{
1420 struct cam_sensor_power_setting *power_setting, *ps = NULL;
1421 int idx;
1422
1423 for (idx = 0; idx < ctrl->power_setting_size; idx++) {
1424 power_setting = &ctrl->power_setting[idx];
1425 if (power_setting->seq_type == seq_type &&
1426 power_setting->seq_val == seq_val) {
1427 ps = power_setting;
1428 return ps;
1429 }
1430
1431 }
1432
1433 return ps;
1434}
1435
1436static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
Alok Pandey01b1b352017-06-25 20:38:54 +05301437 struct cam_hw_soc_info *soc_info, int32_t index)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001438{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001439 int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
1440 struct cam_sensor_power_setting *ps = NULL;
1441 struct cam_sensor_power_setting *pd = NULL;
1442
Alok Pandey01b1b352017-06-25 20:38:54 +05301443 num_vreg = soc_info->num_rgltr;
1444
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001445 pd = &ctrl->power_down_setting[index];
1446
1447 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301448 if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001449
1450 ps = NULL;
1451 for (idx = 0; idx <
1452 ctrl->power_setting_size; idx++) {
1453 if (ctrl->power_setting[idx].
1454 seq_type == pd->seq_type) {
1455 ps = &ctrl->power_setting[idx];
1456 break;
1457 }
1458 }
1459
Alok Pandey01b1b352017-06-25 20:38:54 +05301460 if (ps != NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001461 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301462
1463 rc = cam_soc_util_regulator_disable(
1464 soc_info->rgltr[j],
1465 soc_info->rgltr_name[j],
1466 soc_info->rgltr_min_volt[j],
1467 soc_info->rgltr_max_volt[j],
1468 soc_info->rgltr_op_mode[j],
1469 soc_info->rgltr_delay[j]);
1470
1471 ps->data[0] =
1472 soc_info->rgltr[j];
1473 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001474 }
1475 }
1476
1477 return rc;
1478}
1479
Alok Pandey01b1b352017-06-25 20:38:54 +05301480int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
1481 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001482{
Alok Pandey01b1b352017-06-25 20:38:54 +05301483 int index = 0, ret = 0, num_vreg = 0, i;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001484 struct cam_sensor_power_setting *pd = NULL;
1485 struct cam_sensor_power_setting *ps;
Alok Pandey01b1b352017-06-25 20:38:54 +05301486 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001487
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001488 CAM_DBG(CAM_SENSOR, "Enter");
Alok Pandey01b1b352017-06-25 20:38:54 +05301489 if (!ctrl || !soc_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001490 CAM_ERR(CAM_SENSOR, "failed ctrl %pK", ctrl);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001491 return -EINVAL;
1492 }
1493
Alok Pandey01b1b352017-06-25 20:38:54 +05301494 gpio_num_info = ctrl->gpio_num_info;
1495 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001496
1497 for (index = 0; index < ctrl->power_down_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001498 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001499 pd = &ctrl->power_down_setting[index];
1500 ps = NULL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001501 CAM_DBG(CAM_SENSOR, "type %d", pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001502 switch (pd->seq_type) {
1503 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301504 ret = cam_config_mclk_reg(ctrl, soc_info, index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001505 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001506 CAM_ERR(CAM_SENSOR,
1507 "config clk reg failed rc: %d", ret);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001508 return ret;
1509 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301510 //cam_soc_util_clk_disable_default(soc_info);
1511 for (i = soc_info->num_clk - 1; i >= 0; i--) {
1512 cam_soc_util_clk_disable(soc_info->clk[i],
1513 soc_info->clk_name[i]);
1514 }
1515
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001516 break;
1517 case SENSOR_RESET:
1518 case SENSOR_STANDBY:
1519 case SENSOR_CUSTOM_GPIO1:
1520 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301521
1522 if (!gpio_num_info->valid[pd->seq_val])
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001523 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301524
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001525 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301526 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001527 [pd->seq_val],
1528 (int) pd->config_val);
Alok Pandey01b1b352017-06-25 20:38:54 +05301529
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001530 break;
1531 case SENSOR_VANA:
1532 case SENSOR_VDIG:
1533 case SENSOR_VIO:
1534 case SENSOR_VAF:
1535 case SENSOR_VAF_PWDM:
1536 case SENSOR_CUSTOM_REG1:
1537 case SENSOR_CUSTOM_REG2:
1538 if (pd->seq_val == INVALID_VREG)
1539 break;
Alok Pandey01b1b352017-06-25 20:38:54 +05301540
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001541 ps = msm_camera_get_power_settings(
1542 ctrl, pd->seq_type,
1543 pd->seq_val);
1544 if (ps) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301545 if (pd->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001546 CAM_DBG(CAM_SENSOR,
1547 "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301548 ret = cam_soc_util_regulator_disable(
1549 soc_info->rgltr[ps->seq_val],
1550 soc_info->rgltr_name[ps->seq_val],
1551 soc_info->rgltr_min_volt[ps->seq_val],
1552 soc_info->rgltr_max_volt[ps->seq_val],
1553 soc_info->rgltr_op_mode[ps->seq_val],
1554 soc_info->rgltr_delay[ps->seq_val]);
1555
1556 ps->data[0] =
1557 soc_info->rgltr[ps->seq_val];
1558 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001559 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001560 CAM_ERR(CAM_SENSOR,
1561 "seq_val:%d > num_vreg: %d",
1562 pd->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301563 num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001564 } else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001565 CAM_ERR(CAM_SENSOR,
1566 "error in power up/down seq");
Alok Pandey01b1b352017-06-25 20:38:54 +05301567
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001568 ret = msm_cam_sensor_handle_reg_gpio(pd->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301569 gpio_num_info, GPIOF_OUT_INIT_LOW);
1570
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001571 if (ret < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001572 CAM_ERR(CAM_SENSOR,
1573 "Error disabling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001574 break;
1575 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001576 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1577 pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001578 break;
1579 }
1580 if (pd->delay > 20)
1581 msleep(pd->delay);
1582 else if (pd->delay)
1583 usleep_range(pd->delay * 1000,
1584 (pd->delay * 1000) + 1000);
1585 }
1586
1587 if (ctrl->cam_pinctrl_status) {
1588 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1589 ctrl->pinctrl_info.gpio_state_suspend);
1590 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001591 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001592 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1593 }
1594
1595 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301596
1597 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001598
1599 return 0;
1600}
1601