Merge commit 'v2.6.32-rc3'
[pandora-kernel.git] / drivers / staging / dream / camera / msm_vfe8x.c
1 /*
2  * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3  */
4 #include <linux/uaccess.h>
5 #include <linux/interrupt.h>
6 #include <mach/irqs.h>
7 #include "msm_vfe8x_proc.h"
8
9 #define ON  1
10 #define OFF 0
11
12 struct mutex vfe_lock;
13 static void     *vfe_syncdata;
14
15 static int vfe_enable(struct camera_enable_cmd *enable)
16 {
17         int rc = 0;
18         return rc;
19 }
20
21 static int vfe_disable(struct camera_enable_cmd *enable,
22         struct platform_device *dev)
23 {
24         int rc = 0;
25
26         vfe_stop();
27
28         msm_camio_disable(dev);
29         return rc;
30 }
31
32 static void vfe_release(struct platform_device *dev)
33 {
34         msm_camio_disable(dev);
35         vfe_cmd_release(dev);
36
37         mutex_lock(&vfe_lock);
38         vfe_syncdata = NULL;
39         mutex_unlock(&vfe_lock);
40 }
41
42 static void vfe_config_axi(int mode,
43         struct axidata *ad, struct vfe_cmd_axi_output_config *ao)
44 {
45         struct msm_pmem_region *regptr;
46         int i, j;
47         uint32_t *p1, *p2;
48
49         if (mode == OUTPUT_1 || mode == OUTPUT_1_AND_2) {
50                 regptr = ad->region;
51                 for (i = 0;
52                         i < ad->bufnum1; i++) {
53
54                         p1 = &(ao->output1.outputY.outFragments[i][0]);
55                         p2 = &(ao->output1.outputCbcr.outFragments[i][0]);
56
57                         for (j = 0;
58                                 j < ao->output1.fragmentCount; j++) {
59
60                                 *p1 = regptr->paddr + regptr->y_off;
61                                 p1++;
62
63                                 *p2 = regptr->paddr + regptr->cbcr_off;
64                                 p2++;
65                         }
66                         regptr++;
67                 }
68         } /* if OUTPUT1 or Both */
69
70         if (mode == OUTPUT_2 || mode == OUTPUT_1_AND_2) {
71
72                 regptr = &(ad->region[ad->bufnum1]);
73                 CDBG("bufnum2 = %d\n", ad->bufnum2);
74
75                 for (i = 0;
76                         i < ad->bufnum2; i++) {
77
78                         p1 = &(ao->output2.outputY.outFragments[i][0]);
79                         p2 = &(ao->output2.outputCbcr.outFragments[i][0]);
80
81                 CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, cbcr_off = %d\n",
82                         regptr->paddr, regptr->y_off, regptr->cbcr_off);
83
84                         for (j = 0;
85                                 j < ao->output2.fragmentCount; j++) {
86
87                                 *p1 = regptr->paddr + regptr->y_off;
88                                 CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
89                                 p1++;
90
91                                 *p2 = regptr->paddr + regptr->cbcr_off;
92                                 CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
93                                 p2++;
94                         }
95                         regptr++;
96                 }
97         }
98 }
99
100 static int vfe_proc_general(struct msm_vfe_command_8k *cmd)
101 {
102         int rc = 0;
103
104         CDBG("vfe_proc_general: cmdID = %d\n", cmd->id);
105
106         switch (cmd->id) {
107         case VFE_CMD_ID_RESET:
108                 msm_camio_vfe_blk_reset();
109                 msm_camio_camif_pad_reg_reset_2();
110                 vfe_reset();
111                 break;
112
113         case VFE_CMD_ID_START: {
114                 struct vfe_cmd_start start;
115                 if (copy_from_user(&start,
116                         (void __user *) cmd->value, cmd->length))
117                         rc = -EFAULT;
118
119                 /* msm_camio_camif_pad_reg_reset_2(); */
120                 msm_camio_camif_pad_reg_reset();
121                 vfe_start(&start);
122         }
123                 break;
124
125         case VFE_CMD_ID_CAMIF_CONFIG: {
126                 struct vfe_cmd_camif_config camif;
127                 if (copy_from_user(&camif,
128                         (void __user *) cmd->value, cmd->length))
129                         rc = -EFAULT;
130
131                 vfe_camif_config(&camif);
132         }
133                 break;
134
135         case VFE_CMD_ID_BLACK_LEVEL_CONFIG: {
136                 struct vfe_cmd_black_level_config bl;
137                 if (copy_from_user(&bl,
138                         (void __user *) cmd->value, cmd->length))
139                         rc = -EFAULT;
140
141                 vfe_black_level_config(&bl);
142         }
143                 break;
144
145         case VFE_CMD_ID_ROLL_OFF_CONFIG: {
146                 struct vfe_cmd_roll_off_config rolloff;
147                 if (copy_from_user(&rolloff,
148                         (void __user *) cmd->value, cmd->length))
149                         rc = -EFAULT;
150
151                 vfe_roll_off_config(&rolloff);
152         }
153                 break;
154
155         case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_CONFIG: {
156                 struct vfe_cmd_demux_channel_gain_config demuxc;
157                 if (copy_from_user(&demuxc,
158                         (void __user *) cmd->value, cmd->length))
159                         rc = -EFAULT;
160
161                 /* demux is always enabled.  */
162                 vfe_demux_channel_gain_config(&demuxc);
163         }
164                 break;
165
166         case VFE_CMD_ID_DEMOSAIC_CONFIG: {
167                 struct vfe_cmd_demosaic_config demosaic;
168                 if (copy_from_user(&demosaic,
169                         (void __user *) cmd->value, cmd->length))
170                         rc = -EFAULT;
171
172                 vfe_demosaic_config(&demosaic);
173         }
174                 break;
175
176         case VFE_CMD_ID_FOV_CROP_CONFIG:
177         case VFE_CMD_ID_FOV_CROP_UPDATE: {
178                 struct vfe_cmd_fov_crop_config fov;
179                 if (copy_from_user(&fov,
180                         (void __user *) cmd->value, cmd->length))
181                         rc = -EFAULT;
182
183                 vfe_fov_crop_config(&fov);
184         }
185                 break;
186
187         case VFE_CMD_ID_MAIN_SCALER_CONFIG:
188         case VFE_CMD_ID_MAIN_SCALER_UPDATE: {
189                 struct vfe_cmd_main_scaler_config mainds;
190                 if (copy_from_user(&mainds,
191                         (void __user *) cmd->value, cmd->length))
192                         rc = -EFAULT;
193
194                 vfe_main_scaler_config(&mainds);
195         }
196                 break;
197
198         case VFE_CMD_ID_WHITE_BALANCE_CONFIG:
199         case VFE_CMD_ID_WHITE_BALANCE_UPDATE: {
200                 struct vfe_cmd_white_balance_config wb;
201                 if (copy_from_user(&wb,
202                         (void __user *) cmd->value, cmd->length))
203                         rc = -EFAULT;
204
205                 vfe_white_balance_config(&wb);
206         }
207                 break;
208
209         case VFE_CMD_ID_COLOR_CORRECTION_CONFIG:
210         case VFE_CMD_ID_COLOR_CORRECTION_UPDATE: {
211                 struct vfe_cmd_color_correction_config cc;
212                 if (copy_from_user(&cc,
213                         (void __user *) cmd->value, cmd->length))
214                         rc = -EFAULT;
215
216                 vfe_color_correction_config(&cc);
217         }
218                 break;
219
220         case VFE_CMD_ID_LA_CONFIG: {
221                 struct vfe_cmd_la_config la;
222                 if (copy_from_user(&la,
223                         (void __user *) cmd->value, cmd->length))
224                         rc = -EFAULT;
225
226                 vfe_la_config(&la);
227         }
228                 break;
229
230         case VFE_CMD_ID_RGB_GAMMA_CONFIG: {
231                 struct vfe_cmd_rgb_gamma_config rgb;
232                 if (copy_from_user(&rgb,
233                         (void __user *) cmd->value, cmd->length))
234                         rc = -EFAULT;
235
236                 rc = vfe_rgb_gamma_config(&rgb);
237         }
238                 break;
239
240         case VFE_CMD_ID_CHROMA_ENHAN_CONFIG:
241         case VFE_CMD_ID_CHROMA_ENHAN_UPDATE: {
242                 struct vfe_cmd_chroma_enhan_config chrom;
243                 if (copy_from_user(&chrom,
244                         (void __user *) cmd->value, cmd->length))
245                         rc = -EFAULT;
246
247                 vfe_chroma_enhan_config(&chrom);
248         }
249                 break;
250
251         case VFE_CMD_ID_CHROMA_SUPPRESSION_CONFIG:
252         case VFE_CMD_ID_CHROMA_SUPPRESSION_UPDATE: {
253                 struct vfe_cmd_chroma_suppression_config chromsup;
254                 if (copy_from_user(&chromsup,
255                         (void __user *) cmd->value, cmd->length))
256                         rc = -EFAULT;
257
258                 vfe_chroma_sup_config(&chromsup);
259         }
260                 break;
261
262         case VFE_CMD_ID_ASF_CONFIG: {
263                 struct vfe_cmd_asf_config asf;
264                 if (copy_from_user(&asf,
265                         (void __user *) cmd->value, cmd->length))
266                         rc = -EFAULT;
267
268                 vfe_asf_config(&asf);
269         }
270                 break;
271
272         case VFE_CMD_ID_SCALER2Y_CONFIG:
273         case VFE_CMD_ID_SCALER2Y_UPDATE: {
274                 struct vfe_cmd_scaler2_config ds2y;
275                 if (copy_from_user(&ds2y,
276                         (void __user *) cmd->value, cmd->length))
277                         rc = -EFAULT;
278
279                 vfe_scaler2y_config(&ds2y);
280         }
281                 break;
282
283         case VFE_CMD_ID_SCALER2CbCr_CONFIG:
284         case VFE_CMD_ID_SCALER2CbCr_UPDATE: {
285                 struct vfe_cmd_scaler2_config ds2cbcr;
286                 if (copy_from_user(&ds2cbcr,
287                         (void __user *) cmd->value, cmd->length))
288                         rc = -EFAULT;
289
290                 vfe_scaler2cbcr_config(&ds2cbcr);
291         }
292                 break;
293
294         case VFE_CMD_ID_CHROMA_SUBSAMPLE_CONFIG: {
295                 struct vfe_cmd_chroma_subsample_config sub;
296                 if (copy_from_user(&sub,
297                         (void __user *) cmd->value, cmd->length))
298                         rc = -EFAULT;
299
300                 vfe_chroma_subsample_config(&sub);
301         }
302                 break;
303
304         case VFE_CMD_ID_FRAME_SKIP_CONFIG: {
305                 struct vfe_cmd_frame_skip_config fskip;
306                 if (copy_from_user(&fskip,
307                         (void __user *) cmd->value, cmd->length))
308                         rc = -EFAULT;
309
310                 vfe_frame_skip_config(&fskip);
311         }
312                 break;
313
314         case VFE_CMD_ID_OUTPUT_CLAMP_CONFIG: {
315                 struct vfe_cmd_output_clamp_config clamp;
316                 if (copy_from_user(&clamp,
317                         (void __user *) cmd->value, cmd->length))
318                         rc = -EFAULT;
319
320                 vfe_output_clamp_config(&clamp);
321         }
322                 break;
323
324         /* module update commands */
325         case VFE_CMD_ID_BLACK_LEVEL_UPDATE: {
326                 struct vfe_cmd_black_level_config blk;
327                 if (copy_from_user(&blk,
328                         (void __user *) cmd->value, cmd->length))
329                         rc = -EFAULT;
330
331                 vfe_black_level_update(&blk);
332         }
333                 break;
334
335         case VFE_CMD_ID_DEMUX_CHANNEL_GAIN_UPDATE: {
336                 struct vfe_cmd_demux_channel_gain_config dmu;
337                 if (copy_from_user(&dmu,
338                         (void __user *) cmd->value, cmd->length))
339                         rc = -EFAULT;
340
341                 vfe_demux_channel_gain_update(&dmu);
342         }
343                 break;
344
345         case VFE_CMD_ID_DEMOSAIC_BPC_UPDATE: {
346                 struct vfe_cmd_demosaic_bpc_update demo_bpc;
347                 if (copy_from_user(&demo_bpc,
348                         (void __user *) cmd->value, cmd->length))
349                         rc = -EFAULT;
350
351                 vfe_demosaic_bpc_update(&demo_bpc);
352         }
353                 break;
354
355         case VFE_CMD_ID_DEMOSAIC_ABF_UPDATE: {
356                 struct vfe_cmd_demosaic_abf_update demo_abf;
357                 if (copy_from_user(&demo_abf,
358                         (void __user *) cmd->value, cmd->length))
359                         rc = -EFAULT;
360
361                 vfe_demosaic_abf_update(&demo_abf);
362         }
363                 break;
364
365         case VFE_CMD_ID_LA_UPDATE: {
366                 struct vfe_cmd_la_config la;
367                 if (copy_from_user(&la,
368                         (void __user *) cmd->value, cmd->length))
369                         rc = -EFAULT;
370
371                 vfe_la_update(&la);
372         }
373                 break;
374
375         case VFE_CMD_ID_RGB_GAMMA_UPDATE: {
376                 struct vfe_cmd_rgb_gamma_config rgb;
377                 if (copy_from_user(&rgb,
378                         (void __user *) cmd->value, cmd->length))
379                         rc = -EFAULT;
380
381                 rc = vfe_rgb_gamma_update(&rgb);
382         }
383                 break;
384
385         case VFE_CMD_ID_ASF_UPDATE: {
386                 struct vfe_cmd_asf_update asf;
387                 if (copy_from_user(&asf,
388                         (void __user *) cmd->value, cmd->length))
389                         rc = -EFAULT;
390
391                 vfe_asf_update(&asf);
392         }
393                 break;
394
395         case VFE_CMD_ID_FRAME_SKIP_UPDATE: {
396                 struct vfe_cmd_frame_skip_update fskip;
397                 if (copy_from_user(&fskip,
398                         (void __user *) cmd->value, cmd->length))
399                         rc = -EFAULT;
400
401                 vfe_frame_skip_update(&fskip);
402         }
403                 break;
404
405         case VFE_CMD_ID_CAMIF_FRAME_UPDATE: {
406                 struct vfe_cmds_camif_frame fup;
407                 if (copy_from_user(&fup,
408                         (void __user *) cmd->value, cmd->length))
409                         rc = -EFAULT;
410
411                 vfe_camif_frame_update(&fup);
412         }
413                 break;
414
415         /* stats update commands */
416         case VFE_CMD_ID_STATS_AUTOFOCUS_UPDATE: {
417                 struct vfe_cmd_stats_af_update afup;
418                 if (copy_from_user(&afup,
419                         (void __user *) cmd->value, cmd->length))
420                         rc = -EFAULT;
421
422                 vfe_stats_update_af(&afup);
423         }
424                 break;
425
426         case VFE_CMD_ID_STATS_WB_EXP_UPDATE: {
427                 struct vfe_cmd_stats_wb_exp_update wbexp;
428                 if (copy_from_user(&wbexp,
429                         (void __user *) cmd->value, cmd->length))
430                         rc = -EFAULT;
431
432                 vfe_stats_update_wb_exp(&wbexp);
433         }
434                 break;
435
436         /* control of start, stop, update, etc... */
437         case VFE_CMD_ID_STOP:
438                 vfe_stop();
439                 break;
440
441         case VFE_CMD_ID_GET_HW_VERSION:
442                 break;
443
444         /* stats */
445         case VFE_CMD_ID_STATS_SETTING: {
446                 struct vfe_cmd_stats_setting stats;
447                 if (copy_from_user(&stats,
448                         (void __user *) cmd->value, cmd->length))
449                         rc = -EFAULT;
450
451                 vfe_stats_setting(&stats);
452         }
453                 break;
454
455         case VFE_CMD_ID_STATS_AUTOFOCUS_START: {
456                 struct vfe_cmd_stats_af_start af;
457                 if (copy_from_user(&af,
458                         (void __user *) cmd->value, cmd->length))
459                         rc = -EFAULT;
460
461                 vfe_stats_start_af(&af);
462         }
463                 break;
464
465         case VFE_CMD_ID_STATS_AUTOFOCUS_STOP:
466                 vfe_stats_af_stop();
467                 break;
468
469         case VFE_CMD_ID_STATS_WB_EXP_START: {
470                 struct vfe_cmd_stats_wb_exp_start awexp;
471                 if (copy_from_user(&awexp,
472                         (void __user *) cmd->value, cmd->length))
473                         rc = -EFAULT;
474
475                 vfe_stats_start_wb_exp(&awexp);
476         }
477                 break;
478
479         case VFE_CMD_ID_STATS_WB_EXP_STOP:
480                 vfe_stats_wb_exp_stop();
481                 break;
482
483         case VFE_CMD_ID_ASYNC_TIMER_SETTING:
484                 break;
485
486         case VFE_CMD_ID_UPDATE:
487                 vfe_update();
488                 break;
489
490         /* test gen */
491         case VFE_CMD_ID_TEST_GEN_START:
492                 break;
493
494 /*
495   acknowledge from upper layer
496         these are not in general command.
497
498         case VFE_CMD_ID_OUTPUT1_ACK:
499                 break;
500         case VFE_CMD_ID_OUTPUT2_ACK:
501                 break;
502         case VFE_CMD_ID_EPOCH1_ACK:
503                 break;
504         case VFE_CMD_ID_EPOCH2_ACK:
505                 break;
506         case VFE_CMD_ID_STATS_AUTOFOCUS_ACK:
507                 break;
508         case VFE_CMD_ID_STATS_WB_EXP_ACK:
509                 break;
510 */
511
512         default:
513                 break;
514         } /* switch */
515
516         return rc;
517 }
518
519 static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
520 {
521         struct msm_pmem_region *regptr;
522         struct msm_vfe_command_8k vfecmd;
523
524         uint32_t i;
525
526         void *cmd_data = NULL;
527         long rc = 0;
528
529         struct vfe_cmd_axi_output_config *axio = NULL;
530         struct vfe_cmd_stats_setting *scfg = NULL;
531
532         if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
533             cmd->cmd_type != CMD_STATS_BUF_RELEASE) {
534
535                 if (copy_from_user(&vfecmd,
536                                 (void __user *)(cmd->value),
537                                 sizeof(struct msm_vfe_command_8k)))
538                         return -EFAULT;
539         }
540
541         CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);
542
543         switch (cmd->cmd_type) {
544         case CMD_GENERAL:
545                 rc = vfe_proc_general(&vfecmd);
546                 break;
547
548         case CMD_STATS_ENABLE:
549         case CMD_STATS_AXI_CFG: {
550                 struct axidata *axid;
551
552                 axid = data;
553                 if (!axid)
554                         return -EFAULT;
555
556                 scfg =
557                         kmalloc(sizeof(struct vfe_cmd_stats_setting),
558                                 GFP_ATOMIC);
559                 if (!scfg)
560                         return -ENOMEM;
561
562                 if (copy_from_user(scfg,
563                                         (void __user *)(vfecmd.value),
564                                         vfecmd.length)) {
565
566                         kfree(scfg);
567                         return -EFAULT;
568                 }
569
570                 regptr = axid->region;
571                 if (axid->bufnum1 > 0) {
572                         for (i = 0; i < axid->bufnum1; i++) {
573                                 scfg->awbBuffer[i] =
574                                         (uint32_t)(regptr->paddr);
575                                 regptr++;
576                         }
577                 }
578
579                 if (axid->bufnum2 > 0) {
580                         for (i = 0; i < axid->bufnum2; i++) {
581                                 scfg->afBuffer[i] =
582                                         (uint32_t)(regptr->paddr);
583                                 regptr++;
584                         }
585                 }
586
587                 vfe_stats_config(scfg);
588         }
589                 break;
590
591         case CMD_STATS_AF_AXI_CFG: {
592         }
593                 break;
594
595         case CMD_FRAME_BUF_RELEASE: {
596                 /* preview buffer release */
597                 struct msm_frame *b;
598                 unsigned long p;
599                 struct vfe_cmd_output_ack fack;
600
601                 if (!data)
602                         return -EFAULT;
603
604                 b = (struct msm_frame *)(cmd->value);
605                 p = *(unsigned long *)data;
606
607                 b->path = MSM_FRAME_ENC;
608
609                 fack.ybufaddr[0] =
610                         (uint32_t)(p + b->y_off);
611
612                 fack.chromabufaddr[0] =
613                         (uint32_t)(p + b->cbcr_off);
614
615                 if (b->path == MSM_FRAME_PREV_1)
616                         vfe_output1_ack(&fack);
617
618                 if (b->path == MSM_FRAME_ENC ||
619                     b->path == MSM_FRAME_PREV_2)
620                         vfe_output2_ack(&fack);
621         }
622                 break;
623
624         case CMD_SNAP_BUF_RELEASE: {
625         }
626                 break;
627
628         case CMD_STATS_BUF_RELEASE: {
629                 struct vfe_cmd_stats_wb_exp_ack sack;
630
631                 if (!data)
632                         return -EFAULT;
633
634                 sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
635                 vfe_stats_wb_exp_ack(&sack);
636         }
637                 break;
638
639         case CMD_AXI_CFG_OUT1: {
640                 struct axidata *axid;
641
642                 axid = data;
643                 if (!axid)
644                         return -EFAULT;
645
646                 axio =
647                         kmalloc(sizeof(struct vfe_cmd_axi_output_config),
648                                 GFP_ATOMIC);
649                 if (!axio)
650                         return -ENOMEM;
651
652                 if (copy_from_user(axio, (void __user *)(vfecmd.value),
653                         sizeof(struct vfe_cmd_axi_output_config))) {
654                         kfree(axio);
655                         return -EFAULT;
656                 }
657
658                 vfe_config_axi(OUTPUT_1, axid, axio);
659                 vfe_axi_output_config(axio);
660         }
661                 break;
662
663         case CMD_AXI_CFG_OUT2:
664         case CMD_RAW_PICT_AXI_CFG: {
665                 struct axidata *axid;
666
667                 axid = data;
668                 if (!axid)
669                         return -EFAULT;
670
671                 axio =
672                         kmalloc(sizeof(struct vfe_cmd_axi_output_config),
673                                 GFP_ATOMIC);
674                 if (!axio)
675                         return -ENOMEM;
676
677                 if (copy_from_user(axio, (void __user *)(vfecmd.value),
678                                 sizeof(struct vfe_cmd_axi_output_config))) {
679                         kfree(axio);
680                         return -EFAULT;
681                 }
682
683                 vfe_config_axi(OUTPUT_2, axid, axio);
684
685                 axio->outputDataSize = 0;
686                 vfe_axi_output_config(axio);
687         }
688                 break;
689
690         case CMD_AXI_CFG_SNAP_O1_AND_O2: {
691                 struct axidata *axid;
692                 axid = data;
693                 if (!axid)
694                         return -EFAULT;
695
696                 axio =
697                         kmalloc(sizeof(struct vfe_cmd_axi_output_config),
698                                 GFP_ATOMIC);
699                 if (!axio)
700                         return -ENOMEM;
701
702                 if (copy_from_user(axio, (void __user *)(vfecmd.value),
703                         sizeof(struct vfe_cmd_axi_output_config))) {
704                         kfree(axio);
705                         return -EFAULT;
706                 }
707
708                 vfe_config_axi(OUTPUT_1_AND_2,
709                         axid, axio);
710                 vfe_axi_output_config(axio);
711                 cmd_data = axio;
712         }
713                 break;
714
715         default:
716                 break;
717         } /* switch */
718
719         kfree(scfg);
720
721         kfree(axio);
722
723 /*
724         if (cmd->length > 256 &&
725                         cmd_data &&
726                         (cmd->cmd_type == CMD_GENERAL ||
727                          cmd->cmd_type == CMD_STATS_DISABLE)) {
728                 kfree(cmd_data);
729         }
730 */
731         return rc;
732 }
733
734 static int vfe_init(struct msm_vfe_callback *presp,
735         struct platform_device *dev)
736 {
737         int rc = 0;
738
739         rc = vfe_cmd_init(presp, dev, vfe_syncdata);
740         if (rc < 0)
741                 return rc;
742
743         /* Bring up all the required GPIOs and Clocks */
744         return msm_camio_enable(dev);
745 }
746
747 void msm_camvfe_fn_init(struct msm_camvfe_fn *fptr, void *data)
748 {
749         mutex_init(&vfe_lock);
750         fptr->vfe_init    = vfe_init;
751         fptr->vfe_enable  = vfe_enable;
752         fptr->vfe_config  = vfe_config;
753         fptr->vfe_disable = vfe_disable;
754         fptr->vfe_release = vfe_release;
755         vfe_syncdata = data;
756 }