1 /* Gstreamer MFLD camera source abstract Layer API
2 * Copyright (c) 2010 Intel Corporation
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.
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.
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.
21 * This file provide the IOCTL wrap to the Medfield v4l2 drivers
22 * It provides the following features.
25 * Skin tone detection/correction FIXME
26 * Image effect (Color Sapce Convertion)
27 * Noise Reduction (XNR, TNR, BNR, YNR FPN)
30 * False Color Correction
33 * Lens shading correction
52 #include "mfld_driver.h"
53 #include "sh_css_types.h"
54 #include "atomisp_v4l2.h"
56 #define CAM_ISP_IS_OPEN(fd) (fd > 0)
59 xioctl (int fd, int request, void *arg, const char *name)
63 cam_driver_dbg ("ioctl %s ", name);
66 ret = ioctl (fd, request, arg);
67 } while (-1 == ret && EINTR == errno);
70 cam_driver_dbg ("failed: %s\n", strerror (errno));
72 cam_driver_dbg ("ok\n");
77 /* Utilities for debug message and error message output
80 cam_driver_dbg (const char *format, ...)
84 if ((env = getenv ("LIBMFLDCAM_DEBUG")) && strstr (env, "verbose")) {
85 va_start (ap, format);
86 vfprintf (stdout, format, ap);
91 static const char *cameralib_error_map[] = {
100 "CAM_ERR_INVALID_STATE",
106 cam_err_print (cam_err_t err)
108 if ((err < CAM_ERR_NONE) || (err > CAM_ERR_3A)) {
109 cam_driver_dbg (" %s Wrong error number in lib camera\n", __func__);
113 cam_driver_dbg ("%s\n", cameralib_error_map[err]);
116 /******************************************************
117 * cam_driver_get_attribute():
118 * try to get the value of one specific attribute
119 * return value: CAM_ERR_NONE for success
121 ******************************************************/
123 cam_driver_get_attribute (int fd, int attribute_num, int *value, char *name)
125 struct v4l2_control control;
127 cam_driver_dbg ("getting value of attribute %d: %s\n", attribute_num, name);
129 if (!CAM_ISP_IS_OPEN (fd))
130 return CAM_ERR_NOT_OPEN;
132 control.id = attribute_num;
134 if (ioctl (fd, VIDIOC_G_CTRL, &control) < 0)
137 *value = control.value;
143 struct v4l2_ext_controls controls;
144 struct v4l2_ext_control control;
146 controls.ctrl_class = V4L2_CTRL_CLASS_USER;
148 controls.controls = &control;
150 control.id = attribute_num;
152 if (ioctl (fd, VIDIOC_G_EXT_CTRLS, &controls) < 0)
155 *value = control.value;
163 struct v4l2_ext_controls controls;
164 struct v4l2_ext_control control;
166 controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
168 controls.controls = &control;
170 control.id = attribute_num;
172 if (ioctl (fd, VIDIOC_G_EXT_CTRLS, &controls) < 0)
175 *value = control.value;
184 cam_driver_dbg ("Failed to get value for control %d on device '%d'.",
190 /******************************************************
191 * cam_driver_set_attribute():
192 * try to set the value of one specific attribute
193 * return value: CAM_ERR_NONE for success
195 ******************************************************/
197 cam_driver_set_attribute (int fd, int attribute_num, const int value,
200 struct v4l2_control control;
202 cam_driver_dbg ("setting value of attribute [%s] to %d\n", name, value);
204 if (!CAM_ISP_IS_OPEN (fd))
205 return CAM_ERR_NOT_OPEN;
207 control.id = attribute_num;
208 control.value = value;
209 if (ioctl (fd, VIDIOC_S_CTRL, &control) < 0)
216 struct v4l2_ext_controls controls;
217 struct v4l2_ext_control control;
219 controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
221 controls.controls = &control;
223 control.id = attribute_num;
224 control.value = value;
226 if (ioctl (fd, VIDIOC_S_EXT_CTRLS, &controls) < 0)
234 struct v4l2_ext_controls controls;
235 struct v4l2_ext_control control;
237 controls.ctrl_class = V4L2_CTRL_CLASS_USER;
239 controls.controls = &control;
241 control.id = attribute_num;
242 control.value = value;
244 if (ioctl (fd, VIDIOC_S_EXT_CTRLS, &controls) < 0)
254 ("Failed to set value %d for control %d on device '%d', %s\n.", value,
255 attribute_num, fd, strerror (errno));
260 static struct atomisp_gamma_table g_gamma_table;
262 /* Gamma configuration
263 * Also used by extended dymanic range and tone control
265 struct Camera_gm_config
267 /* [gain] 1.0..2.4 Gamma value. */
269 int GmToe; /* [intensity] Toe position of S-curve. */
270 int GmKne; /* [intensity] Knee position of S-curve */
272 /* [gain] 100%..400% Magnification factor of dynamic range
273 * (1.0 for normal dynamic range) */
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;
284 static struct Camera_gm_config g_cfg_gm = {
297 AutoGmLut (unsigned short *pptDst, struct Camera_gm_config *cfg_gm)
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.;
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);
317 (adbNume == 0.) ? 0. : pow (adbDeno / adbNume, adbReGammaVal);
318 short auiTmp = (short) ((double) 255 * adbY + 0.5);
320 if (auiTmp < cfg_gm->GmLevelMin) {
321 auiTmp = cfg_gm->GmLevelMin;
322 } else if (auiTmp > cfg_gm->GmLevelMax) {
323 auiTmp = cfg_gm->GmLevelMax;
325 pptDst[asiCnt] = auiTmp;
330 cam_driver_set_fpn (int fd, int on)
336 cam_driver_set_sc (int fd, int on)
342 /* Bad Pixel Detection*/
344 cam_driver_set_bpd (int fd, int on)
346 return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
347 on, "Bad Pixel Detection");
350 cam_driver_get_bpd (int fd, int *on)
352 return cam_driver_get_attribute (fd, V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
353 on, "Bad Pixel Detection");
357 cam_driver_set_bnr (int fd, int on)
359 struct atomisp_nr_config bnr;
361 bnr.bnr_gain = 60000;
362 bnr.direction = 3200;
363 bnr.threshold_cb = 64;
364 bnr.threshold_cr = 64;
366 memset(&bnr, 0, sizeof(bnr));
368 cam_driver_dbg("%s on:%d\n",__func__,on);
370 // TODO not configured in Android
371 // check later status of this
372 //return xioctl (fd, ATOMISP_IOC_G_NR, &bnr, "Bayer NR");
376 /* False Color Correction, Demosaicing */
378 cam_driver_set_fcc (int fd, int on)
380 return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
381 on, "False Color Correction");
385 cam_driver_set_ynr (int fd, int on)
387 /* YCC NR use the same parameter as Bayer NR */
388 cam_driver_dbg("%s\n",__func__);
390 return cam_driver_set_bnr(fd, on);
394 cam_driver_set_ee (int fd, int on)
396 struct atomisp_ee_config ee;
400 ee.detail_gain = 2048;
406 cam_driver_dbg("%s on:%d\n",__func__,on);
408 return xioctl (fd, ATOMISP_IOC_S_EE, &ee, "Edege Ehancement");
411 /*Black Level Compensation */
413 cam_driver_set_blc (int fd, int on)
415 static struct atomisp_ob_config ob_off;
416 struct atomisp_ob_config ob_on;
417 static int current_status = 0;
419 cam_driver_dbg("Set Black Level compensation\n");
420 if (on && current_status) {
421 cam_driver_dbg("Black Level Compensation Already On\n");
425 if (!on && !current_status) {
426 cam_driver_dbg("Black Level Composition Already Off\n");
430 ob_on.mode = atomisp_ob_mode_fixed;
435 ob_on.start_position = 0;
436 ob_on.end_position = 63;
438 cam_driver_dbg("%s on:%d\n",__func__,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");
445 if (xioctl (fd, ATOMISP_IOC_S_BLACK_LEVEL_COMP, &ob_on, "blc") < 0) {
446 cam_driver_dbg("Error Set black level composition\n");
450 if (xioctl (fd, ATOMISP_IOC_S_BLACK_LEVEL_COMP, &ob_off, "blc") < 0) {
451 cam_driver_dbg("Error Set black level composition\n");
461 cam_driver_set_tnr (int fd, int on)
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");
469 cam_driver_set_xnr (int fd, int on)
471 cam_driver_dbg("%s on:%d\n",__func__,on);
472 return xioctl (fd, ATOMISP_IOC_S_XNR, &on, "ATOMISP_IOC_S_XNR");
476 cam_driver_set_cac (int fd, int on)
478 return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
482 /* Configure the color effect Mode in the kernel
486 cam_driver_set_tone_mode (int fd, enum v4l2_colorfx colorfx)
488 return cam_driver_set_attribute (fd, V4L2_CID_COLORFX, colorfx, "Color Effect");
492 cam_driver_get_tone_mode (int fd, int *colorfx)
494 return cam_driver_get_attribute (fd, V4L2_CID_COLORFX, colorfx, "Color Effect");
498 cam_driver_set_gamma_tbl (int fd, struct atomisp_gamma_table *g_tbl)
501 ret = xioctl (fd, ATOMISP_IOC_S_ISP_GAMMA, g_tbl, "S_GAMMA_TBL");
509 cam_driver_init_gamma (int fd)
512 ret = xioctl (fd, ATOMISP_IOC_G_ISP_GAMMA, &g_gamma_table, "G_GAMMA_TBL");
520 cam_driver_set_mipi_interrupt(int fd, int enable)
524 ret = xioctl (fd, ATOMISP_IOC_S_MIPI_IRQ, &enable, "MIPI_IRQ" );
533 cam_driver_set_gamma (int fd, float gamma)
535 g_cfg_gm.GmVal = gamma;
536 AutoGmLut (g_gamma_table.data, &g_cfg_gm);
538 return cam_driver_set_gamma_tbl (fd, &g_gamma_table);
542 cam_driver_set_contrast (int fd, int contrast, int brightness)
545 for (i = 0; i < 1024; i++) {
546 tmp = (g_gamma_table.data[i] * contrast >> 8) + brightness;
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;
554 g_gamma_table.data[i] = tmp;
556 return cam_driver_set_gamma_tbl (fd, &g_gamma_table);
560 * VF Scaling for View Finder
562 * factor : scaling factor, 0..2. Power of 1/2
564 * Waiting for SH's implementation for this feature
567 cam_driver_set_vf (int fd, int factor, int updatek)
569 cam_driver_dbg ("%s\n", __func__);
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);
581 * Waiting for SH provide the more useful API to do the image/vide overlay.
584 cam_driver_set_si (int fd, int on)
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.
595 cam_driver_set_gdc (int fd, int on)
597 return cam_driver_set_attribute (fd, V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
602 cam_driver_set_dvs (int fd, int on)
604 return cam_driver_set_attribute(fd, V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
605 on, "Video Stabilization");
609 cam_driver_set_exposure (int fd, unsigned int exposure)
613 return cam_driver_set_attribute (fd, V4L2_CID_EXPOSURE_ABSOLUTE, exposure,
618 cam_driver_get_exposure (int fd, int *exposure)
620 return cam_driver_get_attribute (fd, V4L2_CID_EXPOSURE_ABSOLUTE, exposure, "Exposure");
624 cam_driver_set_aperture (int fd, unsigned int aperture)
631 cam_driver_get_aperture (int fd, int *aperture)
638 cam_driver_set_iso_speed (int fd, unsigned int iso_speed)
645 cam_driver_get_iso_speed (int fd, int *iso_speed)
647 // iso speed 0 = not defined
653 cam_driver_set_focus_posi (int fd, int focus)
655 return cam_driver_set_attribute (fd, V4L2_CID_FOCUS_ABSOLUTE, focus, "Focus");
659 cam_driver_get_focus_posi (int fd, int *focus)
661 return cam_driver_get_attribute (fd, V4L2_CID_FOCUS_ABSOLUTE, focus, "Focus");
665 cam_driver_set_zoom (int fd, unsigned int zoom)
667 return cam_driver_set_attribute (fd, V4L2_CID_ZOOM_ABSOLUTE, zoom, "zoom");
671 cam_driver_get_zoom (int fd, unsigned int *zoom)
673 return cam_driver_get_attribute (fd, V4L2_CID_ZOOM_ABSOLUTE, zoom, "Zoom");
677 cam_driver_set_autoexposure (int fd, enum v4l2_exposure_auto_type expo)
679 return cam_driver_set_attribute (fd, V4L2_CID_EXPOSURE_AUTO, expo, "auto exposure");
683 cam_driver_get_makernote (int fd, unsigned char *buf, unsigned size)
687 ret = xioctl (fd, ATOMISP_IOC_ISP_MAKERNOTE, buf, "G_MAKERNOTE");
695 cam_driver_set_led_flash (int fd, int id, int value)
698 struct v4l2_ext_controls controls;
699 struct v4l2_ext_control control;
701 controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
703 controls.controls = &control;
706 control.value = value;
708 ret = xioctl (fd, VIDIOC_S_EXT_CTRLS, &controls, "flash settings");
716 led_flash_trigger (int fd, int duration, int intensity)
720 cam_driver_dbg("%s\n",__func__);
722 ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 0);
723 if (ret != CAM_ERR_NONE)
725 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 0);
727 ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 1);
728 if (ret != CAM_ERR_NONE)
730 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 1);
732 ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_INTENSITY, intensity);
733 if (ret != CAM_ERR_NONE)
735 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 2);
737 ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_TIMEOUT, duration);
738 if (ret != CAM_ERR_NONE)
740 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 3);
745 led_flash_off (int fd)
748 cam_driver_dbg("%s\n",__func__);
750 ret = cam_driver_set_led_flash (fd, V4L2_CID_FLASH_STROBE, 0);
751 if (ret != CAM_ERR_NONE)
753 cam_driver_dbg ("%s: Error flash ioctl %d\n", __func__, 0);
758 cam_driver_set_flash_mode (int fd,int mode)
760 cam_driver_dbg ("%s: mode %d\n", __func__, mode);
762 return cam_driver_set_attribute (fd, V4L2_CID_FLASH_MODE, mode, "Flash Mode");
766 cam_driver_set_indication_intensity (int fd,int intensity)
768 cam_driver_dbg ("%s: intensity %d\n", __func__, intensity);
770 return cam_driver_set_attribute (fd, V4L2_CID_FLASH_INDICATOR_INTENSITY, intensity, "indication intensity");