blob: 06590e4422f1c992b5b789f978661e4d202c9396 [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++) {
343 switch (power_setting[i].seq_type) {
344 case SENSOR_VDIG:
345 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530346 if (!strcmp(soc_info->rgltr_name[j],
347 "cam_vdig")) {
348
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700349 CAM_DBG(CAM_SENSOR,
350 "i: %d j: %d cam_vdig", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700351 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530352
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700353 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530354 soc_info->rgltr_min_volt[j],
355 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700356 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530357 soc_info->rgltr_min_volt[j] =
358 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700359 power_setting[i].config_val;
360 }
361 break;
362 }
363 }
364 if (j == num_vreg)
365 power_setting[i].seq_val = INVALID_VREG;
366 break;
367
368 case SENSOR_VIO:
369 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530370
371 if (!strcmp(soc_info->rgltr_name[j],
372 "cam_vio")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700373 CAM_DBG(CAM_SENSOR,
374 "i: %d j: %d cam_vio", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700375 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530376
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700377 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530378 soc_info->rgltr_min_volt[j],
379 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700380 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530381 soc_info->rgltr_min_volt[j] =
382 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700383 power_setting[i].config_val;
384 }
385 break;
386 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530387
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700388 }
389 if (j == num_vreg)
390 power_setting[i].seq_val = INVALID_VREG;
391 break;
392
393 case SENSOR_VANA:
394 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530395
396 if (!strcmp(soc_info->rgltr_name[j],
397 "cam_vana")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700398 CAM_DBG(CAM_SENSOR,
399 "i: %d j: %d cam_vana", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700400 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530401
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700402 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530403 soc_info->rgltr_min_volt[j],
404 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700405 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530406 soc_info->rgltr_min_volt[j] =
407 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700408 power_setting[i].config_val;
409 }
410 break;
411 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530412
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700413 }
414 if (j == num_vreg)
415 power_setting[i].seq_val = INVALID_VREG;
416 break;
417
418 case SENSOR_VAF:
419 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530420
421 if (!strcmp(soc_info->rgltr_name[j],
422 "cam_vaf")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700423 CAM_DBG(CAM_SENSOR,
424 "i: %d j: %d cam_vaf", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700425 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530426
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700427 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530428 soc_info->rgltr_min_volt[j],
429 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700430 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530431 soc_info->rgltr_min_volt[j] =
432 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700433 power_setting[i].config_val;
434 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530435
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700436 break;
437 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530438
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700439 }
440 if (j == num_vreg)
441 power_setting[i].seq_val = INVALID_VREG;
442 break;
443
444 case SENSOR_CUSTOM_REG1:
445 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530446
447 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700448 "cam_v_custom1")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700449 CAM_DBG(CAM_SENSOR,
450 "i:%d j:%d cam_vcustom1", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700451 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530452
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700453 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530454 soc_info->rgltr_min_volt[j],
455 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700456 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530457 soc_info->rgltr_min_volt[j] =
458 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700459 power_setting[i].config_val;
460 }
461 break;
462 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530463
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700464 }
465 if (j == num_vreg)
466 power_setting[i].seq_val = INVALID_VREG;
467 break;
468 case SENSOR_CUSTOM_REG2:
469 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530470
471 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700472 "cam_v_custom2")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700473 CAM_DBG(CAM_SENSOR,
474 "i:%d j:%d cam_vcustom2", i, j);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700475 power_setting[i].seq_val = j;
Alok Pandey01b1b352017-06-25 20:38:54 +0530476
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700477 if (VALIDATE_VOLTAGE(
Alok Pandey01b1b352017-06-25 20:38:54 +0530478 soc_info->rgltr_min_volt[j],
479 soc_info->rgltr_max_volt[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700480 power_setting[i].config_val)) {
Alok Pandey01b1b352017-06-25 20:38:54 +0530481 soc_info->rgltr_min_volt[j] =
482 soc_info->rgltr_max_volt[j] =
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700483 power_setting[i].config_val;
484 }
485 break;
486 }
487 }
488 if (j == num_vreg)
489 power_setting[i].seq_val = INVALID_VREG;
490 break;
491
492 default: {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700493 CAM_ERR(CAM_SENSOR, "invalid seq_val %d",
494 power_setting[i].seq_val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700495 break;
496 }
497 }
498 }
499
500 return rc;
501}
502
Alok Pandey01b1b352017-06-25 20:38:54 +0530503int cam_sensor_util_request_gpio_table(
504 struct cam_hw_soc_info *soc_info, int gpio_en)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700505{
Alok Pandey01b1b352017-06-25 20:38:54 +0530506 int rc = 0, i = 0;
507 uint8_t size = 0;
508 struct cam_soc_gpio_data *gpio_conf =
509 soc_info->gpio_data;
510 struct gpio *gpio_tbl = gpio_conf->cam_gpio_req_tbl;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700511
Alok Pandey01b1b352017-06-25 20:38:54 +0530512 size = gpio_conf->cam_gpio_req_tbl_size;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700513
Alok Pandey01b1b352017-06-25 20:38:54 +0530514 if (gpio_conf->cam_gpio_common_tbl_size <= 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700515 CAM_INFO(CAM_SENSOR, "No GPIO entry");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700516 return 0;
517 }
518
Alok Pandey01b1b352017-06-25 20:38:54 +0530519 if (!gpio_tbl || !size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700520 CAM_ERR(CAM_SENSOR, "invalid gpio_tbl %pK / size %d",
521 gpio_tbl, size);
Alok Pandey01b1b352017-06-25 20:38:54 +0530522 return -EINVAL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700523 }
524
Alok Pandey01b1b352017-06-25 20:38:54 +0530525 for (i = 0; i < size; i++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700526 CAM_DBG(CAM_SENSOR, "i: %d, gpio %d dir %ld", i,
527 gpio_tbl[i].gpio, gpio_tbl[i].flags);
Alok Pandey01b1b352017-06-25 20:38:54 +0530528 }
529
530 if (gpio_en) {
531 for (i = 0; i < size; i++) {
532 rc = gpio_request_one(gpio_tbl[i].gpio,
533 gpio_tbl[i].flags, gpio_tbl[i].label);
534 if (rc) {
535 /*
536 * After GPIO request fails, contine to
537 * apply new gpios, outout a error message
538 * for driver bringup debug
539 */
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700540 CAM_ERR(CAM_SENSOR, "gpio %d:%s request fails",
Alok Pandey01b1b352017-06-25 20:38:54 +0530541 gpio_tbl[i].gpio, gpio_tbl[i].label);
542 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700543 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530544 } else {
545 gpio_free_array(gpio_tbl, size);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700546 }
547
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700548 return rc;
549}
550
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530551int32_t cam_sensor_update_power_settings(void *cmd_buf,
552 int cmd_length, struct cam_sensor_power_ctrl_t *power_info)
553{
554 int32_t rc = 0, tot_size = 0, last_cmd_type = 0;
555 int32_t i = 0, pwr_up = 0, pwr_down = 0;
556 void *ptr = cmd_buf, *scr;
557 struct cam_cmd_power *pwr_cmd = (struct cam_cmd_power *)cmd_buf;
558 struct common_header *cmm_hdr = (struct common_header *)cmd_buf;
559
560 if (!pwr_cmd || !cmd_length) {
561 CAM_ERR(CAM_SENSOR, "Invalid Args: pwr_cmd %pK, cmd_length: %d",
562 pwr_cmd, cmd_length);
563 return -EINVAL;
564 }
565
566 power_info->power_setting_size = 0;
567 power_info->power_setting =
568 (struct cam_sensor_power_setting *)
569 kzalloc(sizeof(struct cam_sensor_power_setting) *
570 MAX_POWER_CONFIG, GFP_KERNEL);
571 if (!power_info->power_setting)
572 return -ENOMEM;
573
Soundrapandian Jeyaprakash687b32e2017-07-28 14:38:56 -0700574 power_info->power_down_setting_size = 0;
Vivek Veenam2ad8de12017-04-04 18:56:22 +0530575 power_info->power_down_setting =
576 (struct cam_sensor_power_setting *)
577 kzalloc(sizeof(struct cam_sensor_power_setting) *
578 MAX_POWER_CONFIG, GFP_KERNEL);
579 if (!power_info->power_down_setting) {
580 rc = -ENOMEM;
581 goto free_power_settings;
582 }
583
584 while (tot_size < cmd_length) {
585 if (cmm_hdr->cmd_type ==
586 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
587 struct cam_cmd_power *pwr_cmd =
588 (struct cam_cmd_power *)ptr;
589
590 power_info->
591 power_setting_size +=
592 pwr_cmd->count;
593 scr = ptr + sizeof(struct cam_cmd_power);
594 tot_size = tot_size + sizeof(struct cam_cmd_power);
595
596 if (pwr_cmd->count == 0)
597 CAM_DBG(CAM_SENSOR, "Un expected Command");
598
599 for (i = 0; i < pwr_cmd->count; i++, pwr_up++) {
600 power_info->
601 power_setting[pwr_up].seq_type =
602 pwr_cmd->power_settings[i].
603 power_seq_type;
604 power_info->
605 power_setting[pwr_up].config_val =
606 pwr_cmd->power_settings[i].
607 config_val_low;
608 power_info->power_setting[pwr_up].delay = 0;
609 if (i) {
610 scr = scr +
611 sizeof(
612 struct cam_power_settings);
613 tot_size = tot_size +
614 sizeof(
615 struct cam_power_settings);
616 }
617 if (tot_size > cmd_length) {
618 CAM_ERR(CAM_SENSOR,
619 "Error: Cmd Buffer is wrong");
620 rc = -EINVAL;
621 goto free_power_down_settings;
622 }
623 CAM_DBG(CAM_SENSOR,
624 "Seq Type[%d]: %d Config_val: %ld",
625 pwr_up,
626 power_info->
627 power_setting[pwr_up].seq_type,
628 power_info->
629 power_setting[pwr_up].
630 config_val);
631 }
632 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_UP;
633 ptr = (void *) scr;
634 cmm_hdr = (struct common_header *)ptr;
635 } else if (cmm_hdr->cmd_type == CAMERA_SENSOR_CMD_TYPE_WAIT) {
636 struct cam_cmd_unconditional_wait *wait_cmd =
637 (struct cam_cmd_unconditional_wait *)ptr;
638 if (wait_cmd->op_code ==
639 CAMERA_SENSOR_WAIT_OP_SW_UCND) {
640 if (last_cmd_type ==
641 CAMERA_SENSOR_CMD_TYPE_PWR_UP) {
642 if (pwr_up > 0)
643 power_info->
644 power_setting
645 [pwr_up - 1].delay +=
646 wait_cmd->delay;
647 else
648 CAM_ERR(CAM_SENSOR,
649 "Delay is expected only after valid power up setting");
650 } else if (last_cmd_type ==
651 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
652 if (pwr_down > 0)
653 power_info->
654 power_down_setting
655 [pwr_down - 1].delay +=
656 wait_cmd->delay;
657 else
658 CAM_ERR(CAM_SENSOR,
659 "Delay is expected only after valid power up setting");
660 }
661 } else
662 CAM_DBG(CAM_SENSOR, "Invalid op code: %d",
663 wait_cmd->op_code);
664 tot_size = tot_size +
665 sizeof(struct cam_cmd_unconditional_wait);
666 if (tot_size > cmd_length) {
667 CAM_ERR(CAM_SENSOR, "Command Buffer is wrong");
668 return -EINVAL;
669 }
670 scr = (void *) (wait_cmd);
671 ptr = (void *)
672 (scr +
673 sizeof(struct cam_cmd_unconditional_wait));
674 CAM_DBG(CAM_SENSOR, "ptr: %pK sizeof: %d Next: %pK",
675 scr, (int32_t)sizeof(
676 struct cam_cmd_unconditional_wait), ptr);
677
678 cmm_hdr = (struct common_header *)ptr;
679 } else if (cmm_hdr->cmd_type ==
680 CAMERA_SENSOR_CMD_TYPE_PWR_DOWN) {
681 struct cam_cmd_power *pwr_cmd =
682 (struct cam_cmd_power *)ptr;
683
684 scr = ptr + sizeof(struct cam_cmd_power);
685 tot_size = tot_size + sizeof(struct cam_cmd_power);
686 power_info->power_down_setting_size += pwr_cmd->count;
687
688 if (pwr_cmd->count == 0)
689 CAM_ERR(CAM_SENSOR, "Invalid Command");
690
691 for (i = 0; i < pwr_cmd->count; i++, pwr_down++) {
692 power_info->
693 power_down_setting[pwr_down].
694 seq_type =
695 pwr_cmd->power_settings[i].
696 power_seq_type;
697 power_info->
698 power_down_setting[pwr_down].
699 config_val =
700 pwr_cmd->power_settings[i].
701 config_val_low;
702 power_info->
703 power_down_setting[pwr_down].delay = 0;
704 if (i) {
705 scr = scr +
706 sizeof(
707 struct cam_power_settings);
708 tot_size =
709 tot_size +
710 sizeof(
711 struct cam_power_settings);
712 }
713 if (tot_size > cmd_length) {
714 CAM_ERR(CAM_SENSOR,
715 "Command Buffer is wrong");
716 rc = -EINVAL;
717 goto free_power_down_settings;
718 }
719 CAM_DBG(CAM_SENSOR,
720 "Seq Type[%d]: %d Config_val: %ld",
721 pwr_down,
722 power_info->
723 power_down_setting[pwr_down].
724 seq_type,
725 power_info->
726 power_down_setting[pwr_down].
727 config_val);
728 }
729 last_cmd_type = CAMERA_SENSOR_CMD_TYPE_PWR_DOWN;
730 ptr = (void *) scr;
731 cmm_hdr = (struct common_header *)ptr;
732 } else {
733 CAM_ERR(CAM_SENSOR,
734 "Error: Un expected Header Type: %d",
735 cmm_hdr->cmd_type);
736 }
737 }
738
739 return rc;
740free_power_down_settings:
741 kfree(power_info->power_down_setting);
742free_power_settings:
743 kfree(power_info->power_setting);
744 return rc;
745}
746
747int cam_get_dt_power_setting_data(struct device_node *of_node,
748 struct cam_hw_soc_info *soc_info,
749 struct cam_sensor_power_ctrl_t *power_info)
750{
751 int rc = 0, i;
752 int count = 0;
753 const char *seq_name = NULL;
754 uint32_t *array = NULL;
755 struct cam_sensor_power_setting *ps;
756 int c, end;
757
758 if (!power_info)
759 return -EINVAL;
760
761 count = of_property_count_strings(of_node, "qcom,cam-power-seq-type");
762 power_info->power_setting_size = count;
763
764 CAM_DBG(CAM_SENSOR, "qcom,cam-power-seq-type count %d", count);
765
766 if (count <= 0)
767 return 0;
768
769 ps = kcalloc(count, sizeof(*ps), GFP_KERNEL);
770 if (!ps)
771 return -ENOMEM;
772 power_info->power_setting = ps;
773
774 for (i = 0; i < count; i++) {
775 rc = of_property_read_string_index(of_node,
776 "qcom,cam-power-seq-type", i, &seq_name);
777 if (rc < 0) {
778 CAM_ERR(CAM_SENSOR, "failed");
779 goto ERROR1;
780 }
781 CAM_DBG(CAM_SENSOR, "seq_name[%d] = %s", i, seq_name);
782 if (!strcmp(seq_name, "cam_vio")) {
783 ps[i].seq_type = SENSOR_VIO;
784 } else if (!strcmp(seq_name, "cam_vana")) {
785 ps[i].seq_type = SENSOR_VANA;
786 } else if (!strcmp(seq_name, "cam_clk")) {
787 ps[i].seq_type = SENSOR_MCLK;
788 } else {
789 CAM_ERR(CAM_SENSOR, "unrecognized seq-type %s",
790 seq_name);
791 rc = -EILSEQ;
792 goto ERROR1;
793 }
794 CAM_DBG(CAM_SENSOR, "seq_type[%d] %d", i, ps[i].seq_type);
795 }
796
797 array = kcalloc(count, sizeof(uint32_t), GFP_KERNEL);
798 if (!array) {
799 rc = -ENOMEM;
800 goto ERROR1;
801 }
802
803 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val",
804 array, count);
805 if (rc < 0) {
806 CAM_ERR(CAM_SENSOR, "failed ");
807 goto ERROR2;
808 }
809
810 for (i = 0; i < count; i++) {
811 ps[i].config_val = array[i];
812 CAM_DBG(CAM_SENSOR, "power_setting[%d].config_val = %ld", i,
813 ps[i].config_val);
814 }
815
816 rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay",
817 array, count);
818 if (rc < 0) {
819 CAM_ERR(CAM_SENSOR, "failed");
820 goto ERROR2;
821 }
822 for (i = 0; i < count; i++) {
823 ps[i].delay = array[i];
824 CAM_DBG(CAM_SENSOR, "power_setting[%d].delay = %d", i,
825 ps[i].delay);
826 }
827 kfree(array);
828
829 power_info->power_down_setting =
830 kzalloc(sizeof(*ps) * count, GFP_KERNEL);
831
832 if (!power_info->power_down_setting) {
833 CAM_ERR(CAM_SENSOR, "failed");
834 rc = -ENOMEM;
835 goto ERROR1;
836 }
837
838 power_info->power_down_setting_size = count;
839
840 end = count - 1;
841
842 for (c = 0; c < count; c++) {
843 power_info->power_down_setting[c] = ps[end];
844 end--;
845 }
846 return rc;
847ERROR2:
848 kfree(array);
849ERROR1:
850 kfree(ps);
851 return rc;
852}
Alok Pandey01b1b352017-06-25 20:38:54 +0530853
854int cam_sensor_util_init_gpio_pin_tbl(
855 struct cam_hw_soc_info *soc_info,
856 struct msm_camera_gpio_num_info **pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700857{
858 int rc = 0, val = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +0530859 uint32_t gpio_array_size;
860 struct platform_device *pdev = NULL;
861 struct device_node *of_node = NULL;
862 struct cam_soc_gpio_data *gconf = NULL;
863 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700864
Alok Pandey01b1b352017-06-25 20:38:54 +0530865 pdev = soc_info->pdev;
866 of_node = pdev->dev.of_node;
867
868 gconf = soc_info->gpio_data;
869 if (!gconf) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700870 CAM_ERR(CAM_SENSOR, "No gpio_common_table is found");
Alok Pandey01b1b352017-06-25 20:38:54 +0530871 return -EINVAL;
872 }
873
874 if (!gconf->cam_gpio_common_tbl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700875 CAM_ERR(CAM_SENSOR, "gpio_common_table is not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +0530876 return -EINVAL;
877 }
878
879 gpio_array_size = gconf->cam_gpio_common_tbl_size;
880
881 if (!gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700882 CAM_ERR(CAM_SENSOR, "invalid size of gpio table");
Alok Pandey01b1b352017-06-25 20:38:54 +0530883 return -EINVAL;
884 }
885
886 *pgpio_num_info = kzalloc(sizeof(struct msm_camera_gpio_num_info),
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700887 GFP_KERNEL);
Alok Pandey01b1b352017-06-25 20:38:54 +0530888 if (!*pgpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700889 return -ENOMEM;
Alok Pandey01b1b352017-06-25 20:38:54 +0530890 gpio_num_info = *pgpio_num_info;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700891
Alok Pandey01b1b352017-06-25 20:38:54 +0530892 rc = of_property_read_u32(of_node, "gpio-vana", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700893 if (rc != -EINVAL) {
894 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700895 CAM_ERR(CAM_SENSOR, "read gpio-vana failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700896 goto free_gpio_info;
897 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700898 CAM_ERR(CAM_SENSOR, "gpio-vana invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700899 rc = -EINVAL;
900 goto free_gpio_info;
901 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530902 gpio_num_info->gpio_num[SENSOR_VANA] =
903 gconf->cam_gpio_common_tbl[val].gpio;
904 gpio_num_info->valid[SENSOR_VANA] = 1;
905
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700906 CAM_DBG(CAM_SENSOR, "%s:%d gpio-vana %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530907 gpio_num_info->gpio_num[SENSOR_VANA]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700908 }
909
Alok Pandey01b1b352017-06-25 20:38:54 +0530910 rc = of_property_read_u32(of_node, "gpio-vio", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700911 if (rc != -EINVAL) {
912 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700913 CAM_ERR(CAM_SENSOR, "read gpio-vio failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700914 goto free_gpio_info;
915 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700916 CAM_ERR(CAM_SENSOR, "gpio-vio invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700917 goto free_gpio_info;
918 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530919 gpio_num_info->gpio_num[SENSOR_VIO] =
920 gconf->cam_gpio_common_tbl[val].gpio;
921 gpio_num_info->valid[SENSOR_VIO] = 1;
922
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700923 CAM_DBG(CAM_SENSOR, "gpio-vio %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530924 gpio_num_info->gpio_num[SENSOR_VIO]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700925 }
926
Alok Pandey01b1b352017-06-25 20:38:54 +0530927 rc = of_property_read_u32(of_node, "gpio-vaf", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700928 if (rc != -EINVAL) {
929 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700930 CAM_ERR(CAM_SENSOR, "read gpio-vaf failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700931 goto free_gpio_info;
932 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700933 CAM_ERR(CAM_SENSOR, "gpio-vaf invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700934 rc = -EINVAL;
935 goto free_gpio_info;
936 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530937 gpio_num_info->gpio_num[SENSOR_VAF] =
938 gconf->cam_gpio_common_tbl[val].gpio;
939 gpio_num_info->valid[SENSOR_VAF] = 1;
940
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700941 CAM_DBG(CAM_SENSOR, "gpio-vaf %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530942 gpio_num_info->gpio_num[SENSOR_VAF]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700943 }
944
Alok Pandey01b1b352017-06-25 20:38:54 +0530945 rc = of_property_read_u32(of_node, "gpio-vdig", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700946 if (rc != -EINVAL) {
947 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700948 CAM_ERR(CAM_SENSOR, "read gpio-vdig failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700949 goto free_gpio_info;
950 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700951 CAM_ERR(CAM_SENSOR, "gpio-vdig invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700952 rc = -EINVAL;
953 goto free_gpio_info;
954 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530955 gpio_num_info->gpio_num[SENSOR_VDIG] =
956 gconf->cam_gpio_common_tbl[val].gpio;
957 gpio_num_info->valid[SENSOR_VDIG] = 1;
958
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700959 CAM_DBG(CAM_SENSOR, "gpio-vdig %d",
960 gpio_num_info->gpio_num[SENSOR_VDIG]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700961 }
962
Alok Pandey01b1b352017-06-25 20:38:54 +0530963 rc = of_property_read_u32(of_node, "gpio-reset", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700964 if (rc != -EINVAL) {
965 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700966 CAM_ERR(CAM_SENSOR, "read gpio-reset failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700967 goto free_gpio_info;
968 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700969 CAM_ERR(CAM_SENSOR, "gpio-reset invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700970 rc = -EINVAL;
971 goto free_gpio_info;
972 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530973 gpio_num_info->gpio_num[SENSOR_RESET] =
974 gconf->cam_gpio_common_tbl[val].gpio;
975 gpio_num_info->valid[SENSOR_RESET] = 1;
976
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700977 CAM_DBG(CAM_SENSOR, "gpio-reset %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530978 gpio_num_info->gpio_num[SENSOR_RESET]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700979 }
980
Alok Pandey01b1b352017-06-25 20:38:54 +0530981 rc = of_property_read_u32(of_node, "gpio-standby", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700982 if (rc != -EINVAL) {
983 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700984 CAM_ERR(CAM_SENSOR,
985 "read gpio-standby failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700986 goto free_gpio_info;
987 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700988 CAM_ERR(CAM_SENSOR, "gpio-standby invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700989 rc = -EINVAL;
990 goto free_gpio_info;
991 }
Alok Pandey01b1b352017-06-25 20:38:54 +0530992 gpio_num_info->gpio_num[SENSOR_STANDBY] =
993 gconf->cam_gpio_common_tbl[val].gpio;
994 gpio_num_info->valid[SENSOR_STANDBY] = 1;
995
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -0700996 CAM_DBG(CAM_SENSOR, "gpio-standby %d",
Alok Pandey01b1b352017-06-25 20:38:54 +0530997 gpio_num_info->gpio_num[SENSOR_STANDBY]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -0700998 }
999
Alok Pandey01b1b352017-06-25 20:38:54 +05301000 rc = of_property_read_u32(of_node, "gpio-af-pwdm", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001001 if (rc != -EINVAL) {
1002 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001003 CAM_ERR(CAM_SENSOR,
1004 "read gpio-af-pwdm failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001005 goto free_gpio_info;
1006 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001007 CAM_ERR(CAM_SENSOR, "gpio-af-pwdm invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001008 rc = -EINVAL;
1009 goto free_gpio_info;
1010 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301011 gpio_num_info->gpio_num[SENSOR_VAF_PWDM] =
1012 gconf->cam_gpio_common_tbl[val].gpio;
1013 gpio_num_info->valid[SENSOR_VAF_PWDM] = 1;
1014
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001015 CAM_DBG(CAM_SENSOR, "gpio-af-pwdm %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301016 gpio_num_info->gpio_num[SENSOR_VAF_PWDM]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001017 }
1018
Alok Pandey01b1b352017-06-25 20:38:54 +05301019 rc = of_property_read_u32(of_node, "gpio-custom1", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001020 if (rc != -EINVAL) {
1021 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001022 CAM_ERR(CAM_SENSOR,
1023 "read gpio-custom1 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001024 goto free_gpio_info;
1025 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001026 CAM_ERR(CAM_SENSOR, "gpio-custom1 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001027 rc = -EINVAL;
1028 goto free_gpio_info;
1029 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301030 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1] =
1031 gconf->cam_gpio_common_tbl[val].gpio;
1032 gpio_num_info->valid[SENSOR_CUSTOM_GPIO1] = 1;
1033
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001034 CAM_DBG(CAM_SENSOR, "gpio-custom1 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301035 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO1]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001036 }
1037
Alok Pandey01b1b352017-06-25 20:38:54 +05301038 rc = of_property_read_u32(of_node, "gpio-custom2", &val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001039 if (rc != -EINVAL) {
1040 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001041 CAM_ERR(CAM_SENSOR,
1042 "read gpio-custom2 failed rc %d", rc);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001043 goto free_gpio_info;
1044 } else if (val >= gpio_array_size) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001045 CAM_ERR(CAM_SENSOR, "gpio-custom2 invalid %d", val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001046 rc = -EINVAL;
1047 goto free_gpio_info;
1048 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301049 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2] =
1050 gconf->cam_gpio_common_tbl[val].gpio;
1051 gpio_num_info->valid[SENSOR_CUSTOM_GPIO2] = 1;
1052
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001053 CAM_DBG(CAM_SENSOR, "gpio-custom2 %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301054 gpio_num_info->gpio_num[SENSOR_CUSTOM_GPIO2]);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001055 } else {
1056 rc = 0;
1057 }
1058
1059 return rc;
1060
1061free_gpio_info:
Alok Pandey01b1b352017-06-25 20:38:54 +05301062 kfree(gpio_num_info);
1063 gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001064 return rc;
1065}
1066
1067int msm_camera_pinctrl_init(
1068 struct msm_pinctrl_info *sensor_pctrl, struct device *dev) {
1069
1070 sensor_pctrl->pinctrl = devm_pinctrl_get(dev);
1071 if (IS_ERR_OR_NULL(sensor_pctrl->pinctrl)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001072 CAM_ERR(CAM_SENSOR, "Getting pinctrl handle failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001073 return -EINVAL;
1074 }
1075 sensor_pctrl->gpio_state_active =
1076 pinctrl_lookup_state(sensor_pctrl->pinctrl,
1077 CAM_SENSOR_PINCTRL_STATE_DEFAULT);
1078 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_active)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001079 CAM_ERR(CAM_SENSOR,
1080 "Failed to get the active state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001081 return -EINVAL;
1082 }
1083 sensor_pctrl->gpio_state_suspend
1084 = pinctrl_lookup_state(sensor_pctrl->pinctrl,
1085 CAM_SENSOR_PINCTRL_STATE_SLEEP);
1086 if (IS_ERR_OR_NULL(sensor_pctrl->gpio_state_suspend)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001087 CAM_ERR(CAM_SENSOR,
1088 "Failed to get the suspend state pinctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001089 return -EINVAL;
1090 }
1091 return 0;
1092}
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001093int msm_cam_sensor_handle_reg_gpio(int seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301094 struct msm_camera_gpio_num_info *gpio_num_info, int val)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001095{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001096 int gpio_offset = -1;
1097
Alok Pandey01b1b352017-06-25 20:38:54 +05301098 if (!gpio_num_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001099 CAM_ERR(CAM_SENSOR, "Input Parameters are not proper");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001100 return -EINVAL;
1101 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301102
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001103 CAM_DBG(CAM_SENSOR, "Seq type: %d, config: %d", seq_type, val);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001104
1105 gpio_offset = seq_type;
1106
Alok Pandey01b1b352017-06-25 20:38:54 +05301107 if (gpio_num_info->valid[gpio_offset] == 1) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001108 CAM_DBG(CAM_SENSOR, "VALID GPIO offset: %d, seqtype: %d",
1109 gpio_offset, seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001110 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301111 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001112 [gpio_offset], val);
1113 }
1114
1115 return 0;
1116}
1117
Alok Pandey01b1b352017-06-25 20:38:54 +05301118int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
1119 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001120{
1121 int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301122 int32_t vreg_idx = -1;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001123 struct cam_sensor_power_setting *power_setting = NULL;
Alok Pandey01b1b352017-06-25 20:38:54 +05301124 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001125
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001126 CAM_DBG(CAM_SENSOR, "Enter");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001127 if (!ctrl) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001128 CAM_ERR(CAM_SENSOR, "Invalid ctrl handle");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001129 return -EINVAL;
1130 }
1131
Alok Pandey01b1b352017-06-25 20:38:54 +05301132 gpio_num_info = ctrl->gpio_num_info;
1133 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001134
Alok Pandey01b1b352017-06-25 20:38:54 +05301135 if ((num_vreg == 0) || (num_vreg > CAM_SOC_MAX_REGULATOR)) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001136 CAM_ERR(CAM_SENSOR, "Regulators are not initialized");
Alok Pandey01b1b352017-06-25 20:38:54 +05301137 return -EINVAL;
1138 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001139
1140 ret = msm_camera_pinctrl_init(&(ctrl->pinctrl_info), ctrl->dev);
1141 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001142 CAM_ERR(CAM_SENSOR, "Initialization of pinctrl failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001143 ctrl->cam_pinctrl_status = 0;
1144 } else {
1145 ctrl->cam_pinctrl_status = 1;
1146 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301147
1148 rc = cam_sensor_util_request_gpio_table(soc_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001149 if (rc < 0)
1150 no_gpio = rc;
Alok Pandey01b1b352017-06-25 20:38:54 +05301151
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001152 if (ctrl->cam_pinctrl_status) {
1153 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1154 ctrl->pinctrl_info.gpio_state_active);
1155 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001156 CAM_ERR(CAM_SENSOR, "cannot set pin to active state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001157 }
1158
1159 for (index = 0; index < ctrl->power_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001160 CAM_DBG(CAM_SENSOR, "index: %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001161 power_setting = &ctrl->power_setting[index];
Vivek Veenam2ad8de12017-04-04 18:56:22 +05301162 CAM_DBG(CAM_SENSOR, "seq_type %d", power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001163
1164 switch (power_setting->seq_type) {
1165 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301166 if (power_setting->seq_val >= soc_info->num_clk) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001167 CAM_ERR(CAM_SENSOR, "clk index %d >= max %u",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001168 power_setting->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301169 soc_info->num_clk);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001170 goto power_up_failed;
1171 }
1172 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301173 if (!strcmp(soc_info->rgltr_name[j],
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001174 "cam_clk")) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001175 CAM_DBG(CAM_SENSOR,
1176 "Enable cam_clk: %d", j);
Alok Pandey01b1b352017-06-25 20:38:54 +05301177
1178 soc_info->rgltr[j] =
1179 regulator_get(
1180 &soc_info->pdev->dev,
1181 soc_info->rgltr_name[j]);
1182
1183 if (IS_ERR_OR_NULL(
1184 soc_info->rgltr[j])) {
1185 rc = PTR_ERR(
1186 soc_info->rgltr[j]);
1187 rc = rc ? rc : -EINVAL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001188 CAM_ERR(CAM_SENSOR,
1189 "vreg %s %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301190 soc_info->rgltr_name[j],
1191 rc);
1192 soc_info->rgltr[j] = NULL;
1193 }
1194
1195 rc = cam_soc_util_regulator_enable(
1196 soc_info->rgltr[j],
1197 soc_info->rgltr_name[j],
1198 soc_info->rgltr_min_volt[j],
1199 soc_info->rgltr_max_volt[j],
1200 soc_info->rgltr_op_mode[j],
1201 soc_info->rgltr_delay[j]);
1202
1203 power_setting->data[0] =
1204 soc_info->rgltr[j];
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001205 }
1206 }
1207 if (power_setting->config_val)
Alok Pandey01b1b352017-06-25 20:38:54 +05301208 soc_info->clk_rate[0][power_setting->seq_val] =
1209 power_setting->config_val;
1210
1211 for (j = 0; j < soc_info->num_clk; j++) {
1212 rc = cam_soc_util_clk_enable(soc_info->clk[j],
1213 soc_info->clk_name[j],
1214 soc_info->clk_rate[0][j]);
1215 if (rc)
1216 break;
1217 }
1218
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001219 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001220 CAM_ERR(CAM_SENSOR, "clk enable failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001221 goto power_up_failed;
1222 }
1223 break;
1224 case SENSOR_RESET:
1225 case SENSOR_STANDBY:
1226 case SENSOR_CUSTOM_GPIO1:
1227 case SENSOR_CUSTOM_GPIO2:
1228 if (no_gpio) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001229 CAM_ERR(CAM_SENSOR, "request gpio failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001230 return no_gpio;
1231 }
1232 if (power_setting->seq_val >= CAM_VREG_MAX ||
Alok Pandey01b1b352017-06-25 20:38:54 +05301233 !gpio_num_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001234 CAM_ERR(CAM_SENSOR, "gpio index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001235 power_setting->seq_val,
1236 CAM_VREG_MAX);
1237 goto power_up_failed;
1238 }
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001239 CAM_DBG(CAM_SENSOR, "gpio set val %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301240 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001241 [power_setting->seq_val]);
1242
1243 rc = msm_cam_sensor_handle_reg_gpio(
1244 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301245 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001246 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001247 CAM_ERR(CAM_SENSOR,
1248 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001249 goto power_up_failed;
1250 }
1251 break;
1252 case SENSOR_VANA:
1253 case SENSOR_VDIG:
1254 case SENSOR_VIO:
1255 case SENSOR_VAF:
1256 case SENSOR_VAF_PWDM:
1257 case SENSOR_CUSTOM_REG1:
1258 case SENSOR_CUSTOM_REG2:
1259 if (power_setting->seq_val == INVALID_VREG)
1260 break;
1261
1262 if (power_setting->seq_val >= CAM_VREG_MAX) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001263 CAM_ERR(CAM_SENSOR, "vreg index %d >= max %d",
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001264 power_setting->seq_val,
1265 CAM_VREG_MAX);
1266 goto power_up_failed;
1267 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301268 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001269 CAM_DBG(CAM_SENSOR, "Enable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301270 vreg_idx = power_setting->seq_val;
1271
1272 soc_info->rgltr[vreg_idx] =
1273 regulator_get(&soc_info->pdev->dev,
1274 soc_info->rgltr_name[vreg_idx]);
1275 if (IS_ERR_OR_NULL(
1276 soc_info->rgltr[vreg_idx])) {
1277 rc = PTR_ERR(soc_info->rgltr[vreg_idx]);
1278 rc = rc ? rc : -EINVAL;
1279
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001280 CAM_ERR(CAM_SENSOR, "%s get failed %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301281 soc_info->rgltr_name[vreg_idx],
1282 rc);
1283
1284 soc_info->rgltr[vreg_idx] = NULL;
1285 }
1286
1287 rc = cam_soc_util_regulator_enable(
1288 soc_info->rgltr[vreg_idx],
1289 soc_info->rgltr_name[vreg_idx],
1290 soc_info->rgltr_min_volt[vreg_idx],
1291 soc_info->rgltr_max_volt[vreg_idx],
1292 soc_info->rgltr_op_mode[vreg_idx],
1293 soc_info->rgltr_delay[vreg_idx]);
1294
1295 power_setting->data[0] =
1296 soc_info->rgltr[vreg_idx];
1297 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001298 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001299 CAM_ERR(CAM_SENSOR, "usr_idx:%d dts_idx:%d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301300 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001301
1302 rc = msm_cam_sensor_handle_reg_gpio(
1303 power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301304 gpio_num_info, 1);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001305 if (rc < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001306 CAM_ERR(CAM_SENSOR,
1307 "Error in handling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001308 goto power_up_failed;
1309 }
1310 break;
1311 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001312 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1313 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001314 break;
1315 }
1316 if (power_setting->delay > 20)
1317 msleep(power_setting->delay);
1318 else if (power_setting->delay)
1319 usleep_range(power_setting->delay * 1000,
1320 (power_setting->delay * 1000) + 1000);
1321 }
1322
1323 return 0;
1324power_up_failed:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001325 CAM_ERR(CAM_SENSOR, "failed");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001326 for (index--; index >= 0; index--) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001327 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001328 power_setting = &ctrl->power_setting[index];
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001329 CAM_DBG(CAM_SENSOR, "type %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301330 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001331 switch (power_setting->seq_type) {
1332 case SENSOR_RESET:
1333 case SENSOR_STANDBY:
1334 case SENSOR_CUSTOM_GPIO1:
1335 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301336 if (!gpio_num_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001337 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301338 if (!gpio_num_info->valid
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001339 [power_setting->seq_val])
1340 continue;
1341 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301342 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001343 [power_setting->seq_val], GPIOF_OUT_INIT_LOW);
1344 break;
1345 case SENSOR_VANA:
1346 case SENSOR_VDIG:
1347 case SENSOR_VIO:
1348 case SENSOR_VAF:
1349 case SENSOR_VAF_PWDM:
1350 case SENSOR_CUSTOM_REG1:
1351 case SENSOR_CUSTOM_REG2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301352 if (power_setting->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001353 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301354 vreg_idx = power_setting->seq_val;
1355
1356 rc = cam_soc_util_regulator_disable(
1357 soc_info->rgltr[vreg_idx],
1358 soc_info->rgltr_name[vreg_idx],
1359 soc_info->rgltr_min_volt[vreg_idx],
1360 soc_info->rgltr_max_volt[vreg_idx],
1361 soc_info->rgltr_op_mode[vreg_idx],
1362 soc_info->rgltr_delay[vreg_idx]);
1363
1364 power_setting->data[0] =
1365 soc_info->rgltr[vreg_idx];
1366
1367 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001368 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001369 CAM_ERR(CAM_SENSOR, "seq_val:%d > num_vreg: %d",
Alok Pandey01b1b352017-06-25 20:38:54 +05301370 power_setting->seq_val, num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001371
1372 msm_cam_sensor_handle_reg_gpio(power_setting->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301373 gpio_num_info, GPIOF_OUT_INIT_LOW);
1374
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001375 break;
1376 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001377 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1378 power_setting->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001379 break;
1380 }
1381 if (power_setting->delay > 20) {
1382 msleep(power_setting->delay);
1383 } else if (power_setting->delay) {
1384 usleep_range(power_setting->delay * 1000,
1385 (power_setting->delay * 1000) + 1000);
1386 }
1387 }
1388 if (ctrl->cam_pinctrl_status) {
1389 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1390 ctrl->pinctrl_info.gpio_state_suspend);
1391 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001392 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001393 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1394 }
1395 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301396
1397 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001398
1399 return rc;
1400}
1401
1402static struct cam_sensor_power_setting*
1403msm_camera_get_power_settings(struct cam_sensor_power_ctrl_t *ctrl,
1404 enum msm_camera_power_seq_type seq_type,
1405 uint16_t seq_val)
1406{
1407 struct cam_sensor_power_setting *power_setting, *ps = NULL;
1408 int idx;
1409
1410 for (idx = 0; idx < ctrl->power_setting_size; idx++) {
1411 power_setting = &ctrl->power_setting[idx];
1412 if (power_setting->seq_type == seq_type &&
1413 power_setting->seq_val == seq_val) {
1414 ps = power_setting;
1415 return ps;
1416 }
1417
1418 }
1419
1420 return ps;
1421}
1422
1423static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
Alok Pandey01b1b352017-06-25 20:38:54 +05301424 struct cam_hw_soc_info *soc_info, int32_t index)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001425{
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001426 int32_t num_vreg = 0, j = 0, rc = 0, idx = 0;
1427 struct cam_sensor_power_setting *ps = NULL;
1428 struct cam_sensor_power_setting *pd = NULL;
1429
Alok Pandey01b1b352017-06-25 20:38:54 +05301430 num_vreg = soc_info->num_rgltr;
1431
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001432 pd = &ctrl->power_down_setting[index];
1433
1434 for (j = 0; j < num_vreg; j++) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301435 if (!strcmp(soc_info->rgltr_name[j], "cam_clk")) {
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001436
1437 ps = NULL;
1438 for (idx = 0; idx <
1439 ctrl->power_setting_size; idx++) {
1440 if (ctrl->power_setting[idx].
1441 seq_type == pd->seq_type) {
1442 ps = &ctrl->power_setting[idx];
1443 break;
1444 }
1445 }
1446
Alok Pandey01b1b352017-06-25 20:38:54 +05301447 if (ps != NULL) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001448 CAM_DBG(CAM_SENSOR, "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301449
1450 rc = cam_soc_util_regulator_disable(
1451 soc_info->rgltr[j],
1452 soc_info->rgltr_name[j],
1453 soc_info->rgltr_min_volt[j],
1454 soc_info->rgltr_max_volt[j],
1455 soc_info->rgltr_op_mode[j],
1456 soc_info->rgltr_delay[j]);
1457
1458 ps->data[0] =
1459 soc_info->rgltr[j];
1460 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001461 }
1462 }
1463
1464 return rc;
1465}
1466
Alok Pandey01b1b352017-06-25 20:38:54 +05301467int msm_camera_power_down(struct cam_sensor_power_ctrl_t *ctrl,
1468 struct cam_hw_soc_info *soc_info)
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001469{
Alok Pandey01b1b352017-06-25 20:38:54 +05301470 int index = 0, ret = 0, num_vreg = 0, i;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001471 struct cam_sensor_power_setting *pd = NULL;
1472 struct cam_sensor_power_setting *ps;
Alok Pandey01b1b352017-06-25 20:38:54 +05301473 struct msm_camera_gpio_num_info *gpio_num_info = NULL;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001474
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001475 CAM_DBG(CAM_SENSOR, "Enter");
Alok Pandey01b1b352017-06-25 20:38:54 +05301476 if (!ctrl || !soc_info) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001477 CAM_ERR(CAM_SENSOR, "failed ctrl %pK", ctrl);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001478 return -EINVAL;
1479 }
1480
Alok Pandey01b1b352017-06-25 20:38:54 +05301481 gpio_num_info = ctrl->gpio_num_info;
1482 num_vreg = soc_info->num_rgltr;
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001483
1484 for (index = 0; index < ctrl->power_down_setting_size; index++) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001485 CAM_DBG(CAM_SENSOR, "index %d", index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001486 pd = &ctrl->power_down_setting[index];
1487 ps = NULL;
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001488 CAM_DBG(CAM_SENSOR, "type %d", pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001489 switch (pd->seq_type) {
1490 case SENSOR_MCLK:
Alok Pandey01b1b352017-06-25 20:38:54 +05301491 ret = cam_config_mclk_reg(ctrl, soc_info, index);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001492 if (ret < 0) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001493 CAM_ERR(CAM_SENSOR,
1494 "config clk reg failed rc: %d", ret);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001495 return ret;
1496 }
Alok Pandey01b1b352017-06-25 20:38:54 +05301497 //cam_soc_util_clk_disable_default(soc_info);
1498 for (i = soc_info->num_clk - 1; i >= 0; i--) {
1499 cam_soc_util_clk_disable(soc_info->clk[i],
1500 soc_info->clk_name[i]);
1501 }
1502
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001503 break;
1504 case SENSOR_RESET:
1505 case SENSOR_STANDBY:
1506 case SENSOR_CUSTOM_GPIO1:
1507 case SENSOR_CUSTOM_GPIO2:
Alok Pandey01b1b352017-06-25 20:38:54 +05301508
1509 if (!gpio_num_info->valid[pd->seq_val])
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001510 continue;
Alok Pandey01b1b352017-06-25 20:38:54 +05301511
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001512 gpio_set_value_cansleep(
Alok Pandey01b1b352017-06-25 20:38:54 +05301513 gpio_num_info->gpio_num
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001514 [pd->seq_val],
1515 (int) pd->config_val);
Alok Pandey01b1b352017-06-25 20:38:54 +05301516
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001517 break;
1518 case SENSOR_VANA:
1519 case SENSOR_VDIG:
1520 case SENSOR_VIO:
1521 case SENSOR_VAF:
1522 case SENSOR_VAF_PWDM:
1523 case SENSOR_CUSTOM_REG1:
1524 case SENSOR_CUSTOM_REG2:
1525 if (pd->seq_val == INVALID_VREG)
1526 break;
Alok Pandey01b1b352017-06-25 20:38:54 +05301527
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001528 ps = msm_camera_get_power_settings(
1529 ctrl, pd->seq_type,
1530 pd->seq_val);
1531 if (ps) {
Alok Pandey01b1b352017-06-25 20:38:54 +05301532 if (pd->seq_val < num_vreg) {
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001533 CAM_DBG(CAM_SENSOR,
1534 "Disable Regulator");
Alok Pandey01b1b352017-06-25 20:38:54 +05301535 ret = cam_soc_util_regulator_disable(
1536 soc_info->rgltr[ps->seq_val],
1537 soc_info->rgltr_name[ps->seq_val],
1538 soc_info->rgltr_min_volt[ps->seq_val],
1539 soc_info->rgltr_max_volt[ps->seq_val],
1540 soc_info->rgltr_op_mode[ps->seq_val],
1541 soc_info->rgltr_delay[ps->seq_val]);
1542
1543 ps->data[0] =
1544 soc_info->rgltr[ps->seq_val];
1545 }
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001546 else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001547 CAM_ERR(CAM_SENSOR,
1548 "seq_val:%d > num_vreg: %d",
1549 pd->seq_val,
Alok Pandey01b1b352017-06-25 20:38:54 +05301550 num_vreg);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001551 } else
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001552 CAM_ERR(CAM_SENSOR,
1553 "error in power up/down seq");
Alok Pandey01b1b352017-06-25 20:38:54 +05301554
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001555 ret = msm_cam_sensor_handle_reg_gpio(pd->seq_type,
Alok Pandey01b1b352017-06-25 20:38:54 +05301556 gpio_num_info, GPIOF_OUT_INIT_LOW);
1557
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001558 if (ret < 0)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001559 CAM_ERR(CAM_SENSOR,
1560 "Error disabling VREG GPIO");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001561 break;
1562 default:
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001563 CAM_ERR(CAM_SENSOR, "error power seq type %d",
1564 pd->seq_type);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001565 break;
1566 }
1567 if (pd->delay > 20)
1568 msleep(pd->delay);
1569 else if (pd->delay)
1570 usleep_range(pd->delay * 1000,
1571 (pd->delay * 1000) + 1000);
1572 }
1573
1574 if (ctrl->cam_pinctrl_status) {
1575 ret = pinctrl_select_state(ctrl->pinctrl_info.pinctrl,
1576 ctrl->pinctrl_info.gpio_state_suspend);
1577 if (ret)
Jigarkumar Zalacbb5a382017-07-17 19:06:42 -07001578 CAM_ERR(CAM_SENSOR, "cannot set pin to suspend state");
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001579 devm_pinctrl_put(ctrl->pinctrl_info.pinctrl);
1580 }
1581
1582 ctrl->cam_pinctrl_status = 0;
Alok Pandey01b1b352017-06-25 20:38:54 +05301583
1584 cam_sensor_util_request_gpio_table(soc_info, 0);
Viswanadha Raju Thotakura426ec662017-03-15 17:00:29 -07001585
1586 return 0;
1587}
1588