From patchwork Wed Nov 4 16:49:28 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 57646 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA4GnKCS032677 for ; Wed, 4 Nov 2009 16:49:20 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757203AbZKDQtO (ORCPT ); Wed, 4 Nov 2009 11:49:14 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757125AbZKDQtN (ORCPT ); Wed, 4 Nov 2009 11:49:13 -0500 Received: from mail.gmx.net ([213.165.64.20]:43581 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1756916AbZKDQtN (ORCPT ); Wed, 4 Nov 2009 11:49:13 -0500 Received: (qmail invoked by alias); 04 Nov 2009 16:49:15 -0000 Received: from p57BD18E0.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.24.224] by mail.gmx.net (mp012) with SMTP; 04 Nov 2009 17:49:15 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX19rnUwzJg5r1XwJPSKoSMohD3GJbUVrC2E20cizC/ TTBRey2336y9mj Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1N5j32-0002Jr-RY; Wed, 04 Nov 2009 17:49:28 +0100 Date: Wed, 4 Nov 2009 17:49:28 +0100 (CET) From: Guennadi Liakhovetski To: "Karicheri, Muralidharan" cc: Linux Media Mailing List , Hans Verkuil , Laurent Pinchart , Sakari Ailus Subject: [PATCH/RFC 9/9 v2] mt9t031: make the use of the soc-camera client API optional In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.43 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index c95c277..86bf8f6 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c @@ -204,6 +204,71 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); } +enum { + MT9T031_CTRL_VFLIP, + MT9T031_CTRL_HFLIP, + MT9T031_CTRL_GAIN, + MT9T031_CTRL_EXPOSURE, + MT9T031_CTRL_EXPOSURE_AUTO, +}; + +static const struct v4l2_queryctrl mt9t031_controls[] = { + [MT9T031_CTRL_VFLIP] = { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Vertically", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + [MT9T031_CTRL_HFLIP] = { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontally", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + [MT9T031_CTRL_GAIN] = { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 64, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, + [MT9T031_CTRL_EXPOSURE] = { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", + .minimum = 1, + .maximum = 255, + .step = 1, + .default_value = 255, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, + [MT9T031_CTRL_EXPOSURE_AUTO] = { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static struct soc_camera_ops mt9t031_ops = { + .set_bus_param = mt9t031_set_bus_param, + .query_bus_param = mt9t031_query_bus_param, + .controls = mt9t031_controls, + .num_controls = ARRAY_SIZE(mt9t031_controls), +}; + /* target must be _even_ */ static u16 mt9t031_skip(s32 *source, s32 target, s32 max) { @@ -223,10 +288,9 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max) } /* rect is the sensor rectangle, the caller guarantees parameter validity */ -static int mt9t031_set_params(struct soc_camera_device *icd, +static int mt9t031_set_params(struct i2c_client *client, struct v4l2_rect *rect, u16 xskip, u16 yskip) { - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); struct mt9t031 *mt9t031 = to_mt9t031(client); int ret; u16 xbin, ybin; @@ -307,8 +371,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd, if (ret >= 0) { const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; const struct v4l2_queryctrl *qctrl = - soc_camera_find_qctrl(icd->ops, - V4L2_CID_EXPOSURE); + &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * (qctrl->maximum - qctrl->minimum)) / shutter_max + qctrl->minimum; @@ -333,7 +396,6 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) struct v4l2_rect rect = a->c; struct i2c_client *client = sd->priv; struct mt9t031 *mt9t031 = to_mt9t031(client); - struct soc_camera_device *icd = client->dev.platform_data; rect.width = ALIGN(rect.width, 2); rect.height = ALIGN(rect.height, 2); @@ -344,7 +406,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) soc_camera_limit_side(&rect.top, &rect.height, MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); - return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip); + return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip); } static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) @@ -391,7 +453,6 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, { struct i2c_client *client = sd->priv; struct mt9t031 *mt9t031 = to_mt9t031(client); - struct soc_camera_device *icd = client->dev.platform_data; u16 xskip, yskip; struct v4l2_rect rect = mt9t031->rect; @@ -403,7 +464,7 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, yskip = mt9t031_skip(&rect.height, imgf->height, MT9T031_MAX_HEIGHT); /* mt9t031_set_params() doesn't change width and height */ - return mt9t031_set_params(icd, &rect, xskip, yskip); + return mt9t031_set_params(client, &rect, xskip, yskip); } /* @@ -476,59 +537,6 @@ static int mt9t031_s_register(struct v4l2_subdev *sd, } #endif -static const struct v4l2_queryctrl mt9t031_controls[] = { - { - .id = V4L2_CID_VFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Vertically", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Flip Horizontally", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gain", - .minimum = 0, - .maximum = 127, - .step = 1, - .default_value = 64, - .flags = V4L2_CTRL_FLAG_SLIDER, - }, { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 1, - .maximum = 255, - .step = 1, - .default_value = 255, - .flags = V4L2_CTRL_FLAG_SLIDER, - }, { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Automatic Exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - } -}; - -static struct soc_camera_ops mt9t031_ops = { - .set_bus_param = mt9t031_set_bus_param, - .query_bus_param = mt9t031_query_bus_param, - .controls = mt9t031_controls, - .num_controls = ARRAY_SIZE(mt9t031_controls), -}; - static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct i2c_client *client = sd->priv; @@ -565,15 +573,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct i2c_client *client = sd->priv; struct mt9t031 *mt9t031 = to_mt9t031(client); - struct soc_camera_device *icd = client->dev.platform_data; const struct v4l2_queryctrl *qctrl; int data; - qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id); - - if (!qctrl) - return -EINVAL; - switch (ctrl->id) { case V4L2_CID_VFLIP: if (ctrl->value) @@ -592,6 +594,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) return -EIO; break; case V4L2_CID_GAIN: + qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN]; if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) return -EINVAL; /* See Datasheet Table 7, Gain settings. */ @@ -631,6 +634,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) mt9t031->gain = ctrl->value; break; case V4L2_CID_EXPOSURE: + qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; /* mt9t031 has maximum == default */ if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) return -EINVAL; @@ -657,7 +661,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) if (set_shutter(client, total_h) < 0) return -EIO; - qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); + qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * (qctrl->maximum - qctrl->minimum)) / shutter_max + qctrl->minimum; @@ -665,6 +669,8 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) } else mt9t031->autoexposure = 0; break; + default: + return -EINVAL; } return 0; } @@ -751,18 +757,16 @@ static int mt9t031_probe(struct i2c_client *client, struct mt9t031 *mt9t031; struct soc_camera_device *icd = client->dev.platform_data; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - struct soc_camera_link *icl; int ret; - if (!icd) { - dev_err(&client->dev, "MT9T031: missing soc-camera data!\n"); - return -EINVAL; - } + if (icd) { + struct soc_camera_link *icl = to_soc_camera_link(icd); + if (!icl) { + dev_err(&client->dev, "MT9T031 driver needs platform data\n"); + return -EINVAL; + } - icl = to_soc_camera_link(icd); - if (!icl) { - dev_err(&client->dev, "MT9T031 driver needs platform data\n"); - return -EINVAL; + icd->ops = &mt9t031_ops; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { @@ -777,9 +781,6 @@ static int mt9t031_probe(struct i2c_client *client, v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); - /* Second stage probe - when a capture adapter is there */ - icd->ops = &mt9t031_ops; - mt9t031->rect.left = MT9T031_COLUMN_SKIP; mt9t031->rect.top = MT9T031_ROW_SKIP; mt9t031->rect.width = MT9T031_MAX_WIDTH; @@ -801,7 +802,8 @@ static int mt9t031_probe(struct i2c_client *client, mt9t031_disable(client); if (ret) { - icd->ops = NULL; + if (icd) + icd->ops = NULL; i2c_set_clientdata(client, NULL); kfree(mt9t031); } @@ -814,7 +816,8 @@ static int mt9t031_remove(struct i2c_client *client) struct mt9t031 *mt9t031 = to_mt9t031(client); struct soc_camera_device *icd = client->dev.platform_data; - icd->ops = NULL; + if (icd) + icd->ops = NULL; i2c_set_clientdata(client, NULL); client->driver = NULL; kfree(mt9t031);