aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ov772x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ov772x.c')
-rw-r--r--drivers/media/video/ov772x.c169
1 files changed, 68 insertions, 101 deletions
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 3ea650d55b17..119159773a68 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -22,7 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/videodev2.h> 23#include <linux/videodev2.h>
24#include <media/v4l2-chip-ident.h> 24#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-common.h> 25#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h> 26#include <media/soc_camera.h>
27#include <media/ov772x.h> 27#include <media/ov772x.h>
28 28
@@ -398,6 +398,7 @@ struct ov772x_win_size {
398}; 398};
399 399
400struct ov772x_priv { 400struct ov772x_priv {
401 struct v4l2_subdev subdev;
401 struct ov772x_camera_info *info; 402 struct ov772x_camera_info *info;
402 const struct ov772x_color_format *fmt; 403 const struct ov772x_color_format *fmt;
403 const struct ov772x_win_size *win; 404 const struct ov772x_win_size *win;
@@ -575,6 +576,11 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
575 * general function 576 * general function
576 */ 577 */
577 578
579static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
580{
581 return container_of(i2c_get_clientdata(client), struct ov772x_priv, subdev);
582}
583
578static int ov772x_write_array(struct i2c_client *client, 584static int ov772x_write_array(struct i2c_client *client,
579 const struct regval_list *vals) 585 const struct regval_list *vals)
580{ 586{
@@ -615,61 +621,29 @@ static int ov772x_reset(struct i2c_client *client)
615 * soc_camera_ops function 621 * soc_camera_ops function
616 */ 622 */
617 623
618static int ov772x_init(struct soc_camera_device *icd) 624static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
619{ 625{
620 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 626 struct i2c_client *client = sd->priv;
621 struct soc_camera_link *icl = to_soc_camera_link(icd); 627 struct ov772x_priv *priv = to_ov772x(client);
622 int ret = 0;
623 628
624 if (icl->power) { 629 if (!enable) {
625 ret = icl->power(&client->dev, 1); 630 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
626 if (ret < 0) 631 return 0;
627 return ret;
628 } 632 }
629 633
630 if (icl->reset)
631 ret = icl->reset(&client->dev);
632
633 return ret;
634}
635
636static int ov772x_release(struct soc_camera_device *icd)
637{
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;
641
642 if (icl->power)
643 ret = icl->power(&client->dev, 0);
644
645 return ret;
646}
647
648static int ov772x_start_capture(struct soc_camera_device *icd)
649{
650 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
651 struct ov772x_priv *priv = i2c_get_clientdata(client);
652
653 if (!priv->win || !priv->fmt) { 634 if (!priv->win || !priv->fmt) {
654 dev_err(&icd->dev, "norm or win select error\n"); 635 dev_err(&client->dev, "norm or win select error\n");
655 return -EPERM; 636 return -EPERM;
656 } 637 }
657 638
658 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0); 639 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
659 640
660 dev_dbg(&icd->dev, 641 dev_dbg(&client->dev,
661 "format %s, win %s\n", priv->fmt->name, priv->win->name); 642 "format %s, win %s\n", priv->fmt->name, priv->win->name);
662 643
663 return 0; 644 return 0;
664} 645}
665 646
666static int ov772x_stop_capture(struct soc_camera_device *icd)
667{
668 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
669 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
670 return 0;
671}
672
673static int ov772x_set_bus_param(struct soc_camera_device *icd, 647static int ov772x_set_bus_param(struct soc_camera_device *icd,
674 unsigned long flags) 648 unsigned long flags)
675{ 649{
@@ -688,11 +662,10 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
688 return soc_camera_apply_sensor_flags(icl, flags); 662 return soc_camera_apply_sensor_flags(icl, flags);
689} 663}
690 664
691static int ov772x_get_control(struct soc_camera_device *icd, 665static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
692 struct v4l2_control *ctrl)
693{ 666{
694 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 667 struct i2c_client *client = sd->priv;
695 struct ov772x_priv *priv = i2c_get_clientdata(client); 668 struct ov772x_priv *priv = to_ov772x(client);
696 669
697 switch (ctrl->id) { 670 switch (ctrl->id) {
698 case V4L2_CID_VFLIP: 671 case V4L2_CID_VFLIP:
@@ -705,11 +678,10 @@ static int ov772x_get_control(struct soc_camera_device *icd,
705 return 0; 678 return 0;
706} 679}
707 680
708static int ov772x_set_control(struct soc_camera_device *icd, 681static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
709 struct v4l2_control *ctrl)
710{ 682{
711 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 683 struct i2c_client *client = sd->priv;
712 struct ov772x_priv *priv = i2c_get_clientdata(client); 684 struct ov772x_priv *priv = to_ov772x(client);
713 int ret = 0; 685 int ret = 0;
714 u8 val; 686 u8 val;
715 687
@@ -733,11 +705,11 @@ static int ov772x_set_control(struct soc_camera_device *icd,
733 return ret; 705 return ret;
734} 706}
735 707
736static int ov772x_get_chip_id(struct soc_camera_device *icd, 708static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
737 struct v4l2_dbg_chip_ident *id) 709 struct v4l2_dbg_chip_ident *id)
738{ 710{
739 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 711 struct i2c_client *client = sd->priv;
740 struct ov772x_priv *priv = i2c_get_clientdata(client); 712 struct ov772x_priv *priv = to_ov772x(client);
741 713
742 id->ident = priv->model; 714 id->ident = priv->model;
743 id->revision = 0; 715 id->revision = 0;
@@ -746,10 +718,10 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd,
746} 718}
747 719
748#ifdef CONFIG_VIDEO_ADV_DEBUG 720#ifdef CONFIG_VIDEO_ADV_DEBUG
749static int ov772x_get_register(struct soc_camera_device *icd, 721static int ov772x_g_register(struct v4l2_subdev *sd,
750 struct v4l2_dbg_register *reg) 722 struct v4l2_dbg_register *reg)
751{ 723{
752 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 724 struct i2c_client *client = sd->priv;
753 int ret; 725 int ret;
754 726
755 reg->size = 1; 727 reg->size = 1;
@@ -765,10 +737,10 @@ static int ov772x_get_register(struct soc_camera_device *icd,
765 return 0; 737 return 0;
766} 738}
767 739
768static int ov772x_set_register(struct soc_camera_device *icd, 740static int ov772x_s_register(struct v4l2_subdev *sd,
769 struct v4l2_dbg_register *reg) 741 struct v4l2_dbg_register *reg)
770{ 742{
771 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 743 struct i2c_client *client = sd->priv;
772 744
773 if (reg->reg > 0xff || 745 if (reg->reg > 0xff ||
774 reg->val > 0xff) 746 reg->val > 0xff)
@@ -778,8 +750,7 @@ static int ov772x_set_register(struct soc_camera_device *icd,
778} 750}
779#endif 751#endif
780 752
781static const struct ov772x_win_size* 753static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
782ov772x_select_win(u32 width, u32 height)
783{ 754{
784 __u32 diff; 755 __u32 diff;
785 const struct ov772x_win_size *win; 756 const struct ov772x_win_size *win;
@@ -798,11 +769,10 @@ ov772x_select_win(u32 width, u32 height)
798 return win; 769 return win;
799} 770}
800 771
801static int ov772x_set_params(struct soc_camera_device *icd, 772static int ov772x_set_params(struct i2c_client *client,
802 u32 width, u32 height, u32 pixfmt) 773 u32 width, u32 height, u32 pixfmt)
803{ 774{
804 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 775 struct ov772x_priv *priv = to_ov772x(client);
805 struct ov772x_priv *priv = i2c_get_clientdata(client);
806 int ret = -EINVAL; 776 int ret = -EINVAL;
807 u8 val; 777 u8 val;
808 int i; 778 int i;
@@ -817,7 +787,6 @@ static int ov772x_set_params(struct soc_camera_device *icd,
817 break; 787 break;
818 } 788 }
819 } 789 }
820 dev_dbg(&icd->dev, "Using fmt %x #%d\n", pixfmt, i);
821 if (!priv->fmt) 790 if (!priv->fmt)
822 goto ov772x_set_fmt_error; 791 goto ov772x_set_fmt_error;
823 792
@@ -939,26 +908,26 @@ static int ov772x_set_crop(struct soc_camera_device *icd,
939 struct v4l2_rect *rect) 908 struct v4l2_rect *rect)
940{ 909{
941 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 910 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
942 struct ov772x_priv *priv = i2c_get_clientdata(client); 911 struct ov772x_priv *priv = to_ov772x(client);
943 912
944 if (!priv->fmt) 913 if (!priv->fmt)
945 return -EINVAL; 914 return -EINVAL;
946 915
947 return ov772x_set_params(icd, rect->width, rect->height, 916 return ov772x_set_params(client, rect->width, rect->height,
948 priv->fmt->fourcc); 917 priv->fmt->fourcc);
949} 918}
950 919
951static int ov772x_set_fmt(struct soc_camera_device *icd, 920static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
952 struct v4l2_format *f)
953{ 921{
922 struct i2c_client *client = sd->priv;
954 struct v4l2_pix_format *pix = &f->fmt.pix; 923 struct v4l2_pix_format *pix = &f->fmt.pix;
955 924
956 return ov772x_set_params(icd, pix->width, pix->height, 925 return ov772x_set_params(client, pix->width, pix->height,
957 pix->pixelformat); 926 pix->pixelformat);
958} 927}
959 928
960static int ov772x_try_fmt(struct soc_camera_device *icd, 929static int ov772x_try_fmt(struct v4l2_subdev *sd,
961 struct v4l2_format *f) 930 struct v4l2_format *f)
962{ 931{
963 struct v4l2_pix_format *pix = &f->fmt.pix; 932 struct v4l2_pix_format *pix = &f->fmt.pix;
964 const struct ov772x_win_size *win; 933 const struct ov772x_win_size *win;
@@ -978,10 +947,9 @@ static int ov772x_try_fmt(struct soc_camera_device *icd,
978static int ov772x_video_probe(struct soc_camera_device *icd, 947static int ov772x_video_probe(struct soc_camera_device *icd,
979 struct i2c_client *client) 948 struct i2c_client *client)
980{ 949{
981 struct ov772x_priv *priv = i2c_get_clientdata(client); 950 struct ov772x_priv *priv = to_ov772x(client);
982 u8 pid, ver; 951 u8 pid, ver;
983 const char *devname; 952 const char *devname;
984 int ret;
985 953
986 /* 954 /*
987 * We must have a parent by now. And it cannot be a wrong one. 955 * We must have a parent by now. And it cannot be a wrong one.
@@ -1003,11 +971,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1003 icd->formats = ov772x_fmt_lists; 971 icd->formats = ov772x_fmt_lists;
1004 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists); 972 icd->num_formats = ARRAY_SIZE(ov772x_fmt_lists);
1005 973
1006 /* Switch master clock on */
1007 ret = soc_camera_video_start(icd, &client->dev);
1008 if (ret)
1009 return ret;
1010
1011 /* 974 /*
1012 * check and show product ID and manufacturer ID 975 * check and show product ID and manufacturer ID
1013 */ 976 */
@@ -1026,8 +989,7 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1026 default: 989 default:
1027 dev_err(&icd->dev, 990 dev_err(&icd->dev,
1028 "Product ID error %x:%x\n", pid, ver); 991 "Product ID error %x:%x\n", pid, ver);
1029 ret = -ENODEV; 992 return -ENODEV;
1030 goto ever;
1031 } 993 }
1032 994
1033 dev_info(&icd->dev, 995 dev_info(&icd->dev,
@@ -1038,34 +1000,38 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1038 i2c_smbus_read_byte_data(client, MIDH), 1000 i2c_smbus_read_byte_data(client, MIDH),
1039 i2c_smbus_read_byte_data(client, MIDL)); 1001 i2c_smbus_read_byte_data(client, MIDL));
1040 1002
1041 soc_camera_video_stop(icd); 1003 return 0;
1042
1043ever:
1044 return ret;
1045} 1004}
1046 1005
1047static struct soc_camera_ops ov772x_ops = { 1006static struct soc_camera_ops ov772x_ops = {
1048 .owner = THIS_MODULE,
1049 .init = ov772x_init,
1050 .release = ov772x_release,
1051 .start_capture = ov772x_start_capture,
1052 .stop_capture = ov772x_stop_capture,
1053 .set_crop = ov772x_set_crop, 1007 .set_crop = ov772x_set_crop,
1054 .set_fmt = ov772x_set_fmt,
1055 .try_fmt = ov772x_try_fmt,
1056 .set_bus_param = ov772x_set_bus_param, 1008 .set_bus_param = ov772x_set_bus_param,
1057 .query_bus_param = ov772x_query_bus_param, 1009 .query_bus_param = ov772x_query_bus_param,
1058 .controls = ov772x_controls, 1010 .controls = ov772x_controls,
1059 .num_controls = ARRAY_SIZE(ov772x_controls), 1011 .num_controls = ARRAY_SIZE(ov772x_controls),
1060 .get_control = ov772x_get_control, 1012};
1061 .set_control = ov772x_set_control, 1013
1062 .get_chip_id = ov772x_get_chip_id, 1014static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1015 .g_ctrl = ov772x_g_ctrl,
1016 .s_ctrl = ov772x_s_ctrl,
1017 .g_chip_ident = ov772x_g_chip_ident,
1063#ifdef CONFIG_VIDEO_ADV_DEBUG 1018#ifdef CONFIG_VIDEO_ADV_DEBUG
1064 .get_register = ov772x_get_register, 1019 .g_register = ov772x_g_register,
1065 .set_register = ov772x_set_register, 1020 .s_register = ov772x_s_register,
1066#endif 1021#endif
1067}; 1022};
1068 1023
1024static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1025 .s_stream = ov772x_s_stream,
1026 .s_fmt = ov772x_s_fmt,
1027 .try_fmt = ov772x_try_fmt,
1028};
1029
1030static struct v4l2_subdev_ops ov772x_subdev_ops = {
1031 .core = &ov772x_subdev_core_ops,
1032 .video = &ov772x_subdev_video_ops,
1033};
1034
1069/* 1035/*
1070 * i2c_driver function 1036 * i2c_driver function
1071 */ 1037 */
@@ -1081,7 +1047,7 @@ static int ov772x_probe(struct i2c_client *client,
1081 int ret; 1047 int ret;
1082 1048
1083 if (!icd) { 1049 if (!icd) {
1084 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n"); 1050 dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
1085 return -EINVAL; 1051 return -EINVAL;
1086 } 1052 }
1087 1053
@@ -1102,8 +1068,9 @@ static int ov772x_probe(struct i2c_client *client,
1102 if (!priv) 1068 if (!priv)
1103 return -ENOMEM; 1069 return -ENOMEM;
1104 1070
1105 priv->info = info; 1071 priv->info = info;
1106 i2c_set_clientdata(client, priv); 1072
1073 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1107 1074
1108 icd->ops = &ov772x_ops; 1075 icd->ops = &ov772x_ops;
1109 icd->width_max = MAX_WIDTH; 1076 icd->width_max = MAX_WIDTH;
@@ -1121,7 +1088,7 @@ static int ov772x_probe(struct i2c_client *client,
1121 1088
1122static int ov772x_remove(struct i2c_client *client) 1089static int ov772x_remove(struct i2c_client *client)
1123{ 1090{
1124 struct ov772x_priv *priv = i2c_get_clientdata(client); 1091 struct ov772x_priv *priv = to_ov772x(client);
1125 struct soc_camera_device *icd = client->dev.platform_data; 1092 struct soc_camera_device *icd = client->dev.platform_data;
1126 1093
1127 icd->ops = NULL; 1094 icd->ops = NULL;