blob: ea6f90210f19ee939ac17e770f49c2d8fbcd051b [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;
514 struct gpio *gpio_tbl = gpio_conf->cam_gpio_req_tbl;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700515
Alok Pandey01b1b352017-06-25 20:38:54 +0530516 size = gpio_conf->cam_gpio_req_tbl_size;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700517
Alok Pandey01b1b352017-06-25 20:38:54 +0530518 if (gpio_conf->cam_gpio_common_tbl_size <= 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700519 CAM_INFO(CAM_SENSOR, "No GPIO entry");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700520 return 0;
521 }
522
Alok Pandey01b1b352017-06-25 20:38:54 +0530523 if (!gpio_tbl || !size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700524 CAM_ERR(CAM_SENSOR, "invalid gpio_tbl %pK / size %d",
525 gpio_tbl, size);
Alok Pandey01b1b352017-06-25 20:38:54 +0530526 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700527 }
528
Alok Pandey01b1b352017-06-25 20:38:54 +0530529 for (i = 0; i < size; i++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700530 CAM_DBG(CAM_SENSOR, "i: %d, gpio %d dir %ld", i,
531 gpio_tbl[i].gpio, gpio_tbl[i].flags);
Alok Pandey01b1b352017-06-25 20:38:54 +0530532 }
533
534 if (gpio_en) {
535 for (i = 0; i < size; i++) {
536 rc = gpio_request_one(gpio_tbl[i].gpio,
537 gpio_tbl[i].flags, gpio_tbl[i].label);
538 if (rc) {
539 /*
540 * After GPIO request fails, contine to
541 * apply new gpios, outout a error message
542 * for driver bringup debug
543 */
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700544 CAM_ERR(CAM_SENSOR, "gpio %d:%s request fails",
Alok Pandey01b1b352017-06-25 20:38:54 +0530545 gpio_tbl[i].gpio, gpio_tbl[i].label);
546 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700547 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530548 } else {
549 gpio_free_array(gpio_tbl, size);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700550 }
551
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700552 return rc;
553}
554
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530555int32_t cam_sensor_update_power_settings(void *cmd_buf,
556 int cmd_length, struct cam_sensor_power_ctrl_t *power_info)
557{
558 int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
559 int32_t i = 0, pwr_up = 0, pwr_down = 0;
560 void *ptr = cmd_buf, *scr;
561 struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
562 struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
563
564 if (!pwr_cmd || !cmd_length) {
565 CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d",
566 pwr_cmd, cmd_length);
567 return -EINVAL;
568 }
569
570 power_info->power_setting_size = 0;
571 power_info->power_setting =
572 (struct cam_sensor_power_setting *)
573 kzalloc(sizeof(struct cam_sensor_power_setting) *
574 MAX_POWER_CONFIG, GFP_KERNEL);
575 if (!power_info->power_setting)
576 return -ENOMEM;
577
Soundrapandian Jeyaprakash687b32e2017-07-28 14:38:56 -0700578 power_info->power_down_setting_size = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530579 power_info->power_down_setting =
580 (struct cam_sensor_power_setting *)
581 kzalloc(sizeof(struct cam_sensor_power_setting) *
582 MAX_POWER_CONFIG, GFP_KERNEL);
583 if (!power_info->power_down_setting) {
584 rc = -ENOMEM;
585 goto free_power_settings;
586 }
587
588 while (tot_size < cmd_length) {
589 if (cmm_hdr->cmd_type ==
590 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
591 struct cam_cmd_power *pwr_cmd =
592 (struct cam_cmd_power *)ptr;
593
594 power_info->
595 power_setting_size +=
596 pwr_cmd->count;
597 scr = ptr + sizeof(struct cam_cmd_power);
598 tot_size = tot_size + sizeof(struct cam_cmd_power);
599
600 if (pwr_cmd->count == 0)
601 CAM_DBG(CAM_SENSOR, "Un expected Command");
602
603 for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
604 power_info->
605 power_setting[pwr_up].seq_type =
606 pwr_cmd->power_settings[i].
607 power_seq_type;
608 power_info->
609 power_setting[pwr_up].config_val =
610 pwr_cmd->power_settings[i].
611 config_val_low;
612 power_info->power_setting[pwr_up].delay = 0;
613 if (i) {
614 scr = scr +
615 sizeof(
616 struct cam_power_settings);
617 tot_size = tot_size +
618 sizeof(
619 struct cam_power_settings);
620 }
621 if (tot_size > cmd_length) {
622 CAM_ERR(CAM_SENSOR,
623 "Error: Cmd Buffer is wrong");
624 rc = -EINVAL;
625 goto free_power_down_settings;
626 }
627 CAM_DBG(CAM_SENSOR,
628 "Seq Type[%d]: %d Config_val: %ld",
629 pwr_up,
630 power_info->
631 power_setting[pwr_up].seq_type,
632 power_info->
633 power_setting[pwr_up].
634 config_val);
635 }
636 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
637 ptr = (void *) scr;
638 cmm_hdr = (struct common_header *)ptr;
639 } else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
640 struct cam_cmd_unconditional_wait *wait_cmd =
641 (struct cam_cmd_unconditional_wait *)ptr;
642 if (wait_cmd->op_code ==
643 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
644 if (last_cmd_type ==
645 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
646 if (pwr_up > 0)
647 power_info->
648 power_setting
649 [pwr_up - 1].delay +=
650 wait_cmd->delay;
651 else
652 CAM_ERR(CAM_SENSOR,
653 "Delay is expected only after valid power up setting");
654 } else if (last_cmd_type ==
655 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
656 if (pwr_down > 0)
657 power_info->
658 power_down_setting
659 [pwr_down - 1].delay +=
660 wait_cmd->delay;
661 else
662 CAM_ERR(CAM_SENSOR,
663 "Delay is expected only after valid power up setting");
664 }
665 } else
666 CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
667 wait_cmd->op_code);
668 tot_size = tot_size +
669 sizeof(struct cam_cmd_unconditional_wait);
670 if (tot_size > cmd_length) {
671 CAM_ERR(CAM_SENSOR, "Command Buffer is wrong");
672 return -EINVAL;
673 }
674 scr = (void *) (wait_cmd);
675 ptr = (void *)
676 (scr +
677 sizeof(struct cam_cmd_unconditional_wait));
678 CAM_DBG(CAM_SENSOR, "ptr: %pK sizeof: %d Next: %pK",
679 scr, (int32_t)sizeof(
680 struct cam_cmd_unconditional_wait), ptr);
681
682 cmm_hdr = (struct common_header *)ptr;
683 } else if (cmm_hdr->cmd_type ==
684 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
685 struct cam_cmd_power *pwr_cmd =
686 (struct cam_cmd_power *)ptr;
687
688 scr = ptr + sizeof(struct cam_cmd_power);
689 tot_size = tot_size + sizeof(struct cam_cmd_power);
690 power_info->power_down_setting_size += pwr_cmd->count;
691
692 if (pwr_cmd->count == 0)
693 CAM_ERR(CAM_SENSOR, "Invalid Command");
694
695 for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
696 power_info->
697 power_down_setting[pwr_down].
698 seq_type =
699 pwr_cmd->power_settings[i].
700 power_seq_type;
701 power_info->
702 power_down_setting[pwr_down].
703 config_val =
704 pwr_cmd->power_settings[i].
705 config_val_low;
706 power_info->
707 power_down_setting[pwr_down].delay = 0;
708 if (i) {
709 scr = scr +
710 sizeof(
711 struct cam_power_settings);
712 tot_size =
713 tot_size +
714 sizeof(
715 struct cam_power_settings);
716 }
717 if (tot_size > cmd_length) {
718 CAM_ERR(CAM_SENSOR,
719 "Command Buffer is wrong");
720 rc = -EINVAL;
721 goto free_power_down_settings;
722 }
723 CAM_DBG(CAM_SENSOR,
724 "Seq Type[%d]: %d Config_val: %ld",
725 pwr_down,
726 power_info->
727 power_down_setting[pwr_down].
728 seq_type,
729 power_info->
730 power_down_setting[pwr_down].
731 config_val);
732 }
733 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
734 ptr = (void *) scr;
735 cmm_hdr = (struct common_header *)ptr;
736 } else {
737 CAM_ERR(CAM_SENSOR,
738 "Error: Un expected Header Type: %d",
739 cmm_hdr->cmd_type);
740 }
741 }
742
743 return rc;
744free_power_down_settings:
745 kfree(power_info->power_down_setting);
746free_power_settings:
747 kfree(power_info->power_setting);
748 return rc;
749}
750
751int cam_get_dt_power_setting_data(struct device_node *of_node,
752 struct cam_hw_soc_info *soc_info,
753 struct cam_sensor_power_ctrl_t *power_info)
754{
755 int rc = 0, i;
756 int count = 0;
757 const char *seq_name = NULL;
758 uint32_t *array = NULL;
759 struct cam_sensor_power_setting *ps;
760 int c, end;
761
762 if (!power_info)
763 return -EINVAL;
764
765 count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
766 power_info->power_setting_size = count;
767
768 CAM_DBG(CAM_SENSOR, "qcom,cam-power-seq-type count %d", count);
769
770 if (count <= 0)
771 return 0;
772
773 ps = kcalloc(count, sizeof(*ps), GFP_KERNEL);
774 if (!ps)
775 return -ENOMEM;
776 power_info->power_setting = ps;
777
778 for (i = 0; i < count; i++) {
779 rc = of_property_read_string_index(of_node,
780 "qcom,cam-power-seq-type", i, &seq_name);
781 if (rc < 0) {
782 CAM_ERR(CAM_SENSOR, "failed");
783 goto ERROR1;
784 }
785 CAM_DBG(CAM_SENSOR, "seq_name[%d] = %s", i, seq_name);
786 if (!strcmp(seq_name, "cam_vio")) {
787 ps[i].seq_type = SENSOR_VIO;
788 } else if (!strcmp(seq_name, "cam_vana")) {
789 ps[i].seq_type = SENSOR_VANA;
790 } else if (!strcmp(seq_name, "cam_clk")) {
791 ps[i].seq_type = SENSOR_MCLK;
792 } else {
793 CAM_ERR(CAM_SENSOR, "unrecognized seq-type %s",
794 seq_name);
795 rc = -EILSEQ;
796 goto ERROR1;
797 }
798 CAM_DBG(CAM_SENSOR, "seq_type[%d] %d", i, ps[i].seq_type);
799 }
800
801 array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
802 if (!array) {
803 rc = -ENOMEM;
804 goto ERROR1;
805 }
806
807 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val",
808 array, count);
809 if (rc < 0) {
810 CAM_ERR(CAM_SENSOR, "failed ");
811 goto ERROR2;
812 }
813
814 for (i = 0; i < count; i++) {
815 ps[i].config_val = array[i];
816 CAM_DBG(CAM_SENSOR, "power_setting[%d].config_val = %ld", i,
817 ps[i].config_val);
818 }
819
820 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay",
821 array, count);
822 if (rc < 0) {
823 CAM_ERR(CAM_SENSOR, "failed");
824 goto ERROR2;
825 }
826 for (i = 0; i < count; i++) {
827 ps[i].delay = array[i];
828 CAM_DBG(CAM_SENSOR, "power_setting[%d].delay = %d", i,
829 ps[i].delay);
830 }
831 kfree(array);
832
833 power_info->power_down_setting =
834 kzalloc(sizeof(*ps) * count, GFP_KERNEL);
835
836 if (!power_info->power_down_setting) {
837 CAM_ERR(CAM_SENSOR, "failed");
838 rc = -ENOMEM;
839 goto ERROR1;
840 }
841
842 power_info->power_down_setting_size = count;
843
844 end = count - 1;
845
846 for (c = 0; c < count; c++) {
847 power_info->power_down_setting[c] = ps[end];
848 end--;
849 }
850 return rc;
851ERROR2:
852 kfree(array);
853ERROR1:
854 kfree(ps);
855 return rc;
856}
Alok Pandey01b1b352017-06-25 20:38:54 +0530857
858int cam_sensor_util_init_gpio_pin_tbl(
859 struct cam_hw_soc_info *soc_info,
860 struct msm_camera_gpio_num_info **pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700861{
862 int rc = 0, val = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530863 uint32_t gpio_array_size;
864 struct platform_device *pdev = NULL;
865 struct device_node *of_node = NULL;
866 struct cam_soc_gpio_data *gconf = NULL;
867 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700868
Alok Pandey01b1b352017-06-25 20:38:54 +0530869 pdev = soc_info->pdev;
870 of_node = pdev->dev.of_node;
871
872 gconf = soc_info->gpio_data;
873 if (!gconf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700874 CAM_ERR(CAM_SENSOR, "No gpio_common_table is found");
Alok Pandey01b1b352017-06-25 20:38:54 +0530875 return -EINVAL;
876 }
877
878 if (!gconf->cam_gpio_common_tbl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700879 CAM_ERR(CAM_SENSOR, "gpio_common_table is not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +0530880 return -EINVAL;
881 }
882
883 gpio_array_size = gconf->cam_gpio_common_tbl_size;
884
885 if (!gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700886 CAM_ERR(CAM_SENSOR, "invalid size of gpio table");
Alok Pandey01b1b352017-06-25 20:38:54 +0530887 return -EINVAL;
888 }
889
890 *pgpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700891 GFP_KERNEL);
Alok Pandey01b1b352017-06-25 20:38:54 +0530892 if (!*pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700893 return -ENOMEM;
Alok Pandey01b1b352017-06-25 20:38:54 +0530894 gpio_num_info = *pgpio_num_info;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700895
Alok Pandey01b1b352017-06-25 20:38:54 +0530896 rc = of_property_read_u32(of_node, "gpio-vana", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700897 if (rc != -EINVAL) {
898 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700899 CAM_ERR(CAM_SENSOR, "read gpio-vana failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700900 goto free_gpio_info;
901 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700902 CAM_ERR(CAM_SENSOR, "gpio-vana invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700903 rc = -EINVAL;
904 goto free_gpio_info;
905 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530906 gpio_num_info->gpio_num[SENSOR_VANA] =
907 gconf->cam_gpio_common_tbl[val].gpio;
908 gpio_num_info->valid[SENSOR_VANA] = 1;
909
Jigarkumar Zala22223f92017-07-28 12:46:27 -0700910 CAM_DBG(CAM_SENSOR, "gpio-vana %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530911 gpio_num_info->gpio_num[SENSOR_VANA]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700912 }
913
Alok Pandey01b1b352017-06-25 20:38:54 +0530914 rc = of_property_read_u32(of_node, "gpio-vio", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700915 if (rc != -EINVAL) {
916 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700917 CAM_ERR(CAM_SENSOR, "read gpio-vio failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700918 goto free_gpio_info;
919 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700920 CAM_ERR(CAM_SENSOR, "gpio-vio invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700921 goto free_gpio_info;
922 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530923 gpio_num_info->gpio_num[SENSOR_VIO] =
924 gconf->cam_gpio_common_tbl[val].gpio;
925 gpio_num_info->valid[SENSOR_VIO] = 1;
926
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700927 CAM_DBG(CAM_SENSOR, "gpio-vio %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530928 gpio_num_info->gpio_num[SENSOR_VIO]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700929 }
930
Alok Pandey01b1b352017-06-25 20:38:54 +0530931 rc = of_property_read_u32(of_node, "gpio-vaf", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700932 if (rc != -EINVAL) {
933 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700934 CAM_ERR(CAM_SENSOR, "read gpio-vaf failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700935 goto free_gpio_info;
936 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700937 CAM_ERR(CAM_SENSOR, "gpio-vaf invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700938 rc = -EINVAL;
939 goto free_gpio_info;
940 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530941 gpio_num_info->gpio_num[SENSOR_VAF] =
942 gconf->cam_gpio_common_tbl[val].gpio;
943 gpio_num_info->valid[SENSOR_VAF] = 1;
944
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700945 CAM_DBG(CAM_SENSOR, "gpio-vaf %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530946 gpio_num_info->gpio_num[SENSOR_VAF]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700947 }
948
Alok Pandey01b1b352017-06-25 20:38:54 +0530949 rc = of_property_read_u32(of_node, "gpio-vdig", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700950 if (rc != -EINVAL) {
951 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700952 CAM_ERR(CAM_SENSOR, "read gpio-vdig failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700953 goto free_gpio_info;
954 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700955 CAM_ERR(CAM_SENSOR, "gpio-vdig invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700956 rc = -EINVAL;
957 goto free_gpio_info;
958 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530959 gpio_num_info->gpio_num[SENSOR_VDIG] =
960 gconf->cam_gpio_common_tbl[val].gpio;
961 gpio_num_info->valid[SENSOR_VDIG] = 1;
962
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700963 CAM_DBG(CAM_SENSOR, "gpio-vdig %d",
964 gpio_num_info->gpio_num[SENSOR_VDIG]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700965 }
966
Alok Pandey01b1b352017-06-25 20:38:54 +0530967 rc = of_property_read_u32(of_node, "gpio-reset", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700968 if (rc != -EINVAL) {
969 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700970 CAM_ERR(CAM_SENSOR, "read gpio-reset failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700971 goto free_gpio_info;
972 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700973 CAM_ERR(CAM_SENSOR, "gpio-reset invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700974 rc = -EINVAL;
975 goto free_gpio_info;
976 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530977 gpio_num_info->gpio_num[SENSOR_RESET] =
978 gconf->cam_gpio_common_tbl[val].gpio;
979 gpio_num_info->valid[SENSOR_RESET] = 1;
980
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700981 CAM_DBG(CAM_SENSOR, "gpio-reset %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530982 gpio_num_info->gpio_num[SENSOR_RESET]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700983 }
984
Alok Pandey01b1b352017-06-25 20:38:54 +0530985 rc = of_property_read_u32(of_node, "gpio-standby", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700986 if (rc != -EINVAL) {
987 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700988 CAM_ERR(CAM_SENSOR,
989 "read gpio-standby failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700990 goto free_gpio_info;
991 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700992 CAM_ERR(CAM_SENSOR, "gpio-standby invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700993 rc = -EINVAL;
994 goto free_gpio_info;
995 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530996 gpio_num_info->gpio_num[SENSOR_STANDBY] =
997 gconf->cam_gpio_common_tbl[val].gpio;
998 gpio_num_info->valid[SENSOR_STANDBY] = 1;
999
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001000 CAM_DBG(CAM_SENSOR, "gpio-standby %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301001 gpio_num_info->gpio_num[SENSOR_STANDBY]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001002 }
1003
Alok Pandey01b1b352017-06-25 20:38:54 +05301004 rc = of_property_read_u32(of_node, "gpio-af-pwdm", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001005 if (rc != -EINVAL) {
1006 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001007 CAM_ERR(CAM_SENSOR,
1008 "read gpio-af-pwdm failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001009 goto free_gpio_info;
1010 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001011 CAM_ERR(CAM_SENSOR, "gpio-af-pwdm invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001012 rc = -EINVAL;
1013 goto free_gpio_info;
1014 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301015 gpio_num_info->gpio_num[SENSOR_VAF_PWDM] =
1016 gconf->cam_gpio_common_tbl[val].gpio;
1017 gpio_num_info->valid[SENSOR_VAF_PWDM] = 1;
1018
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001019 CAM_DBG(CAM_SENSOR, "gpio-af-pwdm %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301020 gpio_num_info->gpio_num[SENSOR_VAF_PWDM]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001021 }
1022
Alok Pandey01b1b352017-06-25 20:38:54 +05301023 rc = of_property_read_u32(of_node, "gpio-custom1", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001024 if (rc != -EINVAL) {
1025 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001026 CAM_ERR(CAM_SENSOR,
1027 "read gpio-custom1 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001028 goto free_gpio_info;
1029 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001030 CAM_ERR(CAM_SENSOR, "gpio-custom1 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001031 rc = -EINVAL;
1032 goto free_gpio_info;
1033 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301034 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1] =
1035 gconf->cam_gpio_common_tbl[val].gpio;
1036 gpio_num_info->valid[SENSOR_CUSTOM_GPIO1] = 1;
1037
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001038 CAM_DBG(CAM_SENSOR, "gpio-custom1 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301039 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001040 }
1041
Alok Pandey01b1b352017-06-25 20:38:54 +05301042 rc = of_property_read_u32(of_node, "gpio-custom2", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001043 if (rc != -EINVAL) {
1044 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001045 CAM_ERR(CAM_SENSOR,
1046 "read gpio-custom2 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001047 goto free_gpio_info;
1048 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001049 CAM_ERR(CAM_SENSOR, "gpio-custom2 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001050 rc = -EINVAL;
1051 goto free_gpio_info;
1052 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301053 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2] =
1054 gconf->cam_gpio_common_tbl[val].gpio;
1055 gpio_num_info->valid[SENSOR_CUSTOM_GPIO2] = 1;
1056
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001057 CAM_DBG(CAM_SENSOR, "gpio-custom2 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301058 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001059 } else {
1060 rc = 0;
1061 }
1062
1063 return rc;
1064
1065free_gpio_info:
Alok Pandey01b1b352017-06-25 20:38:54 +05301066 kfree(gpio_num_info);
1067 gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001068 return rc;
1069}
1070
1071int msm_camera_pinctrl_init(
1072 struct msm_pinctrl_info *sensor_pctrl, struct device *dev) {
1073
1074 sensor_pctrl->pinctrl = devm_pinctrl_get(dev);
1075 if (IS_ERR_OR_NULL(sensor_pctrl->pinctrl)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001076 CAM_ERR(CAM_SENSOR, "Getting pinctrl handle failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001077 return -EINVAL;
1078 }
1079 sensor_pctrl->gpio_state_active =
1080 pinctrl_lookup_state(sensor_pctrl->pinctrl,
1081 CAM_SENSOR_PINCTRL_STATE_DEFAULT);
1082 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_active)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001083 CAM_ERR(CAM_SENSOR,
1084 "Failed to get the active state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001085 return -EINVAL;
1086 }
1087 sensor_pctrl->gpio_state_suspend
1088 = pinctrl_lookup_state(sensor_pctrl->pinctrl,
1089 CAM_SENSOR_PINCTRL_STATE_SLEEP);
1090 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_suspend)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001091 CAM_ERR(CAM_SENSOR,
1092 "Failed to get the suspend state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001093 return -EINVAL;
1094 }
1095 return 0;
1096}
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001097int msm_cam_sensor_handle_reg_gpio(int seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301098 struct msm_camera_gpio_num_info *gpio_num_info, int val)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001099{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001100 int gpio_offset = -1;
1101
Alok Pandey01b1b352017-06-25 20:38:54 +05301102 if (!gpio_num_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001103 CAM_ERR(CAM_SENSOR, "Input Parameters are not proper");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001104 return -EINVAL;
1105 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301106
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001107 CAM_DBG(CAM_SENSOR, "Seq type: %d, config: %d", seq_type, val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001108
1109 gpio_offset = seq_type;
1110
Alok Pandey01b1b352017-06-25 20:38:54 +05301111 if (gpio_num_info->valid[gpio_offset] == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001112 CAM_DBG(CAM_SENSOR, "VALID GPIO offset: %d, seqtype: %d",
1113 gpio_offset, seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001114 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301115 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001116 [gpio_offset], val);
1117 }
1118
1119 return 0;
1120}
1121
Alok Pandey01b1b352017-06-25 20:38:54 +05301122int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
1123 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001124{
1125 int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301126 int32_t vreg_idx = -1;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001127 struct cam_sensor_power_setting *power_setting = NULL;
Alok Pandey01b1b352017-06-25 20:38:54 +05301128 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001129
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001130 CAM_DBG(CAM_SENSOR, "Enter");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001131 if (!ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001132 CAM_ERR(CAM_SENSOR, "Invalid ctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001133 return -EINVAL;
1134 }
1135
Alok Pandey01b1b352017-06-25 20:38:54 +05301136 gpio_num_info = ctrl->gpio_num_info;
1137 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001138
Alok Pandey01b1b352017-06-25 20:38:54 +05301139 if ((num_vreg == 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001140 CAM_ERR(CAM_SENSOR, "Regulators are not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +05301141 return -EINVAL;
1142 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001143
1144 ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
1145 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001146 CAM_ERR(CAM_SENSOR, "Initialization of pinctrl failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001147 ctrl->cam_pinctrl_status = 0;
1148 } else {
1149 ctrl->cam_pinctrl_status = 1;
1150 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301151
1152 rc = cam_sensor_util_request_gpio_table(soc_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001153 if (rc < 0)
1154 no_gpio = rc;
Alok Pandey01b1b352017-06-25 20:38:54 +05301155
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001156 if (ctrl->cam_pinctrl_status) {
1157 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1158 ctrl->pinctrl_info.gpio_state_active);
1159 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001160 CAM_ERR(CAM_SENSOR, "cannot set pin to active state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001161 }
1162
1163 for (index = 0; index < ctrl->power_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001164 CAM_DBG(CAM_SENSOR, "index: %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001165 power_setting = &ctrl->power_setting[index];
Vivek Veenam2ad8de12017-04-04 18:56:22 +05301166 CAM_DBG(CAM_SENSOR, "seq_type %d", power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001167
1168 switch (power_setting->seq_type) {
1169 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301170 if (power_setting->seq_val >= soc_info->num_clk) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001171 CAM_ERR(CAM_SENSOR, "clk index %d >= max %u",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001172 power_setting->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301173 soc_info->num_clk);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001174 goto power_up_failed;
1175 }
1176 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301177 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001178 "cam_clk")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001179 CAM_DBG(CAM_SENSOR,
1180 "Enable cam_clk: %d", j);
Alok Pandey01b1b352017-06-25 20:38:54 +05301181
1182 soc_info->rgltr[j] =
1183 regulator_get(
1184 &soc_info->pdev->dev,
1185 soc_info->rgltr_name[j]);
1186
1187 if (IS_ERR_OR_NULL(
1188 soc_info->rgltr[j])) {
1189 rc = PTR_ERR(
1190 soc_info->rgltr[j]);
1191 rc = rc ? rc : -EINVAL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001192 CAM_ERR(CAM_SENSOR,
1193 "vreg %s %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301194 soc_info->rgltr_name[j],
1195 rc);
1196 soc_info->rgltr[j] = NULL;
1197 }
1198
1199 rc = cam_soc_util_regulator_enable(
1200 soc_info->rgltr[j],
1201 soc_info->rgltr_name[j],
1202 soc_info->rgltr_min_volt[j],
1203 soc_info->rgltr_max_volt[j],
1204 soc_info->rgltr_op_mode[j],
1205 soc_info->rgltr_delay[j]);
1206
1207 power_setting->data[0] =
1208 soc_info->rgltr[j];
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001209 }
1210 }
1211 if (power_setting->config_val)
Alok Pandey01b1b352017-06-25 20:38:54 +05301212 soc_info->clk_rate[0][power_setting->seq_val] =
1213 power_setting->config_val;
1214
1215 for (j = 0; j < soc_info->num_clk; j++) {
1216 rc = cam_soc_util_clk_enable(soc_info->clk[j],
1217 soc_info->clk_name[j],
1218 soc_info->clk_rate[0][j]);
1219 if (rc)
1220 break;
1221 }
1222
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001223 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001224 CAM_ERR(CAM_SENSOR, "clk enable failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001225 goto power_up_failed;
1226 }
1227 break;
1228 case SENSOR_RESET:
1229 case SENSOR_STANDBY:
1230 case SENSOR_CUSTOM_GPIO1:
1231 case SENSOR_CUSTOM_GPIO2:
1232 if (no_gpio) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001233 CAM_ERR(CAM_SENSOR, "request gpio failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001234 return no_gpio;
1235 }
1236 if (power_setting->seq_val >= CAM_VREG_MAX ||
Alok Pandey01b1b352017-06-25 20:38:54 +05301237 !gpio_num_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001238 CAM_ERR(CAM_SENSOR, "gpio index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001239 power_setting->seq_val,
1240 CAM_VREG_MAX);
1241 goto power_up_failed;
1242 }
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001243 CAM_DBG(CAM_SENSOR, "gpio set val %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301244 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001245 [power_setting->seq_val]);
1246
1247 rc = msm_cam_sensor_handle_reg_gpio(
1248 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301249 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001250 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001251 CAM_ERR(CAM_SENSOR,
1252 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001253 goto power_up_failed;
1254 }
1255 break;
1256 case SENSOR_VANA:
1257 case SENSOR_VDIG:
1258 case SENSOR_VIO:
1259 case SENSOR_VAF:
1260 case SENSOR_VAF_PWDM:
1261 case SENSOR_CUSTOM_REG1:
1262 case SENSOR_CUSTOM_REG2:
1263 if (power_setting->seq_val == INVALID_VREG)
1264 break;
1265
1266 if (power_setting->seq_val >= CAM_VREG_MAX) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001267 CAM_ERR(CAM_SENSOR, "vreg index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001268 power_setting->seq_val,
1269 CAM_VREG_MAX);
1270 goto power_up_failed;
1271 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301272 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001273 CAM_DBG(CAM_SENSOR, "Enable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301274 vreg_idx = power_setting->seq_val;
1275
1276 soc_info->rgltr[vreg_idx] =
1277 regulator_get(&soc_info->pdev->dev,
1278 soc_info->rgltr_name[vreg_idx]);
1279 if (IS_ERR_OR_NULL(
1280 soc_info->rgltr[vreg_idx])) {
1281 rc = PTR_ERR(soc_info->rgltr[vreg_idx]);
1282 rc = rc ? rc : -EINVAL;
1283
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001284 CAM_ERR(CAM_SENSOR, "%s get failed %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301285 soc_info->rgltr_name[vreg_idx],
1286 rc);
1287
1288 soc_info->rgltr[vreg_idx] = NULL;
1289 }
1290
1291 rc = cam_soc_util_regulator_enable(
1292 soc_info->rgltr[vreg_idx],
1293 soc_info->rgltr_name[vreg_idx],
1294 soc_info->rgltr_min_volt[vreg_idx],
1295 soc_info->rgltr_max_volt[vreg_idx],
1296 soc_info->rgltr_op_mode[vreg_idx],
1297 soc_info->rgltr_delay[vreg_idx]);
1298
1299 power_setting->data[0] =
1300 soc_info->rgltr[vreg_idx];
1301 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001302 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001303 CAM_ERR(CAM_SENSOR, "usr_idx:%d dts_idx:%d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301304 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001305
1306 rc = msm_cam_sensor_handle_reg_gpio(
1307 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301308 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001309 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001310 CAM_ERR(CAM_SENSOR,
1311 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001312 goto power_up_failed;
1313 }
1314 break;
1315 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001316 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1317 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001318 break;
1319 }
1320 if (power_setting->delay > 20)
1321 msleep(power_setting->delay);
1322 else if (power_setting->delay)
1323 usleep_range(power_setting->delay * 1000,
1324 (power_setting->delay * 1000) + 1000);
1325 }
1326
1327 return 0;
1328power_up_failed:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001329 CAM_ERR(CAM_SENSOR, "failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001330 for (index--; index >= 0; index--) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001331 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001332 power_setting = &ctrl->power_setting[index];
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001333 CAM_DBG(CAM_SENSOR, "type %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301334 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001335 switch (power_setting->seq_type) {
1336 case SENSOR_RESET:
1337 case SENSOR_STANDBY:
1338 case SENSOR_CUSTOM_GPIO1:
1339 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301340 if (!gpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001341 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301342 if (!gpio_num_info->valid
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001343 [power_setting->seq_val])
1344 continue;
1345 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301346 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001347 [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
1348 break;
1349 case SENSOR_VANA:
1350 case SENSOR_VDIG:
1351 case SENSOR_VIO:
1352 case SENSOR_VAF:
1353 case SENSOR_VAF_PWDM:
1354 case SENSOR_CUSTOM_REG1:
1355 case SENSOR_CUSTOM_REG2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301356 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001357 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301358 vreg_idx = power_setting->seq_val;
1359
1360 rc = cam_soc_util_regulator_disable(
1361 soc_info->rgltr[vreg_idx],
1362 soc_info->rgltr_name[vreg_idx],
1363 soc_info->rgltr_min_volt[vreg_idx],
1364 soc_info->rgltr_max_volt[vreg_idx],
1365 soc_info->rgltr_op_mode[vreg_idx],
1366 soc_info->rgltr_delay[vreg_idx]);
1367
1368 power_setting->data[0] =
1369 soc_info->rgltr[vreg_idx];
1370
1371 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001372 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001373 CAM_ERR(CAM_SENSOR, "seq_val:%d > num_vreg: %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301374 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001375
1376 msm_cam_sensor_handle_reg_gpio(power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301377 gpio_num_info, GPIOF_OUT_INIT_LOW);
1378
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001379 break;
1380 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001381 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1382 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001383 break;
1384 }
1385 if (power_setting->delay > 20) {
1386 msleep(power_setting->delay);
1387 } else if (power_setting->delay) {
1388 usleep_range(power_setting->delay * 1000,
1389 (power_setting->delay * 1000) + 1000);
1390 }
1391 }
1392 if (ctrl->cam_pinctrl_status) {
1393 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1394 ctrl->pinctrl_info.gpio_state_suspend);
1395 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001396 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001397 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1398 }
1399 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301400
1401 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001402
1403 return rc;
1404}
1405
1406static struct cam_sensor_power_setting*
1407msm_camera_get_power_settings(struct cam_sensor_power_ctrl_t *ctrl,
1408 enum msm_camera_power_seq_type seq_type,
1409 uint16_t seq_val)
1410{
1411 struct cam_sensor_power_setting *power_setting, *ps = NULL;
1412 int idx;
1413
1414 for (idx = 0; idx < ctrl->power_setting_size; idx++) {
1415 power_setting = &ctrl->power_setting[idx];
1416 if (power_setting->seq_type == seq_type &&
1417 power_setting->seq_val == seq_val) {
1418 ps = power_setting;
1419 return ps;
1420 }
1421
1422 }
1423
1424 return ps;
1425}
1426
1427static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
Alok Pandey01b1b352017-06-25 20:38:54 +05301428 struct cam_hw_soc_info *soc_info, int32_t index)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001429{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001430 int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
1431 struct cam_sensor_power_setting *ps = NULL;
1432 struct cam_sensor_power_setting *pd = NULL;
1433
Alok Pandey01b1b352017-06-25 20:38:54 +05301434 num_vreg = soc_info->num_rgltr;
1435
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001436 pd = &ctrl->power_down_setting[index];
1437
1438 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301439 if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001440
1441 ps = NULL;
1442 for (idx = 0; idx <
1443 ctrl->power_setting_size; idx++) {
1444 if (ctrl->power_setting[idx].
1445 seq_type == pd->seq_type) {
1446 ps = &ctrl->power_setting[idx];
1447 break;
1448 }
1449 }
1450
Alok Pandey01b1b352017-06-25 20:38:54 +05301451 if (ps != NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001452 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301453
1454 rc = cam_soc_util_regulator_disable(
1455 soc_info->rgltr[j],
1456 soc_info->rgltr_name[j],
1457 soc_info->rgltr_min_volt[j],
1458 soc_info->rgltr_max_volt[j],
1459 soc_info->rgltr_op_mode[j],
1460 soc_info->rgltr_delay[j]);
1461
1462 ps->data[0] =
1463 soc_info->rgltr[j];
1464 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001465 }
1466 }
1467
1468 return rc;
1469}
1470
Alok Pandey01b1b352017-06-25 20:38:54 +05301471int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
1472 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001473{
Alok Pandey01b1b352017-06-25 20:38:54 +05301474 int index = 0, ret = 0, num_vreg = 0, i;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001475 struct cam_sensor_power_setting *pd = NULL;
1476 struct cam_sensor_power_setting *ps;
Alok Pandey01b1b352017-06-25 20:38:54 +05301477 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001478
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001479 CAM_DBG(CAM_SENSOR, "Enter");
Alok Pandey01b1b352017-06-25 20:38:54 +05301480 if (!ctrl || !soc_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001481 CAM_ERR(CAM_SENSOR, "failed ctrl %pK", ctrl);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001482 return -EINVAL;
1483 }
1484
Alok Pandey01b1b352017-06-25 20:38:54 +05301485 gpio_num_info = ctrl->gpio_num_info;
1486 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001487
1488 for (index = 0; index < ctrl->power_down_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001489 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001490 pd = &ctrl->power_down_setting[index];
1491 ps = NULL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001492 CAM_DBG(CAM_SENSOR, "type %d", pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001493 switch (pd->seq_type) {
1494 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301495 ret = cam_config_mclk_reg(ctrl, soc_info, index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001496 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001497 CAM_ERR(CAM_SENSOR,
1498 "config clk reg failed rc: %d", ret);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001499 return ret;
1500 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301501 //cam_soc_util_clk_disable_default(soc_info);
1502 for (i = soc_info->num_clk - 1; i >= 0; i--) {
1503 cam_soc_util_clk_disable(soc_info->clk[i],
1504 soc_info->clk_name[i]);
1505 }
1506
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001507 break;
1508 case SENSOR_RESET:
1509 case SENSOR_STANDBY:
1510 case SENSOR_CUSTOM_GPIO1:
1511 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301512
1513 if (!gpio_num_info->valid[pd->seq_val])
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001514 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301515
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001516 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301517 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001518 [pd->seq_val],
1519 (int) pd->config_val);
Alok Pandey01b1b352017-06-25 20:38:54 +05301520
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001521 break;
1522 case SENSOR_VANA:
1523 case SENSOR_VDIG:
1524 case SENSOR_VIO:
1525 case SENSOR_VAF:
1526 case SENSOR_VAF_PWDM:
1527 case SENSOR_CUSTOM_REG1:
1528 case SENSOR_CUSTOM_REG2:
1529 if (pd->seq_val == INVALID_VREG)
1530 break;
Alok Pandey01b1b352017-06-25 20:38:54 +05301531
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001532 ps = msm_camera_get_power_settings(
1533 ctrl, pd->seq_type,
1534 pd->seq_val);
1535 if (ps) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301536 if (pd->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001537 CAM_DBG(CAM_SENSOR,
1538 "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301539 ret = cam_soc_util_regulator_disable(
1540 soc_info->rgltr[ps->seq_val],
1541 soc_info->rgltr_name[ps->seq_val],
1542 soc_info->rgltr_min_volt[ps->seq_val],
1543 soc_info->rgltr_max_volt[ps->seq_val],
1544 soc_info->rgltr_op_mode[ps->seq_val],
1545 soc_info->rgltr_delay[ps->seq_val]);
1546
1547 ps->data[0] =
1548 soc_info->rgltr[ps->seq_val];
1549 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001550 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001551 CAM_ERR(CAM_SENSOR,
1552 "seq_val:%d > num_vreg: %d",
1553 pd->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301554 num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001555 } else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001556 CAM_ERR(CAM_SENSOR,
1557 "error in power up/down seq");
Alok Pandey01b1b352017-06-25 20:38:54 +05301558
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001559 ret = msm_cam_sensor_handle_reg_gpio(pd->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301560 gpio_num_info, GPIOF_OUT_INIT_LOW);
1561
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001562 if (ret < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001563 CAM_ERR(CAM_SENSOR,
1564 "Error disabling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001565 break;
1566 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001567 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1568 pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001569 break;
1570 }
1571 if (pd->delay > 20)
1572 msleep(pd->delay);
1573 else if (pd->delay)
1574 usleep_range(pd->delay * 1000,
1575 (pd->delay * 1000) + 1000);
1576 }
1577
1578 if (ctrl->cam_pinctrl_status) {
1579 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1580 ctrl->pinctrl_info.gpio_state_suspend);
1581 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001582 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001583 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1584 }
1585
1586 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301587
1588 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001589
1590 return 0;
1591}
1592