aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tw9910.c
diff options
context:
space:
mode:
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;