diff options
| author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2011-07-27 15:00:29 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 16:27:46 -0400 |
| commit | 579cea034237dcfdcac071faa3e00b4528ddf8ec (patch) | |
| tree | ec0458c6468da92eadc0a9fdd4099ef8fb240ee0 | |
| parent | 97a0a611e8dfa8f8f7c7b1c49239b0ab44cc3710 (diff) | |
[media] V4L: mx3_camera: convert to the new mbus-config subdev operations
Switch from soc-camera specific .{query,set}_bus_param() to V4L2
subdevice .[gs]_mbus_config() operations.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/video/mx3_camera.c | 197 |
1 files changed, 89 insertions, 108 deletions
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index c8e958a07e91..f4ef6b993ff1 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
| @@ -109,6 +109,7 @@ struct mx3_camera_dev { | |||
| 109 | 109 | ||
| 110 | unsigned long platform_flags; | 110 | unsigned long platform_flags; |
| 111 | unsigned long mclk; | 111 | unsigned long mclk; |
| 112 | u16 width_flags; /* max 15 bits */ | ||
| 112 | 113 | ||
| 113 | struct list_head capture; | 114 | struct list_head capture; |
| 114 | spinlock_t lock; /* Protects video buffer lists */ | 115 | spinlock_t lock; /* Protects video buffer lists */ |
| @@ -548,58 +549,27 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, | |||
| 548 | unsigned char buswidth, unsigned long *flags) | 549 | unsigned char buswidth, unsigned long *flags) |
| 549 | { | 550 | { |
| 550 | /* | 551 | /* |
| 552 | * If requested data width is supported by the platform, use it or any | ||
| 553 | * possible lower value - i.MX31 is smart enough to shift bits | ||
| 554 | */ | ||
| 555 | if (buswidth > fls(mx3_cam->width_flags)) | ||
| 556 | return -EINVAL; | ||
| 557 | |||
| 558 | /* | ||
| 551 | * Platform specified synchronization and pixel clock polarities are | 559 | * Platform specified synchronization and pixel clock polarities are |
| 552 | * only a recommendation and are only used during probing. MX3x | 560 | * only a recommendation and are only used during probing. MX3x |
| 553 | * camera interface only works in master mode, i.e., uses HSYNC and | 561 | * camera interface only works in master mode, i.e., uses HSYNC and |
| 554 | * VSYNC signals from the sensor | 562 | * VSYNC signals from the sensor |
| 555 | */ | 563 | */ |
| 556 | *flags = SOCAM_MASTER | | 564 | *flags = V4L2_MBUS_MASTER | |
| 557 | SOCAM_HSYNC_ACTIVE_HIGH | | 565 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | |
| 558 | SOCAM_HSYNC_ACTIVE_LOW | | 566 | V4L2_MBUS_HSYNC_ACTIVE_LOW | |
| 559 | SOCAM_VSYNC_ACTIVE_HIGH | | 567 | V4L2_MBUS_VSYNC_ACTIVE_HIGH | |
| 560 | SOCAM_VSYNC_ACTIVE_LOW | | 568 | V4L2_MBUS_VSYNC_ACTIVE_LOW | |
| 561 | SOCAM_PCLK_SAMPLE_RISING | | 569 | V4L2_MBUS_PCLK_SAMPLE_RISING | |
| 562 | SOCAM_PCLK_SAMPLE_FALLING | | 570 | V4L2_MBUS_PCLK_SAMPLE_FALLING | |
| 563 | SOCAM_DATA_ACTIVE_HIGH | | 571 | V4L2_MBUS_DATA_ACTIVE_HIGH | |
| 564 | SOCAM_DATA_ACTIVE_LOW; | 572 | V4L2_MBUS_DATA_ACTIVE_LOW; |
| 565 | |||
| 566 | /* | ||
| 567 | * If requested data width is supported by the platform, use it or any | ||
| 568 | * possible lower value - i.MX31 is smart enough to schift bits | ||
| 569 | */ | ||
| 570 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) | ||
| 571 | *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | | ||
| 572 | SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
| 573 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) | ||
| 574 | *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | | ||
| 575 | SOCAM_DATAWIDTH_4; | ||
| 576 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) | ||
| 577 | *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; | ||
| 578 | else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4) | ||
| 579 | *flags |= SOCAM_DATAWIDTH_4; | ||
| 580 | |||
| 581 | switch (buswidth) { | ||
| 582 | case 15: | ||
| 583 | if (!(*flags & SOCAM_DATAWIDTH_15)) | ||
| 584 | return -EINVAL; | ||
| 585 | break; | ||
| 586 | case 10: | ||
| 587 | if (!(*flags & SOCAM_DATAWIDTH_10)) | ||
| 588 | return -EINVAL; | ||
| 589 | break; | ||
| 590 | case 8: | ||
| 591 | if (!(*flags & SOCAM_DATAWIDTH_8)) | ||
| 592 | return -EINVAL; | ||
| 593 | break; | ||
| 594 | case 4: | ||
| 595 | if (!(*flags & SOCAM_DATAWIDTH_4)) | ||
| 596 | return -EINVAL; | ||
| 597 | break; | ||
| 598 | default: | ||
| 599 | dev_warn(mx3_cam->soc_host.v4l2_dev.dev, | ||
| 600 | "Unsupported bus width %d\n", buswidth); | ||
| 601 | return -EINVAL; | ||
| 602 | } | ||
| 603 | 573 | ||
| 604 | return 0; | 574 | return 0; |
| 605 | } | 575 | } |
| @@ -607,9 +577,11 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam, | |||
| 607 | static int mx3_camera_try_bus_param(struct soc_camera_device *icd, | 577 | static int mx3_camera_try_bus_param(struct soc_camera_device *icd, |
| 608 | const unsigned int depth) | 578 | const unsigned int depth) |
| 609 | { | 579 | { |
| 580 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
| 610 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 581 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| 611 | struct mx3_camera_dev *mx3_cam = ici->priv; | 582 | struct mx3_camera_dev *mx3_cam = ici->priv; |
| 612 | unsigned long bus_flags, camera_flags; | 583 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
| 584 | unsigned long bus_flags, common_flags; | ||
| 613 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); | 585 | int ret = test_platform_param(mx3_cam, depth, &bus_flags); |
| 614 | 586 | ||
| 615 | dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret); | 587 | dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret); |
| @@ -617,15 +589,21 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd, | |||
| 617 | if (ret < 0) | 589 | if (ret < 0) |
| 618 | return ret; | 590 | return ret; |
| 619 | 591 | ||
| 620 | camera_flags = icd->ops->query_bus_param(icd); | 592 | ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); |
| 621 | 593 | if (!ret) { | |
| 622 | ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); | 594 | common_flags = soc_mbus_config_compatible(&cfg, |
| 623 | if (ret < 0) | 595 | bus_flags); |
| 624 | dev_warn(icd->parent, | 596 | if (!common_flags) { |
| 625 | "Flags incompatible: camera %lx, host %lx\n", | 597 | dev_warn(icd->parent, |
| 626 | camera_flags, bus_flags); | 598 | "Flags incompatible: camera 0x%x, host 0x%lx\n", |
| 599 | cfg.flags, bus_flags); | ||
| 600 | return -EINVAL; | ||
| 601 | } | ||
| 602 | } else if (ret != -ENOIOCTLCMD) { | ||
| 603 | return ret; | ||
| 604 | } | ||
| 627 | 605 | ||
| 628 | return ret; | 606 | return 0; |
| 629 | } | 607 | } |
| 630 | 608 | ||
| 631 | static bool chan_filter(struct dma_chan *chan, void *arg) | 609 | static bool chan_filter(struct dma_chan *chan, void *arg) |
| @@ -994,9 +972,11 @@ static int mx3_camera_querycap(struct soc_camera_host *ici, | |||
| 994 | 972 | ||
| 995 | static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | 973 | static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) |
| 996 | { | 974 | { |
| 975 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | ||
| 997 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 976 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| 998 | struct mx3_camera_dev *mx3_cam = ici->priv; | 977 | struct mx3_camera_dev *mx3_cam = ici->priv; |
| 999 | unsigned long bus_flags, camera_flags, common_flags; | 978 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
| 979 | unsigned long bus_flags, common_flags; | ||
| 1000 | u32 dw, sens_conf; | 980 | u32 dw, sens_conf; |
| 1001 | const struct soc_mbus_pixelfmt *fmt; | 981 | const struct soc_mbus_pixelfmt *fmt; |
| 1002 | int buswidth; | 982 | int buswidth; |
| @@ -1008,83 +988,76 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
| 1008 | if (!fmt) | 988 | if (!fmt) |
| 1009 | return -EINVAL; | 989 | return -EINVAL; |
| 1010 | 990 | ||
| 1011 | buswidth = fmt->bits_per_sample; | ||
| 1012 | ret = test_platform_param(mx3_cam, buswidth, &bus_flags); | ||
| 1013 | |||
| 1014 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); | 991 | xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); |
| 1015 | if (!xlate) { | 992 | if (!xlate) { |
| 1016 | dev_warn(dev, "Format %x not found\n", pixfmt); | 993 | dev_warn(dev, "Format %x not found\n", pixfmt); |
| 1017 | return -EINVAL; | 994 | return -EINVAL; |
| 1018 | } | 995 | } |
| 1019 | 996 | ||
| 997 | buswidth = fmt->bits_per_sample; | ||
| 998 | ret = test_platform_param(mx3_cam, buswidth, &bus_flags); | ||
| 999 | |||
| 1020 | dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); | 1000 | dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); |
| 1021 | 1001 | ||
| 1022 | if (ret < 0) | 1002 | if (ret < 0) |
| 1023 | return ret; | 1003 | return ret; |
| 1024 | 1004 | ||
| 1025 | camera_flags = icd->ops->query_bus_param(icd); | 1005 | ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); |
| 1026 | 1006 | if (!ret) { | |
| 1027 | common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); | 1007 | common_flags = soc_mbus_config_compatible(&cfg, |
| 1028 | dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n", | 1008 | bus_flags); |
| 1029 | camera_flags, bus_flags, common_flags); | 1009 | if (!common_flags) { |
| 1030 | if (!common_flags) { | 1010 | dev_warn(icd->parent, |
| 1031 | dev_dbg(dev, "no common flags"); | 1011 | "Flags incompatible: camera 0x%x, host 0x%lx\n", |
| 1032 | return -EINVAL; | 1012 | cfg.flags, bus_flags); |
| 1013 | return -EINVAL; | ||
| 1014 | } | ||
| 1015 | } else if (ret != -ENOIOCTLCMD) { | ||
| 1016 | return ret; | ||
| 1017 | } else { | ||
| 1018 | common_flags = bus_flags; | ||
| 1033 | } | 1019 | } |
| 1034 | 1020 | ||
| 1021 | dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n", | ||
| 1022 | cfg.flags, bus_flags, common_flags); | ||
| 1023 | |||
| 1035 | /* Make choices, based on platform preferences */ | 1024 | /* Make choices, based on platform preferences */ |
| 1036 | if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && | 1025 | if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && |
| 1037 | (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { | 1026 | (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { |
| 1038 | if (mx3_cam->platform_flags & MX3_CAMERA_HSP) | 1027 | if (mx3_cam->platform_flags & MX3_CAMERA_HSP) |
| 1039 | common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; | 1028 | common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; |
| 1040 | else | 1029 | else |
| 1041 | common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; | 1030 | common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; |
| 1042 | } | 1031 | } |
| 1043 | 1032 | ||
| 1044 | if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && | 1033 | if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && |
| 1045 | (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { | 1034 | (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { |
| 1046 | if (mx3_cam->platform_flags & MX3_CAMERA_VSP) | 1035 | if (mx3_cam->platform_flags & MX3_CAMERA_VSP) |
| 1047 | common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; | 1036 | common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; |
| 1048 | else | 1037 | else |
| 1049 | common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; | 1038 | common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; |
| 1050 | } | 1039 | } |
| 1051 | 1040 | ||
| 1052 | if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && | 1041 | if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) && |
| 1053 | (common_flags & SOCAM_DATA_ACTIVE_LOW)) { | 1042 | (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) { |
| 1054 | if (mx3_cam->platform_flags & MX3_CAMERA_DP) | 1043 | if (mx3_cam->platform_flags & MX3_CAMERA_DP) |
| 1055 | common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; | 1044 | common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH; |
| 1056 | else | 1045 | else |
| 1057 | common_flags &= ~SOCAM_DATA_ACTIVE_LOW; | 1046 | common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW; |
| 1058 | } | 1047 | } |
| 1059 | 1048 | ||
| 1060 | if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && | 1049 | if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && |
| 1061 | (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { | 1050 | (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { |
| 1062 | if (mx3_cam->platform_flags & MX3_CAMERA_PCP) | 1051 | if (mx3_cam->platform_flags & MX3_CAMERA_PCP) |
| 1063 | common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; | 1052 | common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; |
| 1064 | else | 1053 | else |
| 1065 | common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; | 1054 | common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; |
| 1066 | } | 1055 | } |
| 1067 | 1056 | ||
| 1068 | /* | 1057 | cfg.flags = common_flags; |
| 1069 | * Make the camera work in widest common mode, we'll take care of | 1058 | ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); |
| 1070 | * the rest | 1059 | if (ret < 0 && ret != -ENOIOCTLCMD) { |
| 1071 | */ | 1060 | dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n", |
| 1072 | if (common_flags & SOCAM_DATAWIDTH_15) | ||
| 1073 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | | ||
| 1074 | SOCAM_DATAWIDTH_15; | ||
| 1075 | else if (common_flags & SOCAM_DATAWIDTH_10) | ||
| 1076 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | | ||
| 1077 | SOCAM_DATAWIDTH_10; | ||
| 1078 | else if (common_flags & SOCAM_DATAWIDTH_8) | ||
| 1079 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | | ||
| 1080 | SOCAM_DATAWIDTH_8; | ||
| 1081 | else | ||
| 1082 | common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | | ||
| 1083 | SOCAM_DATAWIDTH_4; | ||
| 1084 | |||
| 1085 | ret = icd->ops->set_bus_param(icd, common_flags); | ||
| 1086 | if (ret < 0) { | ||
| 1087 | dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n", | ||
| 1088 | common_flags, ret); | 1061 | common_flags, ret); |
| 1089 | return ret; | 1062 | return ret; |
| 1090 | } | 1063 | } |
| @@ -1108,13 +1081,13 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) | |||
| 1108 | /* This has been set in mx3_camera_activate(), but we clear it above */ | 1081 | /* This has been set in mx3_camera_activate(), but we clear it above */ |
| 1109 | sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; | 1082 | sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; |
| 1110 | 1083 | ||
| 1111 | if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) | 1084 | if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) |
| 1112 | sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; | 1085 | sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; |
| 1113 | if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) | 1086 | if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) |
| 1114 | sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; | 1087 | sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; |
| 1115 | if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) | 1088 | if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) |
| 1116 | sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; | 1089 | sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; |
| 1117 | if (common_flags & SOCAM_DATA_ACTIVE_LOW) | 1090 | if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW) |
| 1118 | sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; | 1091 | sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; |
| 1119 | 1092 | ||
| 1120 | /* Just do what we're asked to do */ | 1093 | /* Just do what we're asked to do */ |
| @@ -1199,6 +1172,14 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev) | |||
| 1199 | "data widths, using default 8 bit\n"); | 1172 | "data widths, using default 8 bit\n"); |
| 1200 | mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; | 1173 | mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; |
| 1201 | } | 1174 | } |
| 1175 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4) | ||
| 1176 | mx3_cam->width_flags = 1 << 3; | ||
| 1177 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) | ||
| 1178 | mx3_cam->width_flags |= 1 << 7; | ||
| 1179 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) | ||
| 1180 | mx3_cam->width_flags |= 1 << 9; | ||
| 1181 | if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) | ||
| 1182 | mx3_cam->width_flags |= 1 << 14; | ||
| 1202 | 1183 | ||
| 1203 | mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; | 1184 | mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; |
| 1204 | if (!mx3_cam->mclk) { | 1185 | if (!mx3_cam->mclk) { |
