summaryrefslogtreecommitdiff
path: root/isp/controls.c
diff options
context:
space:
mode:
Diffstat (limited to 'isp/controls.c')
-rw-r--r--isp/controls.c70
1 files changed, 70 insertions, 0 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;