aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ov772x.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-08-25 10:28:22 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:18:27 -0400
commit40e2e0927003424c25807b575dd40da2b8685857 (patch)
tree917ca8fd5f7598194d264ec92a08b312d4932b90 /drivers/media/video/ov772x.c
parentbc1937b41d8253e2b554da385023a92189d38917 (diff)
V4L/DVB (12506): soc-camera: convert to platform device
Convert soc-camera core and all drivers to platform device API. We already converted platforms to register a platform device for each soc-camera client, now we remove the compatibility code and switch completely to the new scheme. This is a preparatory step for the v4l2-subdev conversion. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r--drivers/media/video/ov772x.c157
1 files changed, 86 insertions, 71 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 0bce255168bd..3ea650d55b17 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -399,8 +399,6 @@ struct ov772x_win_size {
399 399
400struct ov772x_priv { 400struct ov772x_priv {
401 struct ov772x_camera_info *info; 401 struct ov772x_camera_info *info;
402 struct i2c_client *client;
403 struct soc_camera_device icd;
404 const struct ov772x_color_format *fmt; 402 const struct ov772x_color_format *fmt;
405 const struct ov772x_win_size *win; 403 const struct ov772x_win_size *win;
406 int model; 404 int model;
@@ -619,53 +617,56 @@ static int ov772x_reset(struct i2c_client *client)
619 617
620static int ov772x_init(struct soc_camera_device *icd) 618static int ov772x_init(struct soc_camera_device *icd)
621{ 619{
622 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 620 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
621 struct soc_camera_link *icl = to_soc_camera_link(icd);
623 int ret = 0; 622 int ret = 0;
624 623
625 if (priv->info->link.power) { 624 if (icl->power) {
626 ret = priv->info->link.power(&priv->client->dev, 1); 625 ret = icl->power(&client->dev, 1);
627 if (ret < 0) 626 if (ret < 0)
628 return ret; 627 return ret;
629 } 628 }
630 629
631 if (priv->info->link.reset) 630 if (icl->reset)
632 ret = priv->info->link.reset(&priv->client->dev); 631 ret = icl->reset(&client->dev);
633 632
634 return ret; 633 return ret;
635} 634}
636 635
637static int ov772x_release(struct soc_camera_device *icd) 636static int ov772x_release(struct soc_camera_device *icd)
638{ 637{
639 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 638 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
639 struct soc_camera_link *icl = to_soc_camera_link(icd);
640 int ret = 0; 640 int ret = 0;
641 641
642 if (priv->info->link.power) 642 if (icl->power)
643 ret = priv->info->link.power(&priv->client->dev, 0); 643 ret = icl->power(&client->dev, 0);
644 644
645 return ret; 645 return ret;
646} 646}
647 647
648static int ov772x_start_capture(struct soc_camera_device *icd) 648static int ov772x_start_capture(struct soc_camera_device *icd)
649{ 649{
650 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 650 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
651 struct ov772x_priv *priv = i2c_get_clientdata(client);
651 652
652 if (!priv->win || !priv->fmt) { 653 if (!priv->win || !priv->fmt) {
653 dev_err(&icd->dev, "norm or win select error\n"); 654 dev_err(&icd->dev, "norm or win select error\n");
654 return -EPERM; 655 return -EPERM;
655 } 656 }
656 657
657 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0); 658 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
658 659
659 dev_dbg(&icd->dev, 660 dev_dbg(&icd->dev,
660 "format %s, win %s\n", priv->fmt->name, priv->win->name); 661 "format %s, win %s\n", priv->fmt->name, priv->win->name);
661 662
662 return 0; 663 return 0;
663} 664}
664 665
665static int ov772x_stop_capture(struct soc_camera_device *icd) 666static int ov772x_stop_capture(struct soc_camera_device *icd)
666{ 667{
667 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 668 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
668 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE); 669 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
669 return 0; 670 return 0;
670} 671}
671 672
@@ -677,8 +678,9 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
677 678
678static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) 679static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
679{ 680{
680 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 681 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
681 struct soc_camera_link *icl = &priv->info->link; 682 struct ov772x_priv *priv = i2c_get_clientdata(client);
683 struct soc_camera_link *icl = to_soc_camera_link(icd);
682 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 684 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
683 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 685 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
684 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 686 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -689,7 +691,8 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
689static int ov772x_get_control(struct soc_camera_device *icd, 691static int ov772x_get_control(struct soc_camera_device *icd,
690 struct v4l2_control *ctrl) 692 struct v4l2_control *ctrl)
691{ 693{
692 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 694 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
695 struct ov772x_priv *priv = i2c_get_clientdata(client);
693 696
694 switch (ctrl->id) { 697 switch (ctrl->id) {
695 case V4L2_CID_VFLIP: 698 case V4L2_CID_VFLIP:
@@ -705,7 +708,8 @@ static int ov772x_get_control(struct soc_camera_device *icd,
705static int ov772x_set_control(struct soc_camera_device *icd, 708static int ov772x_set_control(struct soc_camera_device *icd,
706 struct v4l2_control *ctrl) 709 struct v4l2_control *ctrl)
707{ 710{
708 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 711 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
712 struct ov772x_priv *priv = i2c_get_clientdata(client);
709 int ret = 0; 713 int ret = 0;
710 u8 val; 714 u8 val;
711 715
@@ -715,14 +719,14 @@ static int ov772x_set_control(struct soc_camera_device *icd,
715 priv->flag_vflip = ctrl->value; 719 priv->flag_vflip = ctrl->value;
716 if (priv->info->flags & OV772X_FLAG_VFLIP) 720 if (priv->info->flags & OV772X_FLAG_VFLIP)
717 val ^= VFLIP_IMG; 721 val ^= VFLIP_IMG;
718 ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val); 722 ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val);
719 break; 723 break;
720 case V4L2_CID_HFLIP: 724 case V4L2_CID_HFLIP:
721 val = ctrl->value ? HFLIP_IMG : 0x00; 725 val = ctrl->value ? HFLIP_IMG : 0x00;
722 priv->flag_hflip = ctrl->value; 726 priv->flag_hflip = ctrl->value;
723 if (priv->info->flags & OV772X_FLAG_HFLIP) 727 if (priv->info->flags & OV772X_FLAG_HFLIP)
724 val ^= HFLIP_IMG; 728 val ^= HFLIP_IMG;
725 ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val); 729 ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
726 break; 730 break;
727 } 731 }
728 732
@@ -730,9 +734,10 @@ static int ov772x_set_control(struct soc_camera_device *icd,
730} 734}
731 735
732static int ov772x_get_chip_id(struct soc_camera_device *icd, 736static int ov772x_get_chip_id(struct soc_camera_device *icd,
733 struct v4l2_dbg_chip_ident *id) 737 struct v4l2_dbg_chip_ident *id)
734{ 738{
735 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 739 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
740 struct ov772x_priv *priv = i2c_get_clientdata(client);
736 741
737 id->ident = priv->model; 742 id->ident = priv->model;
738 id->revision = 0; 743 id->revision = 0;
@@ -744,14 +749,14 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd,
744static int ov772x_get_register(struct soc_camera_device *icd, 749static int ov772x_get_register(struct soc_camera_device *icd,
745 struct v4l2_dbg_register *reg) 750 struct v4l2_dbg_register *reg)
746{ 751{
747 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 752 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
748 int ret; 753 int ret;
749 754
750 reg->size = 1; 755 reg->size = 1;
751 if (reg->reg > 0xff) 756 if (reg->reg > 0xff)
752 return -EINVAL; 757 return -EINVAL;
753 758
754 ret = i2c_smbus_read_byte_data(priv->client, reg->reg); 759 ret = i2c_smbus_read_byte_data(client, reg->reg);
755 if (ret < 0) 760 if (ret < 0)
756 return ret; 761 return ret;
757 762
@@ -763,13 +768,13 @@ static int ov772x_get_register(struct soc_camera_device *icd,
763static int ov772x_set_register(struct soc_camera_device *icd, 768static int ov772x_set_register(struct soc_camera_device *icd,
764 struct v4l2_dbg_register *reg) 769 struct v4l2_dbg_register *reg)
765{ 770{
766 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 771 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
767 772
768 if (reg->reg > 0xff || 773 if (reg->reg > 0xff ||
769 reg->val > 0xff) 774 reg->val > 0xff)
770 return -EINVAL; 775 return -EINVAL;
771 776
772 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); 777 return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
773} 778}
774#endif 779#endif
775 780
@@ -793,9 +798,11 @@ ov772x_select_win(u32 width, u32 height)
793 return win; 798 return win;
794} 799}
795 800
796static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height, 801static int ov772x_set_params(struct soc_camera_device *icd,
797 u32 pixfmt) 802 u32 width, u32 height, u32 pixfmt)
798{ 803{
804 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
805 struct ov772x_priv *priv = i2c_get_clientdata(client);
799 int ret = -EINVAL; 806 int ret = -EINVAL;
800 u8 val; 807 u8 val;
801 int i; 808 int i;
@@ -810,6 +817,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
810 break; 817 break;
811 } 818 }
812 } 819 }
820 dev_dbg(&icd->dev, "Using fmt %x #%d\n", pixfmt, i);
813 if (!priv->fmt) 821 if (!priv->fmt)
814 goto ov772x_set_fmt_error; 822 goto ov772x_set_fmt_error;
815 823
@@ -821,7 +829,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
821 /* 829 /*
822 * reset hardware 830 * reset hardware
823 */ 831 */
824 ov772x_reset(priv->client); 832 ov772x_reset(client);
825 833
826 /* 834 /*
827 * Edge Ctrl 835 * Edge Ctrl
@@ -835,17 +843,17 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
835 * Remove it when manual mode. 843 * Remove it when manual mode.
836 */ 844 */
837 845
838 ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00); 846 ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
839 if (ret < 0) 847 if (ret < 0)
840 goto ov772x_set_fmt_error; 848 goto ov772x_set_fmt_error;
841 849
842 ret = ov772x_mask_set(priv->client, 850 ret = ov772x_mask_set(client,
843 EDGE_TRSHLD, EDGE_THRESHOLD_MASK, 851 EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
844 priv->info->edgectrl.threshold); 852 priv->info->edgectrl.threshold);
845 if (ret < 0) 853 if (ret < 0)
846 goto ov772x_set_fmt_error; 854 goto ov772x_set_fmt_error;
847 855
848 ret = ov772x_mask_set(priv->client, 856 ret = ov772x_mask_set(client,
849 EDGE_STRNGT, EDGE_STRENGTH_MASK, 857 EDGE_STRNGT, EDGE_STRENGTH_MASK,
850 priv->info->edgectrl.strength); 858 priv->info->edgectrl.strength);
851 if (ret < 0) 859 if (ret < 0)
@@ -857,13 +865,13 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
857 * 865 *
858 * set upper and lower limit 866 * set upper and lower limit
859 */ 867 */
860 ret = ov772x_mask_set(priv->client, 868 ret = ov772x_mask_set(client,
861 EDGE_UPPER, EDGE_UPPER_MASK, 869 EDGE_UPPER, EDGE_UPPER_MASK,
862 priv->info->edgectrl.upper); 870 priv->info->edgectrl.upper);
863 if (ret < 0) 871 if (ret < 0)
864 goto ov772x_set_fmt_error; 872 goto ov772x_set_fmt_error;
865 873
866 ret = ov772x_mask_set(priv->client, 874 ret = ov772x_mask_set(client,
867 EDGE_LOWER, EDGE_LOWER_MASK, 875 EDGE_LOWER, EDGE_LOWER_MASK,
868 priv->info->edgectrl.lower); 876 priv->info->edgectrl.lower);
869 if (ret < 0) 877 if (ret < 0)
@@ -873,7 +881,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
873 /* 881 /*
874 * set size format 882 * set size format
875 */ 883 */
876 ret = ov772x_write_array(priv->client, priv->win->regs); 884 ret = ov772x_write_array(client, priv->win->regs);
877 if (ret < 0) 885 if (ret < 0)
878 goto ov772x_set_fmt_error; 886 goto ov772x_set_fmt_error;
879 887
@@ -882,7 +890,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
882 */ 890 */
883 val = priv->fmt->dsp3; 891 val = priv->fmt->dsp3;
884 if (val) { 892 if (val) {
885 ret = ov772x_mask_set(priv->client, 893 ret = ov772x_mask_set(client,
886 DSP_CTRL3, UV_MASK, val); 894 DSP_CTRL3, UV_MASK, val);
887 if (ret < 0) 895 if (ret < 0)
888 goto ov772x_set_fmt_error; 896 goto ov772x_set_fmt_error;
@@ -901,7 +909,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
901 if (priv->flag_hflip) 909 if (priv->flag_hflip)
902 val ^= HFLIP_IMG; 910 val ^= HFLIP_IMG;
903 911
904 ret = ov772x_mask_set(priv->client, 912 ret = ov772x_mask_set(client,
905 COM3, SWAP_MASK | IMG_MASK, val); 913 COM3, SWAP_MASK | IMG_MASK, val);
906 if (ret < 0) 914 if (ret < 0)
907 goto ov772x_set_fmt_error; 915 goto ov772x_set_fmt_error;
@@ -910,7 +918,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
910 * set COM7 918 * set COM7
911 */ 919 */
912 val = priv->win->com7_bit | priv->fmt->com7; 920 val = priv->win->com7_bit | priv->fmt->com7;
913 ret = ov772x_mask_set(priv->client, 921 ret = ov772x_mask_set(client,
914 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), 922 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
915 val); 923 val);
916 if (ret < 0) 924 if (ret < 0)
@@ -920,7 +928,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
920 928
921ov772x_set_fmt_error: 929ov772x_set_fmt_error:
922 930
923 ov772x_reset(priv->client); 931 ov772x_reset(client);
924 priv->win = NULL; 932 priv->win = NULL;
925 priv->fmt = NULL; 933 priv->fmt = NULL;
926 934
@@ -930,22 +938,22 @@ ov772x_set_fmt_error:
930static int ov772x_set_crop(struct soc_camera_device *icd, 938static int ov772x_set_crop(struct soc_camera_device *icd,
931 struct v4l2_rect *rect) 939 struct v4l2_rect *rect)
932{ 940{
933 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 941 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
942 struct ov772x_priv *priv = i2c_get_clientdata(client);
934 943
935 if (!priv->fmt) 944 if (!priv->fmt)
936 return -EINVAL; 945 return -EINVAL;
937 946
938 return ov772x_set_params(priv, rect->width, rect->height, 947 return ov772x_set_params(icd, rect->width, rect->height,
939 priv->fmt->fourcc); 948 priv->fmt->fourcc);
940} 949}
941 950
942static int ov772x_set_fmt(struct soc_camera_device *icd, 951static int ov772x_set_fmt(struct soc_camera_device *icd,
943 struct v4l2_format *f) 952 struct v4l2_format *f)
944{ 953{
945 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
946 struct v4l2_pix_format *pix = &f->fmt.pix; 954 struct v4l2_pix_format *pix = &f->fmt.pix;
947 955
948 return ov772x_set_params(priv, pix->width, pix->height, 956 return ov772x_set_params(icd, pix->width, pix->height,
949 pix->pixelformat); 957 pix->pixelformat);
950} 958}
951 959
@@ -967,11 +975,13 @@ static int ov772x_try_fmt(struct soc_camera_device *icd,
967 return 0; 975 return 0;
968} 976}
969 977
970static int ov772x_video_probe(struct soc_camera_device *icd) 978static int ov772x_video_probe(struct soc_camera_device *icd,
979 struct i2c_client *client)
971{ 980{
972 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 981 struct ov772x_priv *priv = i2c_get_clientdata(client);
973 u8 pid, ver; 982 u8 pid, ver;
974 const char *devname; 983 const char *devname;
984 int ret;
975 985
976 /* 986 /*
977 * We must have a parent by now. And it cannot be a wrong one. 987 * We must have a parent by now. And it cannot be a wrong one.
@@ -993,11 +1003,16 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
993 icd->formats = ov772x_fmt_lists; 1003 icd->formats = ov772x_fmt_lists;
994 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); 1004 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
995 1005
1006 /* Switch master clock on */
1007 ret = soc_camera_video_start(icd, &client->dev);
1008 if (ret)
1009 return ret;
1010
996 /* 1011 /*
997 * check and show product ID and manufacturer ID 1012 * check and show product ID and manufacturer ID
998 */ 1013 */
999 pid = i2c_smbus_read_byte_data(priv->client, PID); 1014 pid = i2c_smbus_read_byte_data(client, PID);
1000 ver = i2c_smbus_read_byte_data(priv->client, VER); 1015 ver = i2c_smbus_read_byte_data(client, VER);
1001 1016
1002 switch (VERSION(pid, ver)) { 1017 switch (VERSION(pid, ver)) {
1003 case OV7720: 1018 case OV7720:
@@ -1011,7 +1026,8 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
1011 default: 1026 default:
1012 dev_err(&icd->dev, 1027 dev_err(&icd->dev,
1013 "Product ID error %x:%x\n", pid, ver); 1028 "Product ID error %x:%x\n", pid, ver);
1014 return -ENODEV; 1029 ret = -ENODEV;
1030 goto ever;
1015 } 1031 }
1016 1032
1017 dev_info(&icd->dev, 1033 dev_info(&icd->dev,
@@ -1019,21 +1035,17 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
1019 devname, 1035 devname,
1020 pid, 1036 pid,
1021 ver, 1037 ver,
1022 i2c_smbus_read_byte_data(priv->client, MIDH), 1038 i2c_smbus_read_byte_data(client, MIDH),
1023 i2c_smbus_read_byte_data(priv->client, MIDL)); 1039 i2c_smbus_read_byte_data(client, MIDL));
1024
1025 return soc_camera_video_start(icd);
1026}
1027 1040
1028static void ov772x_video_remove(struct soc_camera_device *icd)
1029{
1030 soc_camera_video_stop(icd); 1041 soc_camera_video_stop(icd);
1042
1043ever:
1044 return ret;
1031} 1045}
1032 1046
1033static struct soc_camera_ops ov772x_ops = { 1047static struct soc_camera_ops ov772x_ops = {
1034 .owner = THIS_MODULE, 1048 .owner = THIS_MODULE,
1035 .probe = ov772x_video_probe,
1036 .remove = ov772x_video_remove,
1037 .init = ov772x_init, 1049 .init = ov772x_init,
1038 .release = ov772x_release, 1050 .release = ov772x_release,
1039 .start_capture = ov772x_start_capture, 1051 .start_capture = ov772x_start_capture,
@@ -1059,19 +1071,25 @@ static struct soc_camera_ops ov772x_ops = {
1059 */ 1071 */
1060 1072
1061static int ov772x_probe(struct i2c_client *client, 1073static int ov772x_probe(struct i2c_client *client,
1062 const struct i2c_device_id *did) 1074 const struct i2c_device_id *did)
1063{ 1075{
1064 struct ov772x_priv *priv; 1076 struct ov772x_priv *priv;
1065 struct ov772x_camera_info *info; 1077 struct ov772x_camera_info *info;
1066 struct soc_camera_device *icd; 1078 struct soc_camera_device *icd = client->dev.platform_data;
1067 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1079 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1080 struct soc_camera_link *icl;
1068 int ret; 1081 int ret;
1069 1082
1070 if (!client->dev.platform_data) 1083 if (!icd) {
1084 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
1071 return -EINVAL; 1085 return -EINVAL;
1086 }
1072 1087
1073 info = container_of(client->dev.platform_data, 1088 icl = to_soc_camera_link(icd);
1074 struct ov772x_camera_info, link); 1089 if (!icl)
1090 return -EINVAL;
1091
1092 info = container_of(icl, struct ov772x_camera_info, link);
1075 1093
1076 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1094 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1077 dev_err(&adapter->dev, 1095 dev_err(&adapter->dev,
@@ -1085,19 +1103,15 @@ static int ov772x_probe(struct i2c_client *client,
1085 return -ENOMEM; 1103 return -ENOMEM;
1086 1104
1087 priv->info = info; 1105 priv->info = info;
1088 priv->client = client;
1089 i2c_set_clientdata(client, priv); 1106 i2c_set_clientdata(client, priv);
1090 1107
1091 icd = &priv->icd;
1092 icd->ops = &ov772x_ops; 1108 icd->ops = &ov772x_ops;
1093 icd->control = &client->dev;
1094 icd->width_max = MAX_WIDTH; 1109 icd->width_max = MAX_WIDTH;
1095 icd->height_max = MAX_HEIGHT; 1110 icd->height_max = MAX_HEIGHT;
1096 icd->iface = priv->info->link.bus_id;
1097
1098 ret = soc_camera_device_register(icd);
1099 1111
1112 ret = ov772x_video_probe(icd, client);
1100 if (ret) { 1113 if (ret) {
1114 icd->ops = NULL;
1101 i2c_set_clientdata(client, NULL); 1115 i2c_set_clientdata(client, NULL);
1102 kfree(priv); 1116 kfree(priv);
1103 } 1117 }
@@ -1108,8 +1122,9 @@ static int ov772x_probe(struct i2c_client *client,
1108static int ov772x_remove(struct i2c_client *client) 1122static int ov772x_remove(struct i2c_client *client)
1109{ 1123{
1110 struct ov772x_priv *priv = i2c_get_clientdata(client); 1124 struct ov772x_priv *priv = i2c_get_clientdata(client);
1125 struct soc_camera_device *icd = client->dev.platform_data;
1111 1126
1112 soc_camera_device_unregister(&priv->icd); 1127 icd->ops = NULL;
1113 i2c_set_clientdata(client, NULL); 1128 i2c_set_clientdata(client, NULL);
1114 kfree(priv); 1129 kfree(priv);
1115 return 0; 1130 return 0;