diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-12-11 09:53:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-16 06:27:31 -0500 |
commit | a3a4ac14774786bef160ea380bd75307a144a5e9 (patch) | |
tree | aa4d97f29e3ec15c86e7dc1b0e6e9072517750be /drivers/media/video/mt9t031.c | |
parent | a6b5f2008a3d54b5f5350a01121b718dd6bfead7 (diff) |
V4L/DVB (13662): mt9t031: make the use of the soc-camera client API optional
Now that we have moved most of the functions over to the v4l2-subdev API, only
quering and setting bus parameters are still performed using the legacy
soc-camera client API. Make the use of this API optional for mt9t031.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mt9t031.c')
-rw-r--r-- | drivers/media/video/mt9t031.c | 167 |
1 files changed, 85 insertions, 82 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c index 69c227f65bcb..a9061bff79b2 100644 --- a/drivers/media/video/mt9t031.c +++ b/drivers/media/video/mt9t031.c | |||
@@ -201,6 +201,71 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) | |||
201 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); | 201 | return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); |
202 | } | 202 | } |
203 | 203 | ||
204 | enum { | ||
205 | MT9T031_CTRL_VFLIP, | ||
206 | MT9T031_CTRL_HFLIP, | ||
207 | MT9T031_CTRL_GAIN, | ||
208 | MT9T031_CTRL_EXPOSURE, | ||
209 | MT9T031_CTRL_EXPOSURE_AUTO, | ||
210 | }; | ||
211 | |||
212 | static const struct v4l2_queryctrl mt9t031_controls[] = { | ||
213 | [MT9T031_CTRL_VFLIP] = { | ||
214 | .id = V4L2_CID_VFLIP, | ||
215 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
216 | .name = "Flip Vertically", | ||
217 | .minimum = 0, | ||
218 | .maximum = 1, | ||
219 | .step = 1, | ||
220 | .default_value = 0, | ||
221 | }, | ||
222 | [MT9T031_CTRL_HFLIP] = { | ||
223 | .id = V4L2_CID_HFLIP, | ||
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
225 | .name = "Flip Horizontally", | ||
226 | .minimum = 0, | ||
227 | .maximum = 1, | ||
228 | .step = 1, | ||
229 | .default_value = 0, | ||
230 | }, | ||
231 | [MT9T031_CTRL_GAIN] = { | ||
232 | .id = V4L2_CID_GAIN, | ||
233 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
234 | .name = "Gain", | ||
235 | .minimum = 0, | ||
236 | .maximum = 127, | ||
237 | .step = 1, | ||
238 | .default_value = 64, | ||
239 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
240 | }, | ||
241 | [MT9T031_CTRL_EXPOSURE] = { | ||
242 | .id = V4L2_CID_EXPOSURE, | ||
243 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
244 | .name = "Exposure", | ||
245 | .minimum = 1, | ||
246 | .maximum = 255, | ||
247 | .step = 1, | ||
248 | .default_value = 255, | ||
249 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
250 | }, | ||
251 | [MT9T031_CTRL_EXPOSURE_AUTO] = { | ||
252 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
253 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
254 | .name = "Automatic Exposure", | ||
255 | .minimum = 0, | ||
256 | .maximum = 1, | ||
257 | .step = 1, | ||
258 | .default_value = 1, | ||
259 | } | ||
260 | }; | ||
261 | |||
262 | static struct soc_camera_ops mt9t031_ops = { | ||
263 | .set_bus_param = mt9t031_set_bus_param, | ||
264 | .query_bus_param = mt9t031_query_bus_param, | ||
265 | .controls = mt9t031_controls, | ||
266 | .num_controls = ARRAY_SIZE(mt9t031_controls), | ||
267 | }; | ||
268 | |||
204 | /* target must be _even_ */ | 269 | /* target must be _even_ */ |
205 | static u16 mt9t031_skip(s32 *source, s32 target, s32 max) | 270 | static u16 mt9t031_skip(s32 *source, s32 target, s32 max) |
206 | { | 271 | { |
@@ -220,10 +285,9 @@ static u16 mt9t031_skip(s32 *source, s32 target, s32 max) | |||
220 | } | 285 | } |
221 | 286 | ||
222 | /* rect is the sensor rectangle, the caller guarantees parameter validity */ | 287 | /* rect is the sensor rectangle, the caller guarantees parameter validity */ |
223 | static int mt9t031_set_params(struct soc_camera_device *icd, | 288 | static int mt9t031_set_params(struct i2c_client *client, |
224 | struct v4l2_rect *rect, u16 xskip, u16 yskip) | 289 | struct v4l2_rect *rect, u16 xskip, u16 yskip) |
225 | { | 290 | { |
226 | struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); | ||
227 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 291 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
228 | int ret; | 292 | int ret; |
229 | u16 xbin, ybin; | 293 | u16 xbin, ybin; |
@@ -304,8 +368,7 @@ static int mt9t031_set_params(struct soc_camera_device *icd, | |||
304 | if (ret >= 0) { | 368 | if (ret >= 0) { |
305 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; | 369 | const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; |
306 | const struct v4l2_queryctrl *qctrl = | 370 | const struct v4l2_queryctrl *qctrl = |
307 | soc_camera_find_qctrl(icd->ops, | 371 | &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; |
308 | V4L2_CID_EXPOSURE); | ||
309 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * | 372 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
310 | (qctrl->maximum - qctrl->minimum)) / | 373 | (qctrl->maximum - qctrl->minimum)) / |
311 | shutter_max + qctrl->minimum; | 374 | shutter_max + qctrl->minimum; |
@@ -330,7 +393,6 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
330 | struct v4l2_rect rect = a->c; | 393 | struct v4l2_rect rect = a->c; |
331 | struct i2c_client *client = sd->priv; | 394 | struct i2c_client *client = sd->priv; |
332 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 395 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
333 | struct soc_camera_device *icd = client->dev.platform_data; | ||
334 | 396 | ||
335 | rect.width = ALIGN(rect.width, 2); | 397 | rect.width = ALIGN(rect.width, 2); |
336 | rect.height = ALIGN(rect.height, 2); | 398 | rect.height = ALIGN(rect.height, 2); |
@@ -341,7 +403,7 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | |||
341 | soc_camera_limit_side(&rect.top, &rect.height, | 403 | soc_camera_limit_side(&rect.top, &rect.height, |
342 | MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); | 404 | MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT); |
343 | 405 | ||
344 | return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip); | 406 | return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip); |
345 | } | 407 | } |
346 | 408 | ||
347 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) | 409 | static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) |
@@ -389,7 +451,6 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, | |||
389 | { | 451 | { |
390 | struct i2c_client *client = sd->priv; | 452 | struct i2c_client *client = sd->priv; |
391 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 453 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
392 | struct soc_camera_device *icd = client->dev.platform_data; | ||
393 | u16 xskip, yskip; | 454 | u16 xskip, yskip; |
394 | struct v4l2_rect rect = mt9t031->rect; | 455 | struct v4l2_rect rect = mt9t031->rect; |
395 | 456 | ||
@@ -404,7 +465,7 @@ static int mt9t031_s_fmt(struct v4l2_subdev *sd, | |||
404 | mf->colorspace = V4L2_COLORSPACE_SRGB; | 465 | mf->colorspace = V4L2_COLORSPACE_SRGB; |
405 | 466 | ||
406 | /* mt9t031_set_params() doesn't change width and height */ | 467 | /* mt9t031_set_params() doesn't change width and height */ |
407 | return mt9t031_set_params(icd, &rect, xskip, yskip); | 468 | return mt9t031_set_params(client, &rect, xskip, yskip); |
408 | } | 469 | } |
409 | 470 | ||
410 | /* | 471 | /* |
@@ -480,59 +541,6 @@ static int mt9t031_s_register(struct v4l2_subdev *sd, | |||
480 | } | 541 | } |
481 | #endif | 542 | #endif |
482 | 543 | ||
483 | static const struct v4l2_queryctrl mt9t031_controls[] = { | ||
484 | { | ||
485 | .id = V4L2_CID_VFLIP, | ||
486 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
487 | .name = "Flip Vertically", | ||
488 | .minimum = 0, | ||
489 | .maximum = 1, | ||
490 | .step = 1, | ||
491 | .default_value = 0, | ||
492 | }, { | ||
493 | .id = V4L2_CID_HFLIP, | ||
494 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
495 | .name = "Flip Horizontally", | ||
496 | .minimum = 0, | ||
497 | .maximum = 1, | ||
498 | .step = 1, | ||
499 | .default_value = 0, | ||
500 | }, { | ||
501 | .id = V4L2_CID_GAIN, | ||
502 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
503 | .name = "Gain", | ||
504 | .minimum = 0, | ||
505 | .maximum = 127, | ||
506 | .step = 1, | ||
507 | .default_value = 64, | ||
508 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
509 | }, { | ||
510 | .id = V4L2_CID_EXPOSURE, | ||
511 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
512 | .name = "Exposure", | ||
513 | .minimum = 1, | ||
514 | .maximum = 255, | ||
515 | .step = 1, | ||
516 | .default_value = 255, | ||
517 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
518 | }, { | ||
519 | .id = V4L2_CID_EXPOSURE_AUTO, | ||
520 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
521 | .name = "Automatic Exposure", | ||
522 | .minimum = 0, | ||
523 | .maximum = 1, | ||
524 | .step = 1, | ||
525 | .default_value = 1, | ||
526 | } | ||
527 | }; | ||
528 | |||
529 | static struct soc_camera_ops mt9t031_ops = { | ||
530 | .set_bus_param = mt9t031_set_bus_param, | ||
531 | .query_bus_param = mt9t031_query_bus_param, | ||
532 | .controls = mt9t031_controls, | ||
533 | .num_controls = ARRAY_SIZE(mt9t031_controls), | ||
534 | }; | ||
535 | |||
536 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | 544 | static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) |
537 | { | 545 | { |
538 | struct i2c_client *client = sd->priv; | 546 | struct i2c_client *client = sd->priv; |
@@ -569,15 +577,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
569 | { | 577 | { |
570 | struct i2c_client *client = sd->priv; | 578 | struct i2c_client *client = sd->priv; |
571 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 579 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
572 | struct soc_camera_device *icd = client->dev.platform_data; | ||
573 | const struct v4l2_queryctrl *qctrl; | 580 | const struct v4l2_queryctrl *qctrl; |
574 | int data; | 581 | int data; |
575 | 582 | ||
576 | qctrl = soc_camera_find_qctrl(&mt9t031_ops, ctrl->id); | ||
577 | |||
578 | if (!qctrl) | ||
579 | return -EINVAL; | ||
580 | |||
581 | switch (ctrl->id) { | 583 | switch (ctrl->id) { |
582 | case V4L2_CID_VFLIP: | 584 | case V4L2_CID_VFLIP: |
583 | if (ctrl->value) | 585 | if (ctrl->value) |
@@ -596,6 +598,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
596 | return -EIO; | 598 | return -EIO; |
597 | break; | 599 | break; |
598 | case V4L2_CID_GAIN: | 600 | case V4L2_CID_GAIN: |
601 | qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN]; | ||
599 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | 602 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) |
600 | return -EINVAL; | 603 | return -EINVAL; |
601 | /* See Datasheet Table 7, Gain settings. */ | 604 | /* See Datasheet Table 7, Gain settings. */ |
@@ -635,6 +638,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
635 | mt9t031->gain = ctrl->value; | 638 | mt9t031->gain = ctrl->value; |
636 | break; | 639 | break; |
637 | case V4L2_CID_EXPOSURE: | 640 | case V4L2_CID_EXPOSURE: |
641 | qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; | ||
638 | /* mt9t031 has maximum == default */ | 642 | /* mt9t031 has maximum == default */ |
639 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) | 643 | if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) |
640 | return -EINVAL; | 644 | return -EINVAL; |
@@ -662,7 +666,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
662 | 666 | ||
663 | if (set_shutter(client, total_h) < 0) | 667 | if (set_shutter(client, total_h) < 0) |
664 | return -EIO; | 668 | return -EIO; |
665 | qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); | 669 | qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; |
666 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * | 670 | mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * |
667 | (qctrl->maximum - qctrl->minimum)) / | 671 | (qctrl->maximum - qctrl->minimum)) / |
668 | shutter_max + qctrl->minimum; | 672 | shutter_max + qctrl->minimum; |
@@ -670,6 +674,8 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
670 | } else | 674 | } else |
671 | mt9t031->autoexposure = 0; | 675 | mt9t031->autoexposure = 0; |
672 | break; | 676 | break; |
677 | default: | ||
678 | return -EINVAL; | ||
673 | } | 679 | } |
674 | return 0; | 680 | return 0; |
675 | } | 681 | } |
@@ -771,18 +777,16 @@ static int mt9t031_probe(struct i2c_client *client, | |||
771 | struct mt9t031 *mt9t031; | 777 | struct mt9t031 *mt9t031; |
772 | struct soc_camera_device *icd = client->dev.platform_data; | 778 | struct soc_camera_device *icd = client->dev.platform_data; |
773 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 779 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
774 | struct soc_camera_link *icl; | ||
775 | int ret; | 780 | int ret; |
776 | 781 | ||
777 | if (!icd) { | 782 | if (icd) { |
778 | dev_err(&client->dev, "MT9T031: missing soc-camera data!\n"); | 783 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
779 | return -EINVAL; | 784 | if (!icl) { |
780 | } | 785 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); |
786 | return -EINVAL; | ||
787 | } | ||
781 | 788 | ||
782 | icl = to_soc_camera_link(icd); | 789 | icd->ops = &mt9t031_ops; |
783 | if (!icl) { | ||
784 | dev_err(&client->dev, "MT9T031 driver needs platform data\n"); | ||
785 | return -EINVAL; | ||
786 | } | 790 | } |
787 | 791 | ||
788 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { | 792 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { |
@@ -797,9 +801,6 @@ static int mt9t031_probe(struct i2c_client *client, | |||
797 | 801 | ||
798 | v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); | 802 | v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); |
799 | 803 | ||
800 | /* Second stage probe - when a capture adapter is there */ | ||
801 | icd->ops = &mt9t031_ops; | ||
802 | |||
803 | mt9t031->y_skip_top = 0; | 804 | mt9t031->y_skip_top = 0; |
804 | mt9t031->rect.left = MT9T031_COLUMN_SKIP; | 805 | mt9t031->rect.left = MT9T031_COLUMN_SKIP; |
805 | mt9t031->rect.top = MT9T031_ROW_SKIP; | 806 | mt9t031->rect.top = MT9T031_ROW_SKIP; |
@@ -822,7 +823,8 @@ static int mt9t031_probe(struct i2c_client *client, | |||
822 | mt9t031_disable(client); | 823 | mt9t031_disable(client); |
823 | 824 | ||
824 | if (ret) { | 825 | if (ret) { |
825 | icd->ops = NULL; | 826 | if (icd) |
827 | icd->ops = NULL; | ||
826 | i2c_set_clientdata(client, NULL); | 828 | i2c_set_clientdata(client, NULL); |
827 | kfree(mt9t031); | 829 | kfree(mt9t031); |
828 | } | 830 | } |
@@ -835,7 +837,8 @@ static int mt9t031_remove(struct i2c_client *client) | |||
835 | struct mt9t031 *mt9t031 = to_mt9t031(client); | 837 | struct mt9t031 *mt9t031 = to_mt9t031(client); |
836 | struct soc_camera_device *icd = client->dev.platform_data; | 838 | struct soc_camera_device *icd = client->dev.platform_data; |
837 | 839 | ||
838 | icd->ops = NULL; | 840 | if (icd) |
841 | icd->ops = NULL; | ||
839 | i2c_set_clientdata(client, NULL); | 842 | i2c_set_clientdata(client, NULL); |
840 | client->driver = NULL; | 843 | client->driver = NULL; |
841 | kfree(mt9t031); | 844 | kfree(mt9t031); |