summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-10-20 20:49:07 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-10-20 21:05:46 +0200
commit1922132a4facf53e71855fb3624ab29da99a6fe3 (patch)
tree918d8e20962db8a811108db6f0be8d81e783b1a7
parent7e62380de5584b9edbd61048f5b16e521e893eeb (diff)
isp: Emulate global gain for sensors that only expose color gains
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--isp/controls.c70
-rw-r--r--isp/controls.h1
-rw-r--r--isp/omap3isp-priv.h5
-rw-r--r--isp/omap3isp.c8
4 files changed, 77 insertions, 7 deletions
diff --git a/isp/controls.c b/isp/controls.c
index cce4265..05ab20b 100644
--- a/isp/controls.c
+++ b/isp/controls.c
@@ -343,6 +343,70 @@ int omap3_isp_preview_setup(struct omap3_isp_device *isp)
#define V4L2_CID_GAIN_GREEN2 (V4L2_CTRL_CLASS_CAMERA | 0x1003)
#define V4L2_CID_GAIN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1004)
+#define SENSOR_GAIN_GLOBAL (1 << 0)
+#define SENSOR_GAIN_RED (1 << 1)
+#define SENSOR_GAIN_GREEN1 (1 << 2)
+#define SENSOR_GAIN_GREEN2 (1 << 3)
+#define SENSOR_GAIN_BLUE (1 << 4)
+#define SENSOR_GAIN_COLORS (SENSOR_GAIN_RED | \
+ SENSOR_GAIN_GREEN1 | \
+ SENSOR_GAIN_GREEN2 | \
+ SENSOR_GAIN_BLUE)
+
+int omap3_isp_sensor_init(struct omap3_isp_device *isp)
+{
+ struct v4l2_queryctrl query;
+ unsigned int gains = 0;
+ __u32 id;
+ int ret;
+
+ /* Retrieve the sensor default format. */
+ ret = v4l2_subdev_get_format(isp->sensor.entity, &isp->sensor.format, 0,
+ V4L2_SUBDEV_FORMAT_TRY);
+ if (ret < 0) {
+ printf("error: unable to get sensor default format.\n");
+ return ret;
+ }
+
+ for (id = 0; ; id = query.id) {
+ memset(&query, 0, sizeof query);
+ query.id = id | V4L2_CTRL_FLAG_NEXT_CTRL;
+ ret = ioctl(isp->sensor.entity->fd, VIDIOC_QUERYCTRL, &query);
+ if (ret < 0) {
+ if (errno == EINVAL)
+ break;
+
+ printf("error: unable to get sensor default format.\n");
+ return -errno;
+ }
+
+ switch (query.id) {
+ case V4L2_CID_GAIN:
+ gains |= SENSOR_GAIN_GLOBAL;
+ break;
+ case V4L2_CID_GAIN_RED:
+ gains |= SENSOR_GAIN_RED;
+ break;
+ case V4L2_CID_GAIN_GREEN1:
+ gains |= SENSOR_GAIN_GREEN1;
+ break;
+ case V4L2_CID_GAIN_GREEN2:
+ gains |= SENSOR_GAIN_GREEN2;
+ break;
+ case V4L2_CID_GAIN_BLUE:
+ gains |= SENSOR_GAIN_BLUE;
+ break;
+ }
+ }
+
+ if ((gains & SENSOR_GAIN_COLORS) == SENSOR_GAIN_COLORS)
+ isp->sensor.has_color_gains = true;
+ if (gains & SENSOR_GAIN_GLOBAL)
+ isp->sensor.has_global_gain = true;
+
+ return 0;
+}
+
int omap3_isp_sensor_get_exposure(struct omap3_isp_device *isp,
unsigned int *exposure)
{
@@ -374,6 +438,9 @@ int omap3_isp_sensor_set_gain(struct omap3_isp_device *isp, unsigned int gain)
{
struct v4l2_ext_control ctrls[1];
+ if (!isp->sensor.has_global_gain)
+ return omap3_isp_sensor_set_gains(isp, gain, gain, gain);
+
ctrls[0].id = V4L2_CID_GAIN;
ctrls[0].value = gain;
@@ -386,6 +453,9 @@ int omap3_isp_sensor_set_gains(struct omap3_isp_device *isp,
struct v4l2_ext_control ctrls[4];
unsigned int i = 0;
+ if (!isp->sensor.has_color_gains)
+ return -EINVAL;
+
if (red != OMAP3_ISP_SENSOR_GAIN_KEEP) {
ctrls[i].id = V4L2_CID_GAIN_RED;
ctrls[i++].value = red;
diff --git a/isp/controls.h b/isp/controls.h
index 6c7f74e..29bdd48 100644
--- a/isp/controls.h
+++ b/isp/controls.h
@@ -25,5 +25,6 @@
struct omap3_isp_device;
int omap3_isp_preview_setup(struct omap3_isp_device *isp);
+int omap3_isp_sensor_init(struct omap3_isp_device *isp);
#endif /* __OMAP3ISP_CONTROLS_H */
diff --git a/isp/omap3isp-priv.h b/isp/omap3isp-priv.h
index 2f3dbb9..c71ed40 100644
--- a/isp/omap3isp-priv.h
+++ b/isp/omap3isp-priv.h
@@ -139,6 +139,9 @@ struct omap3_isp_device {
struct {
struct media_entity *entity;
+ struct v4l2_mbus_framefmt format;
+ bool has_color_gains;
+ bool has_global_gain;
} sensor;
struct {
struct media_entity *entity;
@@ -149,8 +152,6 @@ struct omap3_isp_device {
} preview;
struct omap3_isp_aewb aewb;
- struct v4l2_mbus_framefmt sensor_format;
-
struct omap3_isp_pipeline viewfinder;
struct omap3_isp_pipeline snapshot;
diff --git a/isp/omap3isp.c b/isp/omap3isp.c
index ac9cc4a..7ff2d7e 100644
--- a/isp/omap3isp.c
+++ b/isp/omap3isp.c
@@ -637,7 +637,7 @@ static int omap3_isp_pipeline_try_format(struct omap3_isp_device *isp,
* Otherwise scale as much as possible on the sensor.
*/
if (scaler == OMAP3_ISP_SCALER_ISP)
- format = isp->sensor_format;
+ format = isp->sensor.format;
else
format = *ofmt;
@@ -939,11 +939,9 @@ struct omap3_isp_device *omap3_isp_open(const char *devname,
isp->sensor.entity = entity;
- /* Retrieve the sensor default format. */
- ret = v4l2_subdev_get_format(isp->sensor.entity, &isp->sensor_format, 0,
- V4L2_SUBDEV_FORMAT_TRY);
+ ret = omap3_isp_sensor_init(isp);
if (ret < 0) {
- printf("error: unable to get sensor default format.\n");
+ printf("error: unable to initialize sensor.\n");
goto error;
}