aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tw9910.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:43:33 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:35 -0400
commit979ea1ddf80ac7383acdea03471355ca62702539 (patch)
tree2ee4c73eb672c1ee8167ed7e0906bac6f3b00e69 /drivers/media/video/tw9910.c
parent0bab829de1ab60d8c3cbf7e402192bb9446840b7 (diff)
V4L/DVB (12510): soc-camera: (partially) convert to v4l2-(sub)dev API
Convert the soc-camera framework to use the v4l2-(sub)dev API. Start using v4l2-subdev operations. Only a part of the interface between the soc_camera core, soc_camera host drivers on one side and soc_camera device drivers on the other side is replaced so far. The rest of the interface will be replaced in incremental steps, and will require extensions and, possibly, modifications to the v4l2-subdev code. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/tw9910.c')
-rw-r--r--drivers/media/video/tw9910.c151
1 files changed, 63 insertions, 88 deletions
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index d780a509faa9..a006df1d28ec 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -24,7 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h> 26#include <media/v4l2-chip-ident.h>
27#include <media/v4l2-common.h> 27#include <media/v4l2-subdev.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30 30
@@ -223,6 +223,7 @@ struct tw9910_hsync_ctrl {
223}; 223};
224 224
225struct tw9910_priv { 225struct tw9910_priv {
226 struct v4l2_subdev subdev;
226 struct tw9910_video_info *info; 227 struct tw9910_video_info *info;
227 const struct tw9910_scale_ctrl *scale; 228 const struct tw9910_scale_ctrl *scale;
228}; 229};
@@ -354,6 +355,11 @@ static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
354/* 355/*
355 * general function 356 * general function
356 */ 357 */
358static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
359{
360 return container_of(i2c_get_clientdata(client), struct tw9910_priv, subdev);
361}
362
357static int tw9910_set_scale(struct i2c_client *client, 363static int tw9910_set_scale(struct i2c_client *client,
358 const struct tw9910_scale_ctrl *scale) 364 const struct tw9910_scale_ctrl *scale)
359{ 365{
@@ -507,47 +513,20 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
507/* 513/*
508 * soc_camera_ops function 514 * soc_camera_ops function
509 */ 515 */
510static int tw9910_init(struct soc_camera_device *icd) 516static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
511{ 517{
512 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 518 struct i2c_client *client = sd->priv;
513 struct soc_camera_link *icl = to_soc_camera_link(icd); 519 struct tw9910_priv *priv = to_tw9910(client);
514 int ret = 0;
515 520
516 if (icl->power) { 521 if (!enable)
517 ret = icl->power(&client->dev, 1); 522 return 0;
518 if (ret < 0)
519 return ret;
520 }
521
522 if (icl->reset)
523 ret = icl->reset(&client->dev);
524
525 return ret;
526}
527
528static int tw9910_release(struct soc_camera_device *icd)
529{
530 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
531 struct soc_camera_link *icl = to_soc_camera_link(icd);
532 int ret = 0;
533
534 if (icl->power)
535 ret = icl->power(&client->dev, 0);
536
537 return ret;
538}
539
540static int tw9910_start_capture(struct soc_camera_device *icd)
541{
542 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
543 struct tw9910_priv *priv = i2c_get_clientdata(client);
544 523
545 if (!priv->scale) { 524 if (!priv->scale) {
546 dev_err(&icd->dev, "norm select error\n"); 525 dev_err(&client->dev, "norm select error\n");
547 return -EPERM; 526 return -EPERM;
548 } 527 }
549 528
550 dev_dbg(&icd->dev, "%s %dx%d\n", 529 dev_dbg(&client->dev, "%s %dx%d\n",
551 priv->scale->name, 530 priv->scale->name,
552 priv->scale->width, 531 priv->scale->width,
553 priv->scale->height); 532 priv->scale->height);
@@ -555,11 +534,6 @@ static int tw9910_start_capture(struct soc_camera_device *icd)
555 return 0; 534 return 0;
556} 535}
557 536
558static int tw9910_stop_capture(struct soc_camera_device *icd)
559{
560 return 0;
561}
562
563static int tw9910_set_bus_param(struct soc_camera_device *icd, 537static int tw9910_set_bus_param(struct soc_camera_device *icd,
564 unsigned long flags) 538 unsigned long flags)
565{ 539{
@@ -569,7 +543,7 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
569static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) 543static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
570{ 544{
571 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 545 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
572 struct tw9910_priv *priv = i2c_get_clientdata(client); 546 struct tw9910_priv *priv = to_tw9910(client);
573 struct soc_camera_link *icl = to_soc_camera_link(icd); 547 struct soc_camera_link *icl = to_soc_camera_link(icd);
574 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 548 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
575 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 549 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
@@ -578,21 +552,11 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
578 return soc_camera_apply_sensor_flags(icl, flags); 552 return soc_camera_apply_sensor_flags(icl, flags);
579} 553}
580 554
581static int tw9910_get_chip_id(struct soc_camera_device *icd, 555static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
582 struct v4l2_dbg_chip_ident *id)
583{
584 id->ident = V4L2_IDENT_TW9910;
585 id->revision = 0;
586
587 return 0;
588}
589
590static int tw9910_set_std(struct soc_camera_device *icd,
591 v4l2_std_id *a)
592{ 556{
593 int ret = -EINVAL; 557 int ret = -EINVAL;
594 558
595 if (*a & (V4L2_STD_NTSC | V4L2_STD_PAL)) 559 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
596 ret = 0; 560 ret = 0;
597 561
598 return ret; 562 return ret;
@@ -608,11 +572,20 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
608 return 0; 572 return 0;
609} 573}
610 574
575static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
576 struct v4l2_dbg_chip_ident *id)
577{
578 id->ident = V4L2_IDENT_TW9910;
579 id->revision = 0;
580
581 return 0;
582}
583
611#ifdef CONFIG_VIDEO_ADV_DEBUG 584#ifdef CONFIG_VIDEO_ADV_DEBUG
612static int tw9910_get_register(struct soc_camera_device *icd, 585static int tw9910_g_register(struct v4l2_subdev *sd,
613 struct v4l2_dbg_register *reg) 586 struct v4l2_dbg_register *reg)
614{ 587{
615 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 588 struct i2c_client *client = sd->priv;
616 int ret; 589 int ret;
617 590
618 if (reg->reg > 0xff) 591 if (reg->reg > 0xff)
@@ -630,10 +603,10 @@ static int tw9910_get_register(struct soc_camera_device *icd,
630 return 0; 603 return 0;
631} 604}
632 605
633static int tw9910_set_register(struct soc_camera_device *icd, 606static int tw9910_s_register(struct v4l2_subdev *sd,
634 struct v4l2_dbg_register *reg) 607 struct v4l2_dbg_register *reg)
635{ 608{
636 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 609 struct i2c_client *client = sd->priv;
637 610
638 if (reg->reg > 0xff || 611 if (reg->reg > 0xff ||
639 reg->val > 0xff) 612 reg->val > 0xff)
@@ -647,7 +620,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
647 struct v4l2_rect *rect) 620 struct v4l2_rect *rect)
648{ 621{
649 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 622 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
650 struct tw9910_priv *priv = i2c_get_clientdata(client); 623 struct tw9910_priv *priv = to_tw9910(client);
651 int ret = -EINVAL; 624 int ret = -EINVAL;
652 u8 val; 625 u8 val;
653 626
@@ -736,9 +709,10 @@ tw9910_set_fmt_error:
736 return ret; 709 return ret;
737} 710}
738 711
739static int tw9910_set_fmt(struct soc_camera_device *icd, 712static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
740 struct v4l2_format *f)
741{ 713{
714 struct i2c_client *client = sd->priv;
715 struct soc_camera_device *icd = client->dev.platform_data;
742 struct v4l2_pix_format *pix = &f->fmt.pix; 716 struct v4l2_pix_format *pix = &f->fmt.pix;
743 struct v4l2_rect rect = { 717 struct v4l2_rect rect = {
744 .left = icd->x_current, 718 .left = icd->x_current,
@@ -761,16 +735,17 @@ static int tw9910_set_fmt(struct soc_camera_device *icd,
761 return tw9910_set_crop(icd, &rect); 735 return tw9910_set_crop(icd, &rect);
762} 736}
763 737
764static int tw9910_try_fmt(struct soc_camera_device *icd, 738static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
765 struct v4l2_format *f)
766{ 739{
740 struct i2c_client *client = sd->priv;
741 struct soc_camera_device *icd = client->dev.platform_data;
767 struct v4l2_pix_format *pix = &f->fmt.pix; 742 struct v4l2_pix_format *pix = &f->fmt.pix;
768 const struct tw9910_scale_ctrl *scale; 743 const struct tw9910_scale_ctrl *scale;
769 744
770 if (V4L2_FIELD_ANY == pix->field) { 745 if (V4L2_FIELD_ANY == pix->field) {
771 pix->field = V4L2_FIELD_INTERLACED; 746 pix->field = V4L2_FIELD_INTERLACED;
772 } else if (V4L2_FIELD_INTERLACED != pix->field) { 747 } else if (V4L2_FIELD_INTERLACED != pix->field) {
773 dev_err(&icd->dev, "Field type invalid.\n"); 748 dev_err(&client->dev, "Field type invalid.\n");
774 return -EINVAL; 749 return -EINVAL;
775 } 750 }
776 751
@@ -790,9 +765,8 @@ static int tw9910_try_fmt(struct soc_camera_device *icd,
790static int tw9910_video_probe(struct soc_camera_device *icd, 765static int tw9910_video_probe(struct soc_camera_device *icd,
791 struct i2c_client *client) 766 struct i2c_client *client)
792{ 767{
793 struct tw9910_priv *priv = i2c_get_clientdata(client); 768 struct tw9910_priv *priv = to_tw9910(client);
794 s32 val; 769 s32 val;
795 int ret;
796 770
797 /* 771 /*
798 * We must have a parent by now. And it cannot be a wrong one. 772 * We must have a parent by now. And it cannot be a wrong one.
@@ -814,18 +788,11 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
814 icd->formats = tw9910_color_fmt; 788 icd->formats = tw9910_color_fmt;
815 icd->num_formats = ARRAY_SIZE(tw9910_color_fmt); 789 icd->num_formats = ARRAY_SIZE(tw9910_color_fmt);
816 790
817 /* Switch master clock on */
818 ret = soc_camera_video_start(icd, &client->dev);
819 if (ret)
820 return ret;
821
822 /* 791 /*
823 * check and show Product ID 792 * check and show Product ID
824 */ 793 */
825 val = i2c_smbus_read_byte_data(client, ID); 794 val = i2c_smbus_read_byte_data(client, ID);
826 795
827 soc_camera_video_stop(icd);
828
829 if (0x0B != GET_ID(val) || 796 if (0x0B != GET_ID(val) ||
830 0x00 != GET_ReV(val)) { 797 0x00 != GET_ReV(val)) {
831 dev_err(&icd->dev, 798 dev_err(&icd->dev,
@@ -839,29 +806,36 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
839 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 806 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
840 icd->vdev->current_norm = V4L2_STD_NTSC; 807 icd->vdev->current_norm = V4L2_STD_NTSC;
841 808
842 return ret; 809 return 0;
843} 810}
844 811
845static struct soc_camera_ops tw9910_ops = { 812static struct soc_camera_ops tw9910_ops = {
846 .owner = THIS_MODULE,
847 .init = tw9910_init,
848 .release = tw9910_release,
849 .start_capture = tw9910_start_capture,
850 .stop_capture = tw9910_stop_capture,
851 .set_crop = tw9910_set_crop, 813 .set_crop = tw9910_set_crop,
852 .set_fmt = tw9910_set_fmt,
853 .try_fmt = tw9910_try_fmt,
854 .set_bus_param = tw9910_set_bus_param, 814 .set_bus_param = tw9910_set_bus_param,
855 .query_bus_param = tw9910_query_bus_param, 815 .query_bus_param = tw9910_query_bus_param,
856 .get_chip_id = tw9910_get_chip_id,
857 .set_std = tw9910_set_std,
858 .enum_input = tw9910_enum_input, 816 .enum_input = tw9910_enum_input,
817};
818
819static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
820 .g_chip_ident = tw9910_g_chip_ident,
821 .s_std = tw9910_s_std,
859#ifdef CONFIG_VIDEO_ADV_DEBUG 822#ifdef CONFIG_VIDEO_ADV_DEBUG
860 .get_register = tw9910_get_register, 823 .g_register = tw9910_g_register,
861 .set_register = tw9910_set_register, 824 .s_register = tw9910_s_register,
862#endif 825#endif
863}; 826};
864 827
828static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
829 .s_stream = tw9910_s_stream,
830 .s_fmt = tw9910_s_fmt,
831 .try_fmt = tw9910_try_fmt,
832};
833
834static struct v4l2_subdev_ops tw9910_subdev_ops = {
835 .core = &tw9910_subdev_core_ops,
836 .video = &tw9910_subdev_video_ops,
837};
838
865/* 839/*
866 * i2c_driver function 840 * i2c_driver function
867 */ 841 */
@@ -902,7 +876,8 @@ static int tw9910_probe(struct i2c_client *client,
902 return -ENOMEM; 876 return -ENOMEM;
903 877
904 priv->info = info; 878 priv->info = info;
905 i2c_set_clientdata(client, priv); 879
880 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
906 881
907 icd->ops = &tw9910_ops; 882 icd->ops = &tw9910_ops;
908 icd->iface = info->link.bus_id; 883 icd->iface = info->link.bus_id;
@@ -942,7 +917,7 @@ static int tw9910_probe(struct i2c_client *client,
942 917
943static int tw9910_remove(struct i2c_client *client) 918static int tw9910_remove(struct i2c_client *client)
944{ 919{
945 struct tw9910_priv *priv = i2c_get_clientdata(client); 920 struct tw9910_priv *priv = to_tw9910(client);
946 struct soc_camera_device *icd = client->dev.platform_data; 921 struct soc_camera_device *icd = client->dev.platform_data;
947 922
948 icd->ops = NULL; 923 icd->ops = NULL;