995df3a7da85a758dc4e3fe3b9c40439e037f3b6
[adaptation/intel_mfld/gst-plugins-atomisp.git] / gst-libs / atomisphal / mfld_driver.c
1 /* Gstreamer MFLD camera source abstract Layer API
2  * Copyright (c) 2010 Intel Corporation
3
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * This file provide the IOCTL wrap to the Medfield v4l2 drivers
22  * It provides the following features.
23  * Image stablization
24  * Video stablization
25  * Skin tone detection/correction FIXME
26  * Image effect (Color Sapce Convertion)
27  * Noise Reduction (XNR, TNR, BNR, YNR FPN)
28  * Color Enhance Ment
29  * Edege Enhancement
30  * False Color Correction
31  * MACC
32  * Bad Pixel detection
33  * Lens shading correction
34  * black level
35  *
36  * digital zoom
37  * gamma
38  * tone control FIXME
39  * YUV scaler FIXME
40  * CAC/GDC
41  * super impose FIXME
42  *
43  * Bayer Scaling ?
44  *
45  */
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <math.h>
50 #include <errno.h>
51 #include <stdarg.h>
52 #include "mfld_driver.h"
53 #include "sh_css_types.h"
54 #include "atomisp_v4l2.h"
55 #include "atomisp.h"
56 #define CAM_ISP_IS_OPEN(fd)     (fd > 0)
57
58 static int
59 xioctl (int fd, int request, void *arg, const char *name)
60 {
61   int ret;
62
63   cam_driver_dbg ("ioctl %s ", name);
64
65   do {
66     ret = ioctl (fd, request, arg);
67   } while (-1 == ret && EINTR == errno);
68
69   if (ret < 0)
70     cam_driver_dbg ("failed: %s\n", strerror (errno));
71   else
72     cam_driver_dbg ("ok\n");
73
74   return ret;
75 }
76
77 /* Utilities for debug message and error message output
78  * */
79 void
80 cam_driver_dbg (const char *format, ...)
81 {
82   va_list ap;
83   const char *env;
84   if ((env = getenv ("LIBMFLDCAM_DEBUG")) && strstr (env, "verbose")) {
85     va_start (ap, format);
86     vfprintf (stdout, format, ap);
87     va_end (ap);
88   }
89 }
90
91 static const char *cameralib_error_map[] = {
92   "CAM_ERR_NONE",
93   "CAM_ERR_PARAM",
94   "CAM_ERR_UNSUPP",
95   "CAM_ERR_HW",
96   "CAM_ERR_NOT_OPEN",
97   "CAM_ERR_SYS",
98   "CAM_ERR_LEXIT",
99   "CAM_ERR_DEPRECATED",
100   "CAM_ERR_INVALID_STATE",
101   "CAM_ERR_INTERNAL",
102   "CAM_ERR_3A"
103 };
104
105 void
106 cam_err_print (cam_err_t err)
107 {
108   if ((err < CAM_ERR_NONE) || (err > CAM_ERR_3A)) {
109     cam_driver_dbg (" %s Wrong error number in lib camera\n", __func__);
110     return;
111   }
112
113   cam_driver_dbg ("%s\n", cameralib_error_map[err]);
114 }
115
116 /******************************************************
117  * cam_driver_get_attribute():
118  *   try to get the value of one specific attribute
119  * return value: CAM_ERR_NONE for success
120  *               others are errors
121  ******************************************************/
122 cam_err_t
123 cam_driver_get_attribute (int fd, int attribute_num, int *value, char *name)
124 {
125   struct v4l2_control control;
126
127   cam_driver_dbg ("getting value of attribute %d: %s\n", attribute_num, name);
128
129   if (!CAM_ISP_IS_OPEN (fd))
130     return CAM_ERR_NOT_OPEN;
131
132   control.id = attribute_num;
133
134   if (ioctl (fd, VIDIOC_G_CTRL, &control) < 0)
135     goto ctrl_failed1;
136
137   *value = control.value;
138
139   return CAM_ERR_NONE;
140
141 ctrl_failed1:
142   {
143     struct v4l2_ext_controls controls;
144     struct v4l2_ext_control control;
145
146     controls.ctrl_class = V4L2_CTRL_CLASS_USER;
147     controls.count = 1;
148     controls.controls = &control;
149
150     control.id = attribute_num;
151
152     if (ioctl (fd, VIDIOC_G_EXT_CTRLS, &controls) < 0)
153       goto ctrl_failed2;
154
155     *value = control.value;
156
157     return CAM_ERR_NONE;
158
159   }
160
161 ctrl_failed2:
162   {
163     struct v4l2_ext_controls controls;
164     struct v4l2_ext_control control;
165
166     controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
167     controls.count = 1;
168     controls.controls = &control;
169
170     control.id = attribute_num;
171
172     if (ioctl (fd, VIDIOC_G_EXT_CTRLS, &controls) < 0)
173       goto ctrl_failed3;
174
175     *value = control.value;
176
177     return CAM_ERR_NONE;
178
179   }
180
181   /* ERRORS */
182 ctrl_failed3:
183   {
184     cam_driver_dbg ("Failed to get value for control %d on device '%d'.",
185         attribute_num, fd);
186     return CAM_ERR_SYS;
187   }
188 }
189
190 /******************************************************
191  * cam_driver_set_attribute():
192  *   try to set the value of one specific attribute
193  * return value: CAM_ERR_NONE for success
194  *                               others are errors
195  ******************************************************/
196 cam_err_t
197 cam_driver_set_attribute (int fd, int attribute_num, const int value,
198                           const char *name)
199 {
200   struct v4l2_control control;
201
202   cam_driver_dbg ("setting value of attribute [%s] to %d\n", name, value);
203
204   if (!CAM_ISP_IS_OPEN (fd))
205     return CAM_ERR_NOT_OPEN;
206
207   control.id = attribute_num;
208   control.value = value;
209   if (ioctl (fd, VIDIOC_S_CTRL, &control) < 0)
210     goto ctrl_failed1;
211
212   return CAM_ERR_NONE;
213
214 ctrl_failed1:
215   {
216     struct v4l2_ext_controls controls;
217     struct v4l2_ext_control control;
218
219     controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
220     controls.count = 1;
221     controls.controls = &control;
222
223     control.id = attribute_num;
224     control.value = value;
225
226     if (ioctl (fd, VIDIOC_S_EXT_CTRLS, &controls) < 0)
227       goto ctrl_failed2;
228
229     return CAM_ERR_NONE;
230   }
231
232 ctrl_failed2:
233   {
234     struct v4l2_ext_controls controls;
235     struct v4l2_ext_control control;
236
237     controls.ctrl_class = V4L2_CTRL_CLASS_USER;
238     controls.count = 1;
239     controls.controls = &control;
240
241     control.id = attribute_num;
242     control.value = value;
243
244     if (ioctl (fd, VIDIOC_S_EXT_CTRLS, &controls) < 0)
245       goto ctrl_failed3;
246
247     return CAM_ERR_NONE;
248   }
249
250   /* ERRORS */
251 ctrl_failed3:
252   {
253     cam_driver_dbg
254         ("Failed to set value %d for control %d on device '%d', %s\n.", value,
255         attribute_num, fd, strerror (errno));
256     return CAM_ERR_SYS;
257   }
258 }
259
260 static struct atomisp_gamma_table g_gamma_table;
261
262 /* Gamma configuration
263  * Also used by extended dymanic range and tone control
264  */
265 struct Camera_gm_config
266 {
267   /* [gain]      1.0..2.4    Gamma value.  */
268   float GmVal;
269   int GmToe;                    /* [intensity]        Toe position of S-curve. */
270   int GmKne;                    /* [intensity]        Knee position of S-curve */
271
272   /* [gain]      100%..400%  Magnification factor of dynamic range
273    * (1.0 for normal dynamic range) */
274   int GmDyr;
275
276   /* Minimum output levels: Set to   0 for 256 full 8it level output or
277    * 16 for ITU.R601 16-235 output.*/
278   unsigned char GmLevelMin;
279   /* Maximum output levels: Set to 128 for 256 full 8it level output or
280    * 235 for ITU.R601 16-235 output */
281   unsigned char GmLevelMax;
282 };
283
284 static struct Camera_gm_config g_cfg_gm = {
285   .GmVal = 1.5,
286   .GmToe = 123,
287   .GmKne = 287,
288   .GmDyr = 256,
289   .GmLevelMin = 0,
290   .GmLevelMax = 255,
291 };
292
293 /*
294   Make gamma table
295 */
296 static void
297 AutoGmLut (unsigned short *pptDst, struct Camera_gm_config *cfg_gm)
298 {
299   /* cannot use this on cirrus because of missing powf implementation */
300   const double adbToe = (double) (cfg_gm->GmToe) / 1024.;       // [u5.11] -> double
301   const double adbKnee = (double) (cfg_gm->GmKne) / 1024.;      // [u5.11] -> double
302   const double adbDRange = (double) (cfg_gm->GmDyr) / 256.;     // [u8.8] -> double
303   const double adbReGammaVal = 1 / (double) (cfg_gm->GmVal);    // 1/GmVal : [u8.8] -> double
304   const double adbTmpKnee =
305       adbKnee / (adbDRange * adbKnee + adbDRange - adbKnee);
306   const double adbTmpToe =
307       ((1. + adbTmpKnee) * adbToe * adbKnee) / (adbDRange * (1. +
308           adbKnee) * adbTmpKnee);
309   const double adbDx = 1. / (double) 1024;      /* 1024 is the gamma table size */
310   double adbX = (double) 0.;
311   int asiCnt;
312
313   for (asiCnt = 0; asiCnt < 1024; asiCnt++, adbX += adbDx) {
314     const double adbDeno = (1. + adbTmpToe) * (1. + adbTmpKnee) * adbX * adbX;
315     const double adbNume = (adbX + adbTmpToe) * (adbX + adbTmpKnee);
316     const double adbY =
317         (adbNume == 0.) ? 0. : pow (adbDeno / adbNume, adbReGammaVal);
318     short auiTmp = (short) ((double) 255 * adbY + 0.5);
319
320     if (auiTmp < cfg_gm->GmLevelMin) {
321       auiTmp = cfg_gm->GmLevelMin;
322     } else if (auiTmp > cfg_gm->GmLevelMax) {
323       auiTmp = cfg_gm->GmLevelMax;
324     }
325     pptDst[asiCnt] = auiTmp;
326   }
327 }
328
329 cam_err_t
330 cam_driver_set_fpn (int fd, int on)
331 {
332   return CAM_ERR_NONE;
333 }
334
335 cam_err_t
336 cam_driver_set_sc (int fd, int on)
337 {
338 // TODO check this
339   return CAM_ERR_NONE;
340 }
341
342 /* Bad Pixel Detection*/
343 cam_err_t
344 cam_driver_set_bpd (int fd, int on)
345 {
346   return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
347       on, "Bad Pixel Detection");
348 }
349 cam_err_t
350 cam_driver_get_bpd (int fd, int *on)
351 {
352   return cam_driver_get_attribute (fd, V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
353       on, "Bad Pixel Detection");
354 }
355
356 cam_err_t
357 cam_driver_set_bnr (int fd, int on)
358 {
359   struct atomisp_nr_config bnr;
360   if (on) {
361     bnr.bnr_gain = 60000;
362     bnr.direction = 3200;
363     bnr.threshold_cb = 64;
364     bnr.threshold_cr = 64;
365   } else {
366     memset(&bnr, 0, sizeof(bnr));
367   }
368   cam_driver_dbg("%s on:%d\n",__func__,on);
369
370    // TODO not configured in Android
371    // check later status of this
372   //return xioctl (fd, ATOMISP_IOC_G_NR, &bnr, "Bayer NR");
373    return CAM_ERR_NONE;
374 }
375
376 /* False Color Correction, Demosaicing */
377 cam_err_t
378 cam_driver_set_fcc (int fd, int on)
379 {
380   return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
381       on, "False Color Correction");
382 }
383
384 cam_err_t
385 cam_driver_set_ynr (int fd, int on)
386 {
387   /* YCC NR use the same parameter as Bayer NR */
388    cam_driver_dbg("%s\n",__func__);
389
390   return cam_driver_set_bnr(fd, on);
391 }
392
393 cam_err_t
394 cam_driver_set_ee (int fd, int on)
395 {
396   struct atomisp_ee_config ee;
397   if (on) {
398     ee.gain = 8192;
399     ee.threshold = 128;
400     ee.detail_gain = 2048;
401   } else {
402     ee.gain = 0;
403     ee.threshold = 0;
404     ee.detail_gain = 0;
405   }
406   cam_driver_dbg("%s on:%d\n",__func__,on);
407
408   return xioctl (fd, ATOMISP_IOC_S_EE, &ee, "Edege Ehancement");
409 }
410
411 /*Black Level Compensation */
412 cam_err_t
413 cam_driver_set_blc (int fd, int on)
414 {
415   static struct atomisp_ob_config ob_off;
416   struct atomisp_ob_config ob_on;
417   static int current_status = 0;
418
419   cam_driver_dbg("Set Black Level compensation\n");
420   if (on && current_status) {
421       cam_driver_dbg("Black Level Compensation Already On\n");
422       return CAM_ERR_NONE;
423   }
424
425   if (!on && !current_status) {
426       cam_driver_dbg("Black Level Composition Already Off\n");
427       return CAM_ERR_NONE;
428   }
429
430   ob_on.mode = atomisp_ob_mode_fixed;
431   ob_on.level_gr = 0;
432   ob_on.level_r = 0;
433   ob_on.level_b = 0;
434   ob_on.level_gb = 0;
435   ob_on.start_position = 0;
436   ob_on.end_position = 63;
437
438   cam_driver_dbg("%s on:%d\n",__func__,on);
439
440   if (on) {
441     if (xioctl (fd, ATOMISP_IOC_G_BLACK_LEVEL_COMP, &ob_off, "blc") < 0 ) {
442       cam_driver_dbg("Error Get black level composition\n");
443       return CAM_ERR_SYS;
444     }
445     if (xioctl (fd, ATOMISP_IOC_S_BLACK_LEVEL_COMP, &ob_on, "blc") < 0) {
446       cam_driver_dbg("Error Set black level composition\n");
447       return CAM_ERR_SYS;
448     }
449   } else {
450     if (xioctl (fd, ATOMISP_IOC_S_BLACK_LEVEL_COMP, &ob_off, "blc") < 0) {
451       cam_driver_dbg("Error Set black level composition\n");
452       return CAM_ERR_SYS;
453     }
454   }
455   current_status = on;
456   return CAM_ERR_NONE;
457 }
458
459
460 cam_err_t
461 cam_driver_set_tnr (int fd, int on)
462 {
463   struct atomisp_tnr_config tnr;
464   cam_driver_dbg("%s on:%d\n",__func__,on);
465   return xioctl (fd, ATOMISP_IOC_S_TNR, &tnr, "ATOMISP_IOC_S_TNR");
466 }
467
468 cam_err_t
469 cam_driver_set_xnr (int fd, int on)
470 {
471   cam_driver_dbg("%s on:%d\n",__func__,on);
472   return xioctl (fd, ATOMISP_IOC_S_XNR, &on, "ATOMISP_IOC_S_XNR");
473 }
474
475 cam_err_t
476 cam_driver_set_cac (int fd, int on)
477 {
478   return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
479       on, "CAC");
480 }
481
482 /* Configure the color effect Mode in the kernel
483  */
484
485 cam_err_t
486 cam_driver_set_tone_mode (int fd, enum v4l2_colorfx colorfx)
487 {
488   return cam_driver_set_attribute (fd, V4L2_CID_COLORFX, colorfx, "Color Effect");
489 }
490
491 cam_err_t
492 cam_driver_get_tone_mode (int fd, int *colorfx)
493 {
494   return cam_driver_get_attribute (fd, V4L2_CID_COLORFX, colorfx, "Color Effect");
495 }
496
497 static cam_err_t
498 cam_driver_set_gamma_tbl (int fd, struct atomisp_gamma_table *g_tbl)
499 {
500   int ret;
501   ret = xioctl (fd, ATOMISP_IOC_S_ISP_GAMMA, g_tbl, "S_GAMMA_TBL");
502   if (ret < 0)
503     return CAM_ERR_SYS;
504   else
505     return CAM_ERR_NONE;
506 }
507
508 cam_err_t
509 cam_driver_init_gamma (int fd)
510 {
511   int ret;
512   ret = xioctl (fd, ATOMISP_IOC_G_ISP_GAMMA, &g_gamma_table, "G_GAMMA_TBL");
513   if (ret < 0)
514     return CAM_ERR_SYS;
515   else
516     return CAM_ERR_NONE;
517 }
518
519 cam_err_t
520 cam_driver_set_mipi_interrupt(int fd, int enable)
521 {
522   int ret;
523
524   ret = xioctl (fd, ATOMISP_IOC_S_MIPI_IRQ, &enable, "MIPI_IRQ" );
525   if (ret < 0)
526     return CAM_ERR_SYS;
527   else
528     return CAM_ERR_NONE;
529 }
530
531
532 cam_err_t
533 cam_driver_set_gamma (int fd, float gamma)
534 {
535   g_cfg_gm.GmVal = gamma;
536   AutoGmLut (g_gamma_table.data, &g_cfg_gm);
537
538   return cam_driver_set_gamma_tbl (fd, &g_gamma_table);
539 }
540
541 cam_err_t
542 cam_driver_set_contrast (int fd, int contrast, int brightness)
543 {
544   int i, tmp;
545   for (i = 0; i < 1024; i++) {
546     tmp = (g_gamma_table.data[i] * contrast >> 8) + brightness;
547
548     if (tmp < g_cfg_gm.GmLevelMin) {
549       tmp = g_cfg_gm.GmLevelMin;
550     } else if (tmp > g_cfg_gm.GmLevelMax) {
551       tmp = g_cfg_gm.GmLevelMax;
552     }
553
554     g_gamma_table.data[i] = tmp;
555   }
556   return cam_driver_set_gamma_tbl (fd, &g_gamma_table);
557 }
558
559 /* Description
560  * VF Scaling for View Finder
561  * Parameters:
562  * factor : scaling factor, 0..2. Power of 1/2
563  * TBD
564  * Waiting for SH's implementation for this feature
565  */
566 cam_err_t
567 cam_driver_set_vf (int fd, int factor, int updatek)
568 {
569   cam_driver_dbg ("%s\n", __func__);
570 #if 0
571   s_ispparm *w_ispparm = &g_ispparam->w_ispparm;
572   w_ispparm->vf_wind_len_x = w_ispparm->vf_wind_len_x * (factor);
573   w_ispparm->vf_wind_len_y = w_ispparm->vf_wind_len_y * (factor);
574 #endif
575   return CAM_ERR_NONE;
576 }
577
578
579 /* SuperImpose
580  * TBD
581  * Waiting for SH provide the more useful API to do the image/vide overlay.
582  */
583 cam_err_t
584 cam_driver_set_si (int fd, int on)
585 {
586   cam_driver_dbg ("%s\n", __func__);
587   //convert the overlay file to Y file, U file and V file
588   //Store the Y U V file name to sh_si_config
589   //superimpose_file_read((sh_si_config *) arg);
590   //Call the kernel to store the pattern to xmem.
591   return CAM_ERR_NONE;
592 }
593
594 cam_err_t
595 cam_driver_set_gdc (int fd, int on)
596 {
597   return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
598       on, "GDC");
599 }
600
601 cam_err_t
602 cam_driver_set_dvs (int fd, int on)
603 {
604   return cam_driver_set_attribute(fd, V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
605                         on, "Video Stabilization");
606 }
607
608 cam_err_t
609 cam_driver_set_exposure (int fd, unsigned int exposure)
610 {
611   if (exposure == 0)
612     return CAM_ERR_NONE;
613   return cam_driver_set_attribute (fd, V4L2_CID_EXPOSURE_ABSOLUTE, exposure,
614                                    "exposure");
615 }
616
617 cam_err_t
618 cam_driver_get_exposure (int fd, int *exposure)
619 {
620   return cam_driver_get_attribute (fd, V4L2_CID_EXPOSURE_ABSOLUTE, exposure, "Exposure");
621 }
622
623 cam_err_t
624 cam_driver_set_aperture (int fd, unsigned int aperture)
625 {
626 // TODO check this
627   return CAM_ERR_NONE;
628 }
629
630 cam_err_t
631 cam_driver_get_aperture (int fd, int *aperture)
632 {
633 // TODO check this
634   return CAM_ERR_NONE;
635 }
636
637 cam_err_t
638 cam_driver_set_iso_speed (int fd, unsigned int iso_speed)
639 {
640 // TODO check this
641   return CAM_ERR_NONE;
642 }
643
644 cam_err_t
645 cam_driver_get_iso_speed (int fd, int *iso_speed)
646 {
647   // iso speed 0 = not defined
648   *iso_speed = 0;
649   return CAM_ERR_NONE;
650 }
651
652 cam_err_t
653 cam_driver_set_focus_posi (int fd, int focus)
654 {
655   return cam_driver_set_attribute (fd, V4L2_CID_FOCUS_ABSOLUTE, focus, "Focus");
656 }
657
658 cam_err_t
659 cam_driver_get_focus_posi (int fd, int *focus)
660 {
661   return cam_driver_get_attribute (fd, V4L2_CID_FOCUS_ABSOLUTE, focus, "Focus");
662 }
663
664 cam_err_t
665 cam_driver_set_zoom (int fd, unsigned int zoom)
666 {
667   return cam_driver_set_attribute (fd, V4L2_CID_ZOOM_ABSOLUTE, zoom, "zoom");
668 }
669
670 cam_err_t
671 cam_driver_get_zoom (int fd, unsigned int *zoom)
672 {
673   return cam_driver_get_attribute (fd, V4L2_CID_ZOOM_ABSOLUTE, zoom, "Zoom");
674 }
675
676 cam_err_t
677 cam_driver_set_autoexposure (int fd, enum v4l2_exposure_auto_type expo)
678 {
679   return cam_driver_set_attribute (fd, V4L2_CID_EXPOSURE_AUTO, expo, "auto exposure");
680 }
681
682 cam_err_t
683 cam_driver_get_makernote (int fd, unsigned char *buf, unsigned size)
684 {
685         int ret;
686
687         ret = xioctl (fd, ATOMISP_IOC_ISP_MAKERNOTE, buf, "G_MAKERNOTE");
688         if (ret < 0)
689           return CAM_ERR_SYS;
690         else
691           return CAM_ERR_NONE;
692 }
693
694 cam_err_t
695 cam_driver_set_led_flash (int fd, int id, int value)
696 {
697         int ret;
698         struct v4l2_ext_controls controls;
699         struct v4l2_ext_control control;
700
701         controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
702         controls.count = 1;
703         controls.controls = &control;
704
705         control.id = id;
706         control.value = value;
707
708         ret = xioctl (fd, VIDIOC_S_EXT_CTRLS, &controls, "flash settings");
709         if (ret < 0)
710                 return CAM_ERR_SYS;
711         else
712                 return CAM_ERR_NONE;
713 }
714
715 void
716 led_flash_trigger (int fd, int duration, int intensity)
717 {
718         cam_err_t ret;
719
720     cam_driver_dbg("%s\n",__func__);
721
722         ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 0);
723         if (ret != CAM_ERR_NONE)
724         {
725                 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 0);
726         }
727         ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 1);
728         if (ret != CAM_ERR_NONE)
729         {
730                 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 1);
731         }
732         ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_INTENSITY, intensity);
733         if (ret != CAM_ERR_NONE)
734         {
735                 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 2);
736         }
737         ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_TIMEOUT, duration);
738         if (ret != CAM_ERR_NONE)
739         {
740                 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 3);
741         }
742 }
743
744 void
745 led_flash_off (int fd)
746 {
747         cam_err_t ret;
748     cam_driver_dbg("%s\n",__func__);
749
750         ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 0);
751         if (ret != CAM_ERR_NONE)
752         {
753                 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 0);
754         }
755 }
756
757 cam_err_t
758 cam_driver_set_flash_mode (int fd,int mode)
759 {
760   cam_driver_dbg ("%s: mode %d\n", __func__, mode);
761
762   return cam_driver_set_attribute (fd, V4L2_CID_FLASH_MODE, mode, "Flash Mode");
763 }
764
765 cam_err_t
766 cam_driver_set_indication_intensity (int fd,int intensity)
767 {
768   cam_driver_dbg ("%s: intensity %d\n", __func__, intensity);
769
770   return cam_driver_set_attribute (fd, V4L2_CID_FLASH_INDICATOR_INTENSITY, intensity, "indication intensity");
771 }