OSDN Git Service

Merge android-4.4.128 (89904cc) into msm-4.4
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / drivers / media / platform / msm / camera_v2 / common / cam_soc_api.c
1 /* Copyright (c) 2015-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 #define pr_fmt(fmt) "CAM-SOC %s:%d " fmt, __func__, __LINE__
14 #define NO_SET_RATE -1
15 #define INIT_RATE -2
16
17 #ifdef CONFIG_CAM_SOC_API_DBG
18 #define CDBG(fmt, args...) pr_err(fmt, ##args)
19 #else
20 #define CDBG(fmt, args...) pr_debug(fmt, ##args)
21 #endif
22
23 #include <linux/delay.h>
24 #include <linux/module.h>
25 #include <linux/of_platform.h>
26 #include <linux/msm-bus.h>
27 #include <linux/clk/msm-clk.h>
28 #include "cam_soc_api.h"
29
30 struct msm_cam_bus_pscale_data {
31         struct msm_bus_scale_pdata *pdata;
32         uint32_t bus_client;
33         uint32_t num_usecases;
34         uint32_t num_paths;
35         unsigned int vector_index;
36         bool dyn_vote;
37         struct mutex lock;
38 };
39
40 struct msm_cam_bus_pscale_data g_cv[CAM_BUS_CLIENT_MAX];
41
42
43 /* Get all clocks from DT */
44 static int msm_camera_get_clk_info_internal(struct device *dev,
45                         struct msm_cam_clk_info **clk_info,
46                         struct clk ***clk_ptr,
47                         size_t *num_clk)
48 {
49         int rc = 0;
50         size_t cnt, tmp;
51         uint32_t *rates, i = 0;
52         const char *clk_ctl = NULL;
53         bool clock_cntl_support = false;
54         struct device_node *of_node;
55
56         of_node = dev->of_node;
57
58         cnt = of_property_count_strings(of_node, "clock-names");
59         if (cnt <= 0) {
60                 pr_err("err: No clocks found in DT=%zu\n", cnt);
61                 return -EINVAL;
62         }
63
64         tmp = of_property_count_u32_elems(of_node, "qcom,clock-rates");
65         if (tmp <= 0) {
66                 pr_err("err: No clk rates device tree, count=%zu", tmp);
67                 return -EINVAL;
68         }
69
70         if (cnt != tmp) {
71                 pr_err("err: clk name/rates mismatch, strings=%zu, rates=%zu\n",
72                         cnt, tmp);
73                 return -EINVAL;
74         }
75
76         if (of_property_read_bool(of_node, "qcom,clock-cntl-support")) {
77                 tmp = of_property_count_strings(of_node,
78                                 "qcom,clock-control");
79                 if (tmp <= 0) {
80                         pr_err("err: control strings not found in DT count=%zu",
81                                 tmp);
82                         return -EINVAL;
83                 }
84                 if (cnt != tmp) {
85                         pr_err("err: controls mismatch, strings=%zu, ctl=%zu\n",
86                                 cnt, tmp);
87                         return -EINVAL;
88                 }
89                 clock_cntl_support = true;
90         }
91
92         *num_clk = cnt;
93
94         *clk_info = devm_kcalloc(dev, cnt,
95                                 sizeof(struct msm_cam_clk_info), GFP_KERNEL);
96         if (!*clk_info)
97                 return -ENOMEM;
98
99         *clk_ptr = devm_kcalloc(dev, cnt, sizeof(struct clk *),
100                                 GFP_KERNEL);
101         if (!*clk_ptr) {
102                 rc = -ENOMEM;
103                 goto err1;
104         }
105
106         rates = devm_kcalloc(dev, cnt, sizeof(long), GFP_KERNEL);
107         if (!rates) {
108                 rc = -ENOMEM;
109                 goto err2;
110         }
111
112         rc = of_property_read_u32_array(of_node, "qcom,clock-rates",
113                 rates, cnt);
114         if (rc < 0) {
115                 pr_err("err: failed reading clock rates\n");
116                 rc = -EINVAL;
117                 goto err3;
118         }
119
120         for (i = 0; i < cnt; i++) {
121                 rc = of_property_read_string_index(of_node, "clock-names",
122                                 i, &((*clk_info)[i].clk_name));
123                 if (rc < 0) {
124                         pr_err("%s reading clock-name failed index %d\n",
125                                 __func__, i);
126                         rc = -EINVAL;
127                         goto err3;
128                 }
129
130                 CDBG("dbg: clk-name[%d] = %s\n", i, (*clk_info)[i].clk_name);
131                 if (clock_cntl_support) {
132                         rc = of_property_read_string_index(of_node,
133                                 "qcom,clock-control", i, &clk_ctl);
134                         if (rc < 0) {
135                                 pr_err("%s reading clock-control failed index %d\n",
136                                         __func__, i);
137                                 rc = -EINVAL;
138                                 goto err3;
139                         }
140
141                         if (!strcmp(clk_ctl, "NO_SET_RATE"))
142                                 (*clk_info)[i].clk_rate = NO_SET_RATE;
143                         else if (!strcmp(clk_ctl, "INIT_RATE"))
144                                 (*clk_info)[i].clk_rate = INIT_RATE;
145                         else if (!strcmp(clk_ctl, "SET_RATE"))
146                                 (*clk_info)[i].clk_rate = rates[i];
147                         else {
148                                 pr_err("%s: error: clock control has invalid value\n",
149                                          __func__);
150                                 rc = -EBUSY;
151                                 goto err3;
152                         }
153                 } else
154                         (*clk_info)[i].clk_rate =
155                                 (rates[i] == 0) ? (long)-1 : rates[i];
156
157                 CDBG("dbg: clk-rate[%d] = rate: %ld\n",
158                         i, (*clk_info)[i].clk_rate);
159
160                 (*clk_ptr)[i] =
161                         devm_clk_get(dev, (*clk_info)[i].clk_name);
162                 if (IS_ERR((*clk_ptr)[i])) {
163                         rc = PTR_ERR((*clk_ptr)[i]);
164                         goto err4;
165                 }
166                 CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
167         }
168
169         devm_kfree(dev, rates);
170         return rc;
171
172 err4:
173         for (--i; i >= 0; i--)
174                 devm_clk_put(dev, (*clk_ptr)[i]);
175 err3:
176         devm_kfree(dev, rates);
177 err2:
178         devm_kfree(dev, *clk_ptr);
179 err1:
180         devm_kfree(dev, *clk_info);
181         return rc;
182 }
183
184 /* Get all clocks from DT  for I2C devices */
185 int msm_camera_i2c_dev_get_clk_info(struct device *dev,
186                         struct msm_cam_clk_info **clk_info,
187                         struct clk ***clk_ptr,
188                         size_t *num_clk)
189 {
190         int rc = 0;
191
192         if (!dev || !clk_info || !clk_ptr || !num_clk)
193                 return -EINVAL;
194
195         rc = msm_camera_get_clk_info_internal(dev, clk_info, clk_ptr, num_clk);
196         return rc;
197 }
198 EXPORT_SYMBOL(msm_camera_i2c_dev_get_clk_info);
199
200 /* Get all clocks from DT  for platform devices */
201 int msm_camera_get_clk_info(struct platform_device *pdev,
202                         struct msm_cam_clk_info **clk_info,
203                         struct clk ***clk_ptr,
204                         size_t *num_clk)
205 {
206         int rc = 0;
207
208         if (!pdev || !&pdev->dev || !clk_info || !clk_ptr || !num_clk)
209                 return -EINVAL;
210
211         rc = msm_camera_get_clk_info_internal(&pdev->dev,
212                         clk_info, clk_ptr, num_clk);
213         return rc;
214 }
215 EXPORT_SYMBOL(msm_camera_get_clk_info);
216
217 /* Get all clocks and multiple rates from DT */
218 int msm_camera_get_clk_info_and_rates(
219                         struct platform_device *pdev,
220                         struct msm_cam_clk_info **pclk_info,
221                         struct clk ***pclks,
222                         uint32_t ***pclk_rates,
223                         size_t *num_set,
224                         size_t *num_clk)
225 {
226         int rc = 0, tmp_var, cnt, tmp;
227         uint32_t i = 0, j = 0;
228         struct device_node *of_node;
229         uint32_t **rates;
230         struct clk **clks;
231         struct msm_cam_clk_info *clk_info;
232
233         if (!pdev || !pclk_info || !num_clk
234                 || !pclk_rates || !pclks || !num_set)
235                 return -EINVAL;
236
237         of_node = pdev->dev.of_node;
238
239         cnt = of_property_count_strings(of_node, "clock-names");
240         if (cnt <= 0) {
241                 pr_err("err: No clocks found in DT=%d\n", cnt);
242                 return -EINVAL;
243         }
244
245         tmp = of_property_count_u32_elems(of_node, "qcom,clock-rates");
246         if (tmp <= 0) {
247                 pr_err("err: No clk rates device tree, count=%d\n", tmp);
248                 return -EINVAL;
249         }
250
251         if ((tmp % cnt) != 0) {
252                 pr_err("err: clk name/rates mismatch, strings=%d, rates=%d\n",
253                         cnt, tmp);
254                 return -EINVAL;
255         }
256
257         *num_clk = cnt;
258         *num_set = (tmp / cnt);
259
260         clk_info = devm_kcalloc(&pdev->dev, cnt,
261                                 sizeof(struct msm_cam_clk_info), GFP_KERNEL);
262         if (!clk_info)
263                 return -ENOMEM;
264
265         clks = devm_kcalloc(&pdev->dev, cnt, sizeof(struct clk *),
266                                 GFP_KERNEL);
267         if (!clks) {
268                 rc = -ENOMEM;
269                 goto err1;
270         }
271
272         rates = devm_kcalloc(&pdev->dev, *num_set,
273                 sizeof(uint32_t *), GFP_KERNEL);
274         if (!rates) {
275                 rc = -ENOMEM;
276                 goto err2;
277         }
278
279         for (i = 0; i < *num_set; i++) {
280                 rates[i] = devm_kcalloc(&pdev->dev, *num_clk,
281                         sizeof(uint32_t), GFP_KERNEL);
282                 if (!rates[i]) {
283                         rc = -ENOMEM;
284                         for (--i; i >= 0; i--)
285                                 devm_kfree(&pdev->dev, rates[i]);
286                         goto err3;
287                 }
288         }
289
290         tmp_var = 0;
291         for (i = 0; i < *num_set; i++) {
292                 for (j = 0; j < *num_clk; j++) {
293                         rc = of_property_read_u32_index(of_node,
294                                 "qcom,clock-rates", tmp_var++, &rates[i][j]);
295                         if (rc < 0) {
296                                 pr_err("err: failed reading clock rates\n");
297                                 rc = -EINVAL;
298                                 goto err4;
299                         }
300                         CDBG("Clock rate idx %d idx %d value %d\n",
301                                 i, j, rates[i][j]);
302                 }
303         }
304         for (i = 0; i < *num_clk; i++) {
305                 rc = of_property_read_string_index(of_node, "clock-names",
306                                 i, &clk_info[i].clk_name);
307                 if (rc < 0) {
308                         pr_err("%s reading clock-name failed index %d\n",
309                                 __func__, i);
310                         rc = -EINVAL;
311                         goto err4;
312                 }
313
314                 CDBG("dbg: clk-name[%d] = %s\n", i, clk_info[i].clk_name);
315
316                 clks[i] =
317                         devm_clk_get(&pdev->dev, clk_info[i].clk_name);
318                 if (IS_ERR(clks[i])) {
319                         rc = PTR_ERR(clks[i]);
320                         goto err5;
321                 }
322                 CDBG("clk ptr[%d] :%pK\n", i, clks[i]);
323         }
324         *pclk_info = clk_info;
325         *pclks = clks;
326         *pclk_rates = rates;
327
328         return rc;
329
330 err5:
331         for (--i; i >= 0; i--)
332                 devm_clk_put(&pdev->dev, clks[i]);
333 err4:
334         for (i = 0; i < *num_set; i++)
335                 devm_kfree(&pdev->dev, rates[i]);
336 err3:
337         devm_kfree(&pdev->dev, rates);
338 err2:
339         devm_kfree(&pdev->dev, clks);
340 err1:
341         devm_kfree(&pdev->dev, clk_info);
342         return rc;
343 }
344 EXPORT_SYMBOL(msm_camera_get_clk_info_and_rates);
345
346 /* Enable/Disable all clocks */
347 int msm_camera_clk_enable(struct device *dev,
348                 struct msm_cam_clk_info *clk_info,
349                 struct clk **clk_ptr, int num_clk, int enable)
350 {
351         int i;
352         int rc = 0;
353         long clk_rate;
354
355         if (enable) {
356                 for (i = 0; i < num_clk; i++) {
357                         CDBG("enable %s\n", clk_info[i].clk_name);
358                         if (clk_info[i].clk_rate > 0) {
359                                 clk_rate = clk_round_rate(clk_ptr[i],
360                                         clk_info[i].clk_rate);
361                                 if (clk_rate < 0) {
362                                         pr_err("%s round failed\n",
363                                                    clk_info[i].clk_name);
364                                         goto cam_clk_set_err;
365                                 }
366                                 rc = clk_set_rate(clk_ptr[i],
367                                         clk_rate);
368                                 if (rc < 0) {
369                                         pr_err("%s set failed\n",
370                                                 clk_info[i].clk_name);
371                                         goto cam_clk_set_err;
372                                 }
373
374                         } else if (clk_info[i].clk_rate == INIT_RATE) {
375                                 clk_rate = clk_get_rate(clk_ptr[i]);
376                                 if (clk_rate == 0) {
377                                         clk_rate =
378                                                   clk_round_rate(clk_ptr[i], 0);
379                                         if (clk_rate <= 0) {
380                                                 pr_err("%s round rate failed\n",
381                                                           clk_info[i].clk_name);
382                                                 goto cam_clk_set_err;
383                                         }
384                                 }
385                                 rc = clk_set_rate(clk_ptr[i], clk_rate);
386                                 if (rc < 0) {
387                                         pr_err("%s set rate failed\n",
388                                                 clk_info[i].clk_name);
389                                         goto cam_clk_set_err;
390                                 }
391                         }
392                         rc = clk_prepare_enable(clk_ptr[i]);
393                         if (rc < 0) {
394                                 pr_err("%s enable failed\n",
395                                            clk_info[i].clk_name);
396                                 goto cam_clk_enable_err;
397                         }
398                         if (clk_info[i].delay > 20) {
399                                 msleep(clk_info[i].delay);
400                         } else if (clk_info[i].delay) {
401                                 usleep_range(clk_info[i].delay * 1000,
402                                         (clk_info[i].delay * 1000) + 1000);
403                         }
404                 }
405         } else {
406                 for (i = num_clk - 1; i >= 0; i--) {
407                         if (clk_ptr[i] != NULL) {
408                                 CDBG("%s disable %s\n", __func__,
409                                         clk_info[i].clk_name);
410                                 clk_disable_unprepare(clk_ptr[i]);
411                         }
412                 }
413         }
414         return rc;
415
416 cam_clk_enable_err:
417 cam_clk_set_err:
418         for (i--; i >= 0; i--) {
419                 if (clk_ptr[i] != NULL)
420                         clk_disable_unprepare(clk_ptr[i]);
421         }
422         return rc;
423 }
424 EXPORT_SYMBOL(msm_camera_clk_enable);
425
426 /* Set rate on a specific clock */
427 long msm_camera_clk_set_rate(struct device *dev,
428                         struct clk *clk,
429                         long clk_rate)
430 {
431         int rc = 0;
432         long rate = 0;
433
434         if (!dev || !clk || (clk_rate < 0))
435                 return -EINVAL;
436
437         CDBG("clk : %pK, enable : %ld\n", clk, clk_rate);
438
439         if (clk_rate > 0) {
440                 rate = clk_round_rate(clk, clk_rate);
441                 if (rate < 0) {
442                         pr_err("round rate failed\n");
443                         return -EINVAL;
444                 }
445
446                 rc = clk_set_rate(clk, rate);
447                 if (rc < 0) {
448                         pr_err("set rate failed\n");
449                         return -EINVAL;
450                 }
451         }
452
453         return rate;
454 }
455 EXPORT_SYMBOL(msm_camera_clk_set_rate);
456
457 int msm_camera_set_clk_flags(struct clk *clk, unsigned long flags)
458 {
459         if (!clk)
460                 return -EINVAL;
461
462         CDBG("clk : %pK, flags : %ld\n", clk, flags);
463
464         return clk_set_flags(clk, flags);
465 }
466 EXPORT_SYMBOL(msm_camera_set_clk_flags);
467
468 /* release memory allocated for clocks */
469 static int msm_camera_put_clk_info_internal(struct device *dev,
470                                 struct msm_cam_clk_info **clk_info,
471                                 struct clk ***clk_ptr, int cnt)
472 {
473         int i;
474
475         for (i = cnt - 1; i >= 0; i--) {
476                 if (clk_ptr[i] != NULL)
477                         devm_clk_put(dev, (*clk_ptr)[i]);
478
479                 CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
480         }
481         devm_kfree(dev, *clk_info);
482         devm_kfree(dev, *clk_ptr);
483         *clk_info = NULL;
484         *clk_ptr = NULL;
485         return 0;
486 }
487
488 /* release memory allocated for clocks for i2c devices */
489 int msm_camera_i2c_dev_put_clk_info(struct device *dev,
490                                 struct msm_cam_clk_info **clk_info,
491                                 struct clk ***clk_ptr, int cnt)
492 {
493         int rc = 0;
494
495         if (!dev || !clk_info || !clk_ptr)
496                 return -EINVAL;
497
498         rc = msm_camera_put_clk_info_internal(dev, clk_info, clk_ptr, cnt);
499         return rc;
500 }
501 EXPORT_SYMBOL(msm_camera_i2c_dev_put_clk_info);
502
503 /* release memory allocated for clocks for platform devices */
504 int msm_camera_put_clk_info(struct platform_device *pdev,
505                                 struct msm_cam_clk_info **clk_info,
506                                 struct clk ***clk_ptr, int cnt)
507 {
508         int rc = 0;
509
510         if (!pdev || !&pdev->dev || !clk_info || !clk_ptr)
511                 return -EINVAL;
512
513         rc = msm_camera_put_clk_info_internal(&pdev->dev,
514                         clk_info, clk_ptr, cnt);
515         return rc;
516 }
517 EXPORT_SYMBOL(msm_camera_put_clk_info);
518
519 int msm_camera_put_clk_info_and_rates(struct platform_device *pdev,
520                 struct msm_cam_clk_info **clk_info,
521                 struct clk ***clk_ptr, uint32_t ***clk_rates,
522                 size_t set, size_t cnt)
523 {
524         int i;
525
526         for (i = set - 1; i >= 0; i--)
527                 devm_kfree(&pdev->dev, (*clk_rates)[i]);
528
529         devm_kfree(&pdev->dev, *clk_rates);
530         for (i = cnt - 1; i >= 0; i--) {
531                 if (clk_ptr[i] != NULL)
532                         devm_clk_put(&pdev->dev, (*clk_ptr)[i]);
533                 CDBG("clk ptr[%d] :%pK\n", i, (*clk_ptr)[i]);
534         }
535         devm_kfree(&pdev->dev, *clk_info);
536         devm_kfree(&pdev->dev, *clk_ptr);
537         *clk_info = NULL;
538         *clk_ptr = NULL;
539         *clk_rates = NULL;
540         return 0;
541 }
542 EXPORT_SYMBOL(msm_camera_put_clk_info_and_rates);
543
544 /* Get reset info from DT */
545 int msm_camera_get_reset_info(struct platform_device *pdev,
546                 struct reset_control **micro_iface_reset)
547 {
548         if (!pdev || !micro_iface_reset)
549                 return -EINVAL;
550
551         if (of_property_match_string(pdev->dev.of_node, "reset-names",
552                                 "micro_iface_reset")) {
553                 pr_err("err: Reset property not found\n");
554                 return -EINVAL;
555         }
556
557         *micro_iface_reset = devm_reset_control_get
558                                 (&pdev->dev, "micro_iface_reset");
559         if (IS_ERR(*micro_iface_reset))
560                 return PTR_ERR(*micro_iface_reset);
561
562         return 0;
563 }
564 EXPORT_SYMBOL(msm_camera_get_reset_info);
565
566 /* Get regulators from DT */
567 int msm_camera_get_regulator_info(struct platform_device *pdev,
568                                 struct msm_cam_regulator **vdd_info,
569                                 int *num_reg)
570 {
571         uint32_t cnt;
572         int i, rc;
573         struct device_node *of_node;
574         char prop_name[32];
575         struct msm_cam_regulator *tmp_reg;
576
577         if (!pdev || !vdd_info || !num_reg)
578                 return -EINVAL;
579
580         of_node = pdev->dev.of_node;
581
582         if (!of_get_property(of_node, "qcom,vdd-names", NULL)) {
583                 pr_err("err: Regulators property not found\n");
584                 return -EINVAL;
585         }
586
587         cnt = of_property_count_strings(of_node, "qcom,vdd-names");
588         if (cnt <= 0) {
589                 pr_err("err: no regulators found in device tree, count=%d",
590                         cnt);
591                 return -EINVAL;
592         }
593
594         tmp_reg = devm_kcalloc(&pdev->dev, cnt,
595                                 sizeof(struct msm_cam_regulator), GFP_KERNEL);
596         if (!tmp_reg)
597                 return -ENOMEM;
598
599         for (i = 0; i < cnt; i++) {
600                 rc = of_property_read_string_index(of_node,
601                         "qcom,vdd-names", i, &tmp_reg[i].name);
602                 if (rc < 0) {
603                         pr_err("Fail to fetch regulators: %d\n", i);
604                         rc = -EINVAL;
605                         goto err1;
606                 }
607
608                 CDBG("regulator-names[%d] = %s\n", i, tmp_reg[i].name);
609
610                 snprintf(prop_name, 32, "%s-supply", tmp_reg[i].name);
611
612                 if (of_get_property(of_node, prop_name, NULL)) {
613                         tmp_reg[i].vdd =
614                                 devm_regulator_get(&pdev->dev, tmp_reg[i].name);
615                         if (IS_ERR(tmp_reg[i].vdd)) {
616                                 rc = -EINVAL;
617                                 pr_err("Fail to get regulator :%d\n", i);
618                                 goto err1;
619                         }
620                 } else {
621                         pr_err("Regulator phandle not found :%s\n",
622                                 tmp_reg[i].name);
623                         rc = -EINVAL;
624                         goto err1;
625                 }
626                 CDBG("vdd ptr[%d] :%pK\n", i, tmp_reg[i].vdd);
627         }
628
629         *num_reg = cnt;
630         *vdd_info = tmp_reg;
631
632         return 0;
633
634 err1:
635         for (--i; i >= 0; i--)
636                 devm_regulator_put(tmp_reg[i].vdd);
637         devm_kfree(&pdev->dev, tmp_reg);
638         return rc;
639 }
640 EXPORT_SYMBOL(msm_camera_get_regulator_info);
641
642
643 /* Enable/Disable regulators */
644 int msm_camera_regulator_enable(struct msm_cam_regulator *vdd_info,
645                                 int cnt, int enable)
646 {
647         int i;
648         int rc;
649         struct msm_cam_regulator *tmp = vdd_info;
650
651         if (!tmp) {
652                 pr_err("Invalid params");
653                 return -EINVAL;
654         }
655         CDBG("cnt : %d\n", cnt);
656
657         for (i = 0; i < cnt; i++) {
658                 if (tmp && !IS_ERR_OR_NULL(tmp->vdd)) {
659                         CDBG("name : %s, enable : %d\n", tmp->name, enable);
660                         if (enable) {
661                                 rc = regulator_enable(tmp->vdd);
662                                 if (rc < 0) {
663                                         pr_err("regulator enable failed %d\n",
664                                                 i);
665                                         goto error;
666                                 }
667                         } else {
668                                 rc = regulator_disable(tmp->vdd);
669                                 if (rc < 0)
670                                         pr_err("regulator disable failed %d\n",
671                                                 i);
672                         }
673                 }
674                 tmp++;
675         }
676
677         return 0;
678 error:
679         for (--i; i > 0; i--) {
680                 --tmp;
681                 if (!IS_ERR_OR_NULL(tmp->vdd))
682                         regulator_disable(tmp->vdd);
683         }
684         return rc;
685 }
686 EXPORT_SYMBOL(msm_camera_regulator_enable);
687
688 /* set regulator mode */
689 int msm_camera_regulator_set_mode(struct msm_cam_regulator *vdd_info,
690                                 int cnt, bool mode)
691 {
692         int i;
693         int rc;
694         struct msm_cam_regulator *tmp = vdd_info;
695
696         if (!tmp) {
697                 pr_err("Invalid params");
698                 return -EINVAL;
699         }
700         CDBG("cnt : %d\n", cnt);
701
702         for (i = 0; i < cnt; i++) {
703                 if (tmp && !IS_ERR_OR_NULL(tmp->vdd)) {
704                         CDBG("name : %s, enable : %d\n", tmp->name, mode);
705                         if (mode) {
706                                 rc = regulator_set_mode(tmp->vdd,
707                                         REGULATOR_MODE_FAST);
708                                 if (rc < 0) {
709                                         pr_err("regulator enable failed %d\n",
710                                                 i);
711                                         goto error;
712                                 }
713                         } else {
714                                 rc = regulator_set_mode(tmp->vdd,
715                                         REGULATOR_MODE_NORMAL);
716                                 if (rc < 0)
717                                         pr_err("regulator disable failed %d\n",
718                                                 i);
719                                         goto error;
720                         }
721                 }
722                 tmp++;
723         }
724
725         return 0;
726 error:
727         return rc;
728 }
729 EXPORT_SYMBOL(msm_camera_regulator_set_mode);
730
731
732 /* Put regulators regulators */
733 void msm_camera_put_regulators(struct platform_device *pdev,
734         struct msm_cam_regulator **vdd_info, int cnt)
735 {
736         int i;
737
738         if (!vdd_info || !*vdd_info) {
739                 pr_err("Invalid params\n");
740                 return;
741         }
742
743         for (i = cnt - 1; i >= 0; i--) {
744                 if (vdd_info[i] && !IS_ERR_OR_NULL(vdd_info[i]->vdd))
745                         devm_regulator_put(vdd_info[i]->vdd);
746                         CDBG("vdd ptr[%d] :%pK\n", i, vdd_info[i]->vdd);
747         }
748
749         devm_kfree(&pdev->dev, *vdd_info);
750         *vdd_info = NULL;
751 }
752 EXPORT_SYMBOL(msm_camera_put_regulators);
753
754 struct resource *msm_camera_get_irq(struct platform_device *pdev,
755                                                         char *irq_name)
756 {
757         if (!pdev || !irq_name) {
758                 pr_err("Invalid params\n");
759                 return NULL;
760         }
761
762         CDBG("Get irq for %s\n", irq_name);
763         return platform_get_resource_byname(pdev, IORESOURCE_IRQ, irq_name);
764 }
765 EXPORT_SYMBOL(msm_camera_get_irq);
766
767 int msm_camera_register_irq(struct platform_device *pdev,
768                         struct resource *irq, irq_handler_t handler,
769                         unsigned long irqflags, char *irq_name, void *dev_id)
770 {
771         int rc = 0;
772
773         if (!pdev || !irq || !handler || !irq_name || !dev_id) {
774                 pr_err("Invalid params\n");
775                 return -EINVAL;
776         }
777
778         rc = devm_request_irq(&pdev->dev, irq->start, handler,
779                 irqflags, irq_name, dev_id);
780         if (rc < 0) {
781                 pr_err("irq request fail\n");
782                 rc = -EINVAL;
783         }
784
785         CDBG("Registered irq for %s[resource - %pK]\n", irq_name, irq);
786
787         return rc;
788 }
789 EXPORT_SYMBOL(msm_camera_register_irq);
790
791 int msm_camera_register_threaded_irq(struct platform_device *pdev,
792                         struct resource *irq, irq_handler_t handler_fn,
793                         irq_handler_t thread_fn, unsigned long irqflags,
794                         const char *irq_name, void *dev_id)
795 {
796         int rc = 0;
797
798         if (!pdev || !irq || !irq_name || !dev_id) {
799                 pr_err("Invalid params\n");
800                 return -EINVAL;
801         }
802
803         rc = devm_request_threaded_irq(&pdev->dev, irq->start, handler_fn,
804                         thread_fn, irqflags, irq_name, dev_id);
805         if (rc < 0) {
806                 pr_err("irq request fail\n");
807                 rc = -EINVAL;
808         }
809
810         CDBG("Registered irq for %s[resource - %pK]\n", irq_name, irq);
811
812         return rc;
813 }
814 EXPORT_SYMBOL(msm_camera_register_threaded_irq);
815
816 int msm_camera_enable_irq(struct resource *irq, int enable)
817 {
818         if (!irq) {
819                 pr_err("Invalid params\n");
820                 return -EINVAL;
821         }
822
823         CDBG("irq Enable %d\n", enable);
824         if (enable)
825                 enable_irq(irq->start);
826         else
827                 disable_irq(irq->start);
828
829         return 0;
830 }
831 EXPORT_SYMBOL(msm_camera_enable_irq);
832
833 int msm_camera_unregister_irq(struct platform_device *pdev,
834         struct resource *irq, void *dev_id)
835 {
836
837         if (!pdev || !irq || !dev_id) {
838                 pr_err("Invalid params\n");
839                 return -EINVAL;
840         }
841
842         CDBG("Un Registering irq for [resource - %pK]\n", irq);
843         devm_free_irq(&pdev->dev, irq->start, dev_id);
844
845         return 0;
846 }
847 EXPORT_SYMBOL(msm_camera_unregister_irq);
848
849 void __iomem *msm_camera_get_reg_base(struct platform_device *pdev,
850                 char *device_name, int reserve_mem)
851 {
852         struct resource *mem;
853         void *base;
854
855         if (!pdev || !device_name) {
856                 pr_err("Invalid params\n");
857                 return NULL;
858         }
859
860         CDBG("device name :%s\n", device_name);
861         mem = platform_get_resource_byname(pdev,
862                         IORESOURCE_MEM, device_name);
863         if (!mem) {
864                 pr_err("err: mem resource %s not found\n", device_name);
865                 return NULL;
866         }
867
868         if (reserve_mem) {
869                 CDBG("device:%pK, mem : %pK, size : %d\n",
870                         &pdev->dev, mem, (int)resource_size(mem));
871                 if (!devm_request_mem_region(&pdev->dev, mem->start,
872                         resource_size(mem),
873                         device_name)) {
874                         pr_err("err: no valid mem region for device:%s\n",
875                                 device_name);
876                         return NULL;
877                 }
878         }
879
880         base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
881         if (!base) {
882                 devm_release_mem_region(&pdev->dev, mem->start,
883                                 resource_size(mem));
884                 pr_err("err: ioremap failed: %s\n", device_name);
885                 return NULL;
886         }
887
888         CDBG("base : %pK\n", base);
889         return base;
890 }
891 EXPORT_SYMBOL(msm_camera_get_reg_base);
892
893 uint32_t msm_camera_get_res_size(struct platform_device *pdev,
894         char *device_name)
895 {
896         struct resource *mem;
897
898         if (!pdev || !device_name) {
899                 pr_err("Invalid params\n");
900                 return 0;
901         }
902
903         CDBG("device name :%s\n", device_name);
904         mem = platform_get_resource_byname(pdev,
905                 IORESOURCE_MEM, device_name);
906         if (!mem) {
907                 pr_err("err: mem resource %s not found\n", device_name);
908                 return 0;
909         }
910         return resource_size(mem);
911 }
912 EXPORT_SYMBOL(msm_camera_get_res_size);
913
914
915 int msm_camera_put_reg_base(struct platform_device *pdev,
916         void __iomem *base,     char *device_name, int reserve_mem)
917 {
918         struct resource *mem;
919
920         if (!pdev || !base || !device_name) {
921                 pr_err("Invalid params\n");
922                 return -EINVAL;
923         }
924
925         CDBG("device name :%s\n", device_name);
926         mem = platform_get_resource_byname(pdev,
927                         IORESOURCE_MEM, device_name);
928         if (!mem) {
929                 pr_err("err: mem resource %s not found\n", device_name);
930                 return -EINVAL;
931         }
932         CDBG("mem : %pK, size : %d\n", mem, (int)resource_size(mem));
933
934         devm_iounmap(&pdev->dev, base);
935         if (reserve_mem)
936                 devm_release_mem_region(&pdev->dev,
937                         mem->start, resource_size(mem));
938
939         return 0;
940 }
941 EXPORT_SYMBOL(msm_camera_put_reg_base);
942
943 /* Register the bus client */
944 uint32_t msm_camera_register_bus_client(struct platform_device *pdev,
945         enum cam_bus_client id)
946 {
947         int rc = 0;
948         uint32_t bus_client, num_usecases, num_paths;
949         struct msm_bus_scale_pdata *pdata;
950         struct device_node *of_node;
951
952         CDBG("Register client ID: %d\n", id);
953
954         if (id >= CAM_BUS_CLIENT_MAX || !pdev) {
955                 pr_err("Invalid params");
956                 return -EINVAL;
957         }
958
959         of_node = pdev->dev.of_node;
960
961         if (!g_cv[id].pdata) {
962                 rc = of_property_read_u32(of_node, "qcom,msm-bus,num-cases",
963                                 &num_usecases);
964                 if (rc) {
965                         pr_err("num-usecases not found\n");
966                         return -EINVAL;
967                 }
968                 rc = of_property_read_u32(of_node, "qcom,msm-bus,num-paths",
969                                 &num_paths);
970                 if (rc) {
971                         pr_err("num-usecases not found\n");
972                         return -EINVAL;
973                 }
974
975                 if (num_paths != 1) {
976                         pr_err("Exceeds number of paths\n");
977                         return -EINVAL;
978                 }
979
980                 if (of_property_read_bool(of_node,
981                                 "qcom,msm-bus-vector-dyn-vote")) {
982                         if (num_usecases != 2) {
983                                 pr_err("Excess or less vectors\n");
984                                 return -EINVAL;
985                         }
986                         g_cv[id].dyn_vote = true;
987                 }
988
989                 pdata = msm_bus_cl_get_pdata(pdev);
990                 if (!pdata) {
991                         pr_err("failed get_pdata client_id :%d\n", id);
992                         return -EINVAL;
993                 }
994                 bus_client = msm_bus_scale_register_client(pdata);
995                 if (!bus_client) {
996                         pr_err("Unable to register bus client :%d\n", id);
997                         return -EINVAL;
998                 }
999         } else {
1000                 pr_err("vector already setup client_id : %d\n", id);
1001                 return -EINVAL;
1002         }
1003
1004         g_cv[id].pdata = pdata;
1005         g_cv[id].bus_client = bus_client;
1006         g_cv[id].vector_index = 0;
1007         g_cv[id].num_usecases = num_usecases;
1008         g_cv[id].num_paths = num_paths;
1009         mutex_init(&g_cv[id].lock);
1010         CDBG("Exit Client ID: %d\n", id);
1011         return 0;
1012 }
1013 EXPORT_SYMBOL(msm_camera_register_bus_client);
1014
1015 /* Update the bus bandwidth */
1016 uint32_t msm_camera_update_bus_bw(int id, uint64_t ab, uint64_t ib)
1017 {
1018         struct msm_bus_paths *path;
1019         struct msm_bus_scale_pdata *pdata;
1020         int idx = 0;
1021
1022         if (id >= CAM_BUS_CLIENT_MAX) {
1023                 pr_err("Invalid params");
1024                 return -EINVAL;
1025         }
1026         if (g_cv[id].num_usecases != 2 ||
1027                 g_cv[id].num_paths != 1 ||
1028                 g_cv[id].dyn_vote != true) {
1029                 pr_err("dynamic update not allowed\n");
1030                 return -EINVAL;
1031         }
1032
1033         mutex_lock(&g_cv[id].lock);
1034         idx = g_cv[id].vector_index;
1035         idx = 1 - idx;
1036         g_cv[id].vector_index = idx;
1037         mutex_unlock(&g_cv[id].lock);
1038
1039         pdata = g_cv[id].pdata;
1040         path = &(pdata->usecase[idx]);
1041         path->vectors[0].ab = ab;
1042         path->vectors[0].ib = ib;
1043
1044         CDBG("Register client ID : %d [ab : %llx, ib : %llx], update :%d\n",
1045                 id, ab, ib, idx);
1046         msm_bus_scale_client_update_request(g_cv[id].bus_client, idx);
1047
1048         return 0;
1049 }
1050 EXPORT_SYMBOL(msm_camera_update_bus_bw);
1051
1052 /* Update the bus vector */
1053 uint32_t msm_camera_update_bus_vector(enum cam_bus_client id,
1054         int vector_index)
1055 {
1056         if (id >= CAM_BUS_CLIENT_MAX || g_cv[id].dyn_vote == true) {
1057                 pr_err("Invalid params");
1058                 return -EINVAL;
1059         }
1060
1061         if (vector_index < 0 || vector_index > g_cv[id].num_usecases) {
1062                 pr_err("Invalid params");
1063                 return -EINVAL;
1064         }
1065
1066         CDBG("Register client ID : %d vector idx: %d,\n", id, vector_index);
1067         msm_bus_scale_client_update_request(g_cv[id].bus_client,
1068                 vector_index);
1069
1070         return 0;
1071 }
1072 EXPORT_SYMBOL(msm_camera_update_bus_vector);
1073
1074 /* Unregister the bus client */
1075 uint32_t msm_camera_unregister_bus_client(enum cam_bus_client id)
1076 {
1077         if (id >= CAM_BUS_CLIENT_MAX) {
1078                 pr_err("Invalid params");
1079                 return -EINVAL;
1080         }
1081
1082         CDBG("UnRegister client ID: %d\n", id);
1083
1084         mutex_destroy(&g_cv[id].lock);
1085         msm_bus_scale_unregister_client(g_cv[id].bus_client);
1086         g_cv[id].bus_client = 0;
1087         g_cv[id].num_usecases = 0;
1088         g_cv[id].num_paths = 0;
1089         g_cv[id].vector_index = 0;
1090         g_cv[id].dyn_vote = 0;
1091
1092         return 0;
1093 }
1094 EXPORT_SYMBOL(msm_camera_unregister_bus_client);