summaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/mt9v011.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-24 17:35:10 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-24 17:35:10 -0800
commit21fbd5809ad126b949206d78e0a0e07ec872ea11 (patch)
treea824045df99fc1f0690095a925cceb50207e332b /drivers/media/i2c/mt9v011.c
parentd9978ec5680059d727b39d6c706777c6973587f2 (diff)
parented72d37a33fdf43dc47787fe220532cdec9da528 (diff)
downloadop-kernel-dev-21fbd5809ad126b949206d78e0a0e07ec872ea11.zip
op-kernel-dev-21fbd5809ad126b949206d78e0a0e07ec872ea11.tar.gz
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - Some cleanups at V4L2 documentation - new drivers: ts2020 frontend, ov9650 sensor, s5c73m3 sensor, sh-mobile veu mem2mem driver, radio-ma901, davinci_vpfe staging driver - Lots of missing MAINTAINERS entries added - several em28xx driver improvements, including its conversion to videobuf2 - several fixups on drivers to make them to better comply with the API - DVB core: add support for DVBv5 stats, allowing the implementation of statistics for new standards like ISDB - mb86a20s: add statistics to the driver - lots of new board additions, cleanups, and driver improvements. * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (596 commits) [media] media: Add 0x3009 USB PID to ttusb2 driver (fixed diff) [media] rtl28xxu: Add USB IDs for Compro VideoMate U620F [media] em28xx: add usb id for terratec h5 rev. 3 [media] media: rc: gpio-ir-recv: add support for device tree parsing [media] mceusb: move check earlier to make smatch happy [media] radio-si470x doc: add info about v4l2-ctl and sox+alsa [media] staging: media: Remove unnecessary OOM messages [media] sh_vou: Use vou_dev instead of vou_file wherever possible [media] sh_vou: Use video_drvdata() [media] drivers/media/platform/soc_camera/pxa_camera.c: use devm_ functions [media] mt9t112: mt9t111 format set up differs from mt9t112 [media] sh-mobile-ceu-camera: fix SHARPNESS control default Revert "[media] fc0011: Return early, if the frequency is already tuned" [media] cx18/ivtv: fix regression: remove __init from a non-init function [media] em28xx: fix analog streaming with USB bulk transfers [media] stv0900: remove unnecessary null pointer check [media] fc0011: Return early, if the frequency is already tuned [media] fc0011: Add some sanity checks and cleanups [media] fc0011: Fix xin value clamping Revert "[media] [PATH,1/2] mxl5007 move reset to attach" ...
Diffstat (limited to 'drivers/media/i2c/mt9v011.c')
-rw-r--r--drivers/media/i2c/mt9v011.c223
1 files changed, 67 insertions, 156 deletions
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 6bf01ad..73b7688 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -13,6 +13,7 @@
#include <asm/div64.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-ctrls.h>
#include <media/mt9v011.h>
MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
@@ -48,68 +49,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)");
#define MT9V011_VERSION 0x8232
#define MT9V011_REV_B_VERSION 0x8243
-/* supported controls */
-static struct v4l2_queryctrl mt9v011_qctrl[] = {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = (1 << 12) - 1 - 0x0020,
- .step = 1,
- .default_value = 0x0020,
- .flags = 0,
- }, {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 2047,
- .step = 1,
- .default_value = 0x01fc,
- .flags = 0,
- }, {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -1 << 9,
- .maximum = (1 << 9) - 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -1 << 9,
- .maximum = (1 << 9) - 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vflip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- .flags = 0,
- }, {
- }
-};
-
struct mt9v011 {
struct v4l2_subdev sd;
+ struct v4l2_ctrl_handler ctrls;
unsigned width, height;
unsigned xtal;
unsigned hflip:1;
@@ -381,99 +323,6 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
set_read_mode(sd);
return 0;
-};
-
-static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct mt9v011 *core = to_mt9v011(sd);
-
- v4l2_dbg(1, debug, sd, "g_ctrl called\n");
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- ctrl->value = core->global_gain;
- return 0;
- case V4L2_CID_EXPOSURE:
- ctrl->value = core->exposure;
- return 0;
- case V4L2_CID_RED_BALANCE:
- ctrl->value = core->red_bal;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- ctrl->value = core->blue_bal;
- return 0;
- case V4L2_CID_HFLIP:
- ctrl->value = core->hflip ? 1 : 0;
- return 0;
- case V4L2_CID_VFLIP:
- ctrl->value = core->vflip ? 1 : 0;
- return 0;
- }
- return -EINVAL;
-}
-
-static int mt9v011_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
-{
- int i;
-
- v4l2_dbg(1, debug, sd, "queryctrl called\n");
-
- for (i = 0; i < ARRAY_SIZE(mt9v011_qctrl); i++)
- if (qc->id && qc->id == mt9v011_qctrl[i].id) {
- memcpy(qc, &(mt9v011_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
-{
- struct mt9v011 *core = to_mt9v011(sd);
- u8 i, n;
- n = ARRAY_SIZE(mt9v011_qctrl);
-
- for (i = 0; i < n; i++) {
- if (ctrl->id != mt9v011_qctrl[i].id)
- continue;
- if (ctrl->value < mt9v011_qctrl[i].minimum ||
- ctrl->value > mt9v011_qctrl[i].maximum)
- return -ERANGE;
- v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
- ctrl->id, ctrl->value);
- break;
- }
-
- switch (ctrl->id) {
- case V4L2_CID_GAIN:
- core->global_gain = ctrl->value;
- break;
- case V4L2_CID_EXPOSURE:
- core->exposure = ctrl->value;
- break;
- case V4L2_CID_RED_BALANCE:
- core->red_bal = ctrl->value;
- break;
- case V4L2_CID_BLUE_BALANCE:
- core->blue_bal = ctrl->value;
- break;
- case V4L2_CID_HFLIP:
- core->hflip = ctrl->value;
- set_read_mode(sd);
- return 0;
- case V4L2_CID_VFLIP:
- core->vflip = ctrl->value;
- set_read_mode(sd);
- return 0;
- default:
- return -EINVAL;
- }
-
- set_balance(sd);
-
- return 0;
}
static int mt9v011_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
@@ -599,10 +448,46 @@ static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
version);
}
-static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
- .queryctrl = mt9v011_queryctrl,
- .g_ctrl = mt9v011_g_ctrl,
+static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct mt9v011 *core =
+ container_of(ctrl->handler, struct mt9v011, ctrls);
+ struct v4l2_subdev *sd = &core->sd;
+
+ switch (ctrl->id) {
+ case V4L2_CID_GAIN:
+ core->global_gain = ctrl->val;
+ break;
+ case V4L2_CID_EXPOSURE:
+ core->exposure = ctrl->val;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ core->red_bal = ctrl->val;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ core->blue_bal = ctrl->val;
+ break;
+ case V4L2_CID_HFLIP:
+ core->hflip = ctrl->val;
+ set_read_mode(sd);
+ return 0;
+ case V4L2_CID_VFLIP:
+ core->vflip = ctrl->val;
+ set_read_mode(sd);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ set_balance(sd);
+ return 0;
+}
+
+static struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
.s_ctrl = mt9v011_s_ctrl,
+};
+
+static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
.reset = mt9v011_reset,
.g_chip_ident = mt9v011_g_chip_ident,
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -658,6 +543,30 @@ static int mt9v011_probe(struct i2c_client *c,
return -EINVAL;
}
+ v4l2_ctrl_handler_init(&core->ctrls, 5);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_GAIN, 0, (1 << 12) - 1 - 0x20, 1, 0x20);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_EXPOSURE, 0, 2047, 1, 0x01fc);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_RED_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_BLUE_BALANCE, -(1 << 9), (1 << 9) - 1, 1, 0);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&core->ctrls, &mt9v011_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+
+ if (core->ctrls.error) {
+ int ret = core->ctrls.error;
+
+ v4l2_err(sd, "control initialization error %d\n", ret);
+ v4l2_ctrl_handler_free(&core->ctrls);
+ kfree(core);
+ return ret;
+ }
+ core->sd.ctrl_handler = &core->ctrls;
+
core->global_gain = 0x0024;
core->exposure = 0x01fc;
core->width = 640;
@@ -681,12 +590,14 @@ static int mt9v011_probe(struct i2c_client *c,
static int mt9v011_remove(struct i2c_client *c)
{
struct v4l2_subdev *sd = i2c_get_clientdata(c);
+ struct mt9v011 *core = to_mt9v011(sd);
v4l2_dbg(1, debug, sd,
"mt9v011.c: removing mt9v011 adapter on address 0x%x\n",
c->addr << 1);
v4l2_device_unregister_subdev(sd);
+ v4l2_ctrl_handler_free(&core->ctrls);
kfree(to_mt9v011(sd));
return 0;
}
OpenPOWER on IntegriCloud