aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-09-09 12:39:20 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-11-03 16:29:03 -0400
commit2f0babb7e43278247df512263581c4738afa4cbc (patch)
treeb09a18f6f7756c9f793e36c26db17f4cfc9a558e /drivers/media
parent1a99b972a86ba9c3984c042f7f641458ad4812d0 (diff)
[media] V4L: soc-camera: make (almost) all client drivers re-usable outside of the framework
The most important change in this patch is direct linking to struct soc_camera_link via the client->dev.platform_data pointer. This makes most of the soc-camera client drivers also usable outside of the soc-camera framework. After this change all what is needed for these drivers to function are inclusions of soc-camera headers for some convenience macros, suitably configured platform data, which is anyway always required, and loaded soc-camera core module for library functions. If desired, these library functions can be made generic in the future and moved to a more neutral location. The only two client drivers, that still depend on soc-camera are: mt9t031: it uses struct video_device for its PM. Since no hardware is available, alternative methods cannot be tested. ov6650: it uses struct soc_camera_device to pass its sense data back to the bridge driver. A generic v4l2-subdevice approach should be developed to perform this. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/mt9t031.c29
-rw-r--r--drivers/media/video/ov6650.c2
-rw-r--r--drivers/media/video/soc_camera.c11
-rw-r--r--drivers/media/video/tw9910.c50
4 files changed, 65 insertions, 27 deletions
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 95cd602ae4ec..0226486d59be 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -22,6 +22,13 @@
22#include <media/v4l2-ctrls.h> 22#include <media/v4l2-ctrls.h>
23 23
24/* 24/*
25 * ATTENTION: this driver still cannot be used outside of the soc-camera
26 * framework because of its PM implementation, using the video_device node.
27 * If hardware becomes available for testing, alternative PM approaches shall
28 * be considered and tested.
29 */
30
31/*
25 * mt9t031 i2c address 0x5d 32 * mt9t031 i2c address 0x5d
26 * The platform has to define i2c_board_info and link to it from 33 * The platform has to define i2c_board_info and link to it from
27 * struct soc_camera_link 34 * struct soc_camera_link
@@ -606,6 +613,19 @@ static struct device_type mt9t031_dev_type = {
606 .pm = &mt9t031_dev_pm_ops, 613 .pm = &mt9t031_dev_pm_ops,
607}; 614};
608 615
616static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
617{
618 struct i2c_client *client = v4l2_get_subdevdata(sd);
619 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
620
621 if (on)
622 vdev->dev.type = &mt9t031_dev_type;
623 else
624 vdev->dev.type = NULL;
625
626 return 0;
627}
628
609/* 629/*
610 * Interface active, can use i2c. If it fails, it can indeed mean, that 630 * Interface active, can use i2c. If it fails, it can indeed mean, that
611 * this wasn't our capture interface, so, we wait for the right one 631 * this wasn't our capture interface, so, we wait for the right one
@@ -613,7 +633,6 @@ static struct device_type mt9t031_dev_type = {
613static int mt9t031_video_probe(struct i2c_client *client) 633static int mt9t031_video_probe(struct i2c_client *client)
614{ 634{
615 struct mt9t031 *mt9t031 = to_mt9t031(client); 635 struct mt9t031 *mt9t031 = to_mt9t031(client);
616 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
617 s32 data; 636 s32 data;
618 int ret; 637 int ret;
619 638
@@ -637,12 +656,11 @@ static int mt9t031_video_probe(struct i2c_client *client)
637 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data); 656 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
638 657
639 ret = mt9t031_idle(client); 658 ret = mt9t031_idle(client);
640 if (ret < 0) { 659 if (ret < 0)
641 dev_err(&client->dev, "Failed to initialise the camera\n"); 660 dev_err(&client->dev, "Failed to initialise the camera\n");
642 } else { 661 else
643 vdev->dev.type = &mt9t031_dev_type;
644 v4l2_ctrl_handler_setup(&mt9t031->hdl); 662 v4l2_ctrl_handler_setup(&mt9t031->hdl);
645 } 663
646 return ret; 664 return ret;
647} 665}
648 666
@@ -663,6 +681,7 @@ static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
663 681
664static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 682static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
665 .g_chip_ident = mt9t031_g_chip_ident, 683 .g_chip_ident = mt9t031_g_chip_ident,
684 .s_power = mt9t031_s_power,
666#ifdef CONFIG_VIDEO_ADV_DEBUG 685#ifdef CONFIG_VIDEO_ADV_DEBUG
667 .g_register = mt9t031_g_register, 686 .g_register = mt9t031_g_register,
668 .s_register = mt9t031_s_register, 687 .s_register = mt9t031_s_register,
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index f060eaaf916f..eb296f9e69f4 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -541,7 +541,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe,
541static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) 541static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
542{ 542{
543 struct i2c_client *client = v4l2_get_subdevdata(sd); 543 struct i2c_client *client = v4l2_get_subdevdata(sd);
544 struct soc_camera_device *icd = client->dev.platform_data; 544 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
545 struct soc_camera_sense *sense = icd->sense; 545 struct soc_camera_sense *sense = icd->sense;
546 struct ov6650 *priv = to_ov6650(client); 546 struct ov6650 *priv = to_ov6650(client);
547 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); 547 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 9a62ed08d86a..b72580c38957 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -249,6 +249,14 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
249 return v4l2_subdev_call(sd, core, s_std, *a); 249 return v4l2_subdev_call(sd, core, s_std, *a);
250} 250}
251 251
252static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
253{
254 struct soc_camera_device *icd = file->private_data;
255 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
256
257 return v4l2_subdev_call(sd, core, g_std, a);
258}
259
252static int soc_camera_enum_fsizes(struct file *file, void *fh, 260static int soc_camera_enum_fsizes(struct file *file, void *fh,
253 struct v4l2_frmsizeenum *fsize) 261 struct v4l2_frmsizeenum *fsize)
254{ 262{
@@ -977,7 +985,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
977 goto ei2cga; 985 goto ei2cga;
978 } 986 }
979 987
980 icl->board_info->platform_data = icd; 988 icl->board_info->platform_data = icl;
981 989
982 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, 990 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
983 icl->board_info, NULL); 991 icl->board_info, NULL);
@@ -1376,6 +1384,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1376 .vidioc_g_input = soc_camera_g_input, 1384 .vidioc_g_input = soc_camera_g_input,
1377 .vidioc_s_input = soc_camera_s_input, 1385 .vidioc_s_input = soc_camera_s_input,
1378 .vidioc_s_std = soc_camera_s_std, 1386 .vidioc_s_std = soc_camera_s_std,
1387 .vidioc_g_std = soc_camera_g_std,
1379 .vidioc_enum_framesizes = soc_camera_enum_fsizes, 1388 .vidioc_enum_framesizes = soc_camera_enum_fsizes,
1380 .vidioc_reqbufs = soc_camera_reqbufs, 1389 .vidioc_reqbufs = soc_camera_reqbufs,
1381 .vidioc_querybuf = soc_camera_querybuf, 1390 .vidioc_querybuf = soc_camera_querybuf,
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 5a3722b756c7..efce5371915e 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -230,6 +230,7 @@ struct tw9910_priv {
230 struct v4l2_subdev subdev; 230 struct v4l2_subdev subdev;
231 struct tw9910_video_info *info; 231 struct tw9910_video_info *info;
232 const struct tw9910_scale_ctrl *scale; 232 const struct tw9910_scale_ctrl *scale;
233 v4l2_std_id norm;
233 u32 revision; 234 u32 revision;
234}; 235};
235 236
@@ -421,12 +422,11 @@ static int tw9910_power(struct i2c_client *client, int enable)
421 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); 422 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
422} 423}
423 424
424static const struct tw9910_scale_ctrl *tw9910_select_norm(struct soc_camera_device *icd, 425static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
425 u32 width, u32 height) 426 u32 width, u32 height)
426{ 427{
427 const struct tw9910_scale_ctrl *scale; 428 const struct tw9910_scale_ctrl *scale;
428 const struct tw9910_scale_ctrl *ret = NULL; 429 const struct tw9910_scale_ctrl *ret = NULL;
429 v4l2_std_id norm = icd->vdev->current_norm;
430 __u32 diff = 0xffffffff, tmp; 430 __u32 diff = 0xffffffff, tmp;
431 int size, i; 431 int size, i;
432 432
@@ -495,14 +495,27 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
495 return tw9910_power(client, enable); 495 return tw9910_power(client, enable);
496} 496}
497 497
498static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
499{
500 struct i2c_client *client = v4l2_get_subdevdata(sd);
501 struct tw9910_priv *priv = to_tw9910(client);
502
503 *norm = priv->norm;
504
505 return 0;
506}
507
498static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) 508static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
499{ 509{
500 int ret = -EINVAL; 510 struct i2c_client *client = v4l2_get_subdevdata(sd);
511 struct tw9910_priv *priv = to_tw9910(client);
501 512
502 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL)) 513 if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
503 ret = 0; 514 return -EINVAL;
504 515
505 return ret; 516 priv->norm = norm;
517
518 return 0;
506} 519}
507 520
508static int tw9910_g_chip_ident(struct v4l2_subdev *sd, 521static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
@@ -557,14 +570,13 @@ static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
557{ 570{
558 struct i2c_client *client = v4l2_get_subdevdata(sd); 571 struct i2c_client *client = v4l2_get_subdevdata(sd);
559 struct tw9910_priv *priv = to_tw9910(client); 572 struct tw9910_priv *priv = to_tw9910(client);
560 struct soc_camera_device *icd = client->dev.platform_data;
561 int ret = -EINVAL; 573 int ret = -EINVAL;
562 u8 val; 574 u8 val;
563 575
564 /* 576 /*
565 * select suitable norm 577 * select suitable norm
566 */ 578 */
567 priv->scale = tw9910_select_norm(icd, *width, *height); 579 priv->scale = tw9910_select_norm(priv->norm, *width, *height);
568 if (!priv->scale) 580 if (!priv->scale)
569 goto tw9910_set_fmt_error; 581 goto tw9910_set_fmt_error;
570 582
@@ -642,11 +654,11 @@ tw9910_set_fmt_error:
642static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 654static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
643{ 655{
644 struct i2c_client *client = v4l2_get_subdevdata(sd); 656 struct i2c_client *client = v4l2_get_subdevdata(sd);
645 struct soc_camera_device *icd = client->dev.platform_data; 657 struct tw9910_priv *priv = to_tw9910(client);
646 658
647 a->c.left = 0; 659 a->c.left = 0;
648 a->c.top = 0; 660 a->c.top = 0;
649 if (icd->vdev->current_norm & V4L2_STD_NTSC) { 661 if (priv->norm & V4L2_STD_NTSC) {
650 a->c.width = 640; 662 a->c.width = 640;
651 a->c.height = 480; 663 a->c.height = 480;
652 } else { 664 } else {
@@ -661,11 +673,11 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
661static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 673static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
662{ 674{
663 struct i2c_client *client = v4l2_get_subdevdata(sd); 675 struct i2c_client *client = v4l2_get_subdevdata(sd);
664 struct soc_camera_device *icd = client->dev.platform_data; 676 struct tw9910_priv *priv = to_tw9910(client);
665 677
666 a->bounds.left = 0; 678 a->bounds.left = 0;
667 a->bounds.top = 0; 679 a->bounds.top = 0;
668 if (icd->vdev->current_norm & V4L2_STD_NTSC) { 680 if (priv->norm & V4L2_STD_NTSC) {
669 a->bounds.width = 640; 681 a->bounds.width = 640;
670 a->bounds.height = 480; 682 a->bounds.height = 480;
671 } else { 683 } else {
@@ -732,7 +744,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
732 struct v4l2_mbus_framefmt *mf) 744 struct v4l2_mbus_framefmt *mf)
733{ 745{
734 struct i2c_client *client = v4l2_get_subdevdata(sd); 746 struct i2c_client *client = v4l2_get_subdevdata(sd);
735 struct soc_camera_device *icd = client->dev.platform_data; 747 struct tw9910_priv *priv = to_tw9910(client);
736 const struct tw9910_scale_ctrl *scale; 748 const struct tw9910_scale_ctrl *scale;
737 749
738 if (V4L2_FIELD_ANY == mf->field) { 750 if (V4L2_FIELD_ANY == mf->field) {
@@ -748,7 +760,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
748 /* 760 /*
749 * select suitable norm 761 * select suitable norm
750 */ 762 */
751 scale = tw9910_select_norm(icd, mf->width, mf->height); 763 scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
752 if (!scale) 764 if (!scale)
753 return -EINVAL; 765 return -EINVAL;
754 766
@@ -758,8 +770,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
758 return 0; 770 return 0;
759} 771}
760 772
761static int tw9910_video_probe(struct soc_camera_device *icd, 773static int tw9910_video_probe(struct i2c_client *client)
762 struct i2c_client *client)
763{ 774{
764 struct tw9910_priv *priv = to_tw9910(client); 775 struct tw9910_priv *priv = to_tw9910(client);
765 s32 id; 776 s32 id;
@@ -792,8 +803,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
792 dev_info(&client->dev, 803 dev_info(&client->dev,
793 "tw9910 Product ID %0x:%0x\n", id, priv->revision); 804 "tw9910 Product ID %0x:%0x\n", id, priv->revision);
794 805
795 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 806 priv->norm = V4L2_STD_NTSC;
796 icd->vdev->current_norm = V4L2_STD_NTSC;
797 807
798 return 0; 808 return 0;
799} 809}
@@ -801,6 +811,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
801static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { 811static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
802 .g_chip_ident = tw9910_g_chip_ident, 812 .g_chip_ident = tw9910_g_chip_ident,
803 .s_std = tw9910_s_std, 813 .s_std = tw9910_s_std,
814 .g_std = tw9910_g_std,
804#ifdef CONFIG_VIDEO_ADV_DEBUG 815#ifdef CONFIG_VIDEO_ADV_DEBUG
805 .g_register = tw9910_g_register, 816 .g_register = tw9910_g_register,
806 .s_register = tw9910_s_register, 817 .s_register = tw9910_s_register,
@@ -883,7 +894,6 @@ static int tw9910_probe(struct i2c_client *client,
883{ 894{
884 struct tw9910_priv *priv; 895 struct tw9910_priv *priv;
885 struct tw9910_video_info *info; 896 struct tw9910_video_info *info;
886 struct soc_camera_device *icd = client->dev.platform_data;
887 struct i2c_adapter *adapter = 897 struct i2c_adapter *adapter =
888 to_i2c_adapter(client->dev.parent); 898 to_i2c_adapter(client->dev.parent);
889 struct soc_camera_link *icl = soc_camera_i2c_to_link(client); 899 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
@@ -911,7 +921,7 @@ static int tw9910_probe(struct i2c_client *client,
911 921
912 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); 922 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
913 923
914 ret = tw9910_video_probe(icd, client); 924 ret = tw9910_video_probe(client);
915 if (ret) 925 if (ret)
916 kfree(priv); 926 kfree(priv);
917 927