aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pxa_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pxa_camera.c')
-rw-r--r--drivers/media/video/pxa_camera.c140
1 files changed, 80 insertions, 60 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index d07df22a5ec..79fb22c89ae 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -214,6 +214,7 @@ struct pxa_camera_dev {
214 unsigned long ciclk; 214 unsigned long ciclk;
215 unsigned long mclk; 215 unsigned long mclk;
216 u32 mclk_divisor; 216 u32 mclk_divisor;
217 u16 width_flags; /* max 10 bits */
217 218
218 struct list_head capture; 219 struct list_head capture;
219 220
@@ -1020,37 +1021,20 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
1020 * quick capture interface supports both. 1021 * quick capture interface supports both.
1021 */ 1022 */
1022 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? 1023 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
1023 SOCAM_MASTER : SOCAM_SLAVE) | 1024 V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
1024 SOCAM_HSYNC_ACTIVE_HIGH | 1025 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1025 SOCAM_HSYNC_ACTIVE_LOW | 1026 V4L2_MBUS_HSYNC_ACTIVE_LOW |
1026 SOCAM_VSYNC_ACTIVE_HIGH | 1027 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
1027 SOCAM_VSYNC_ACTIVE_LOW | 1028 V4L2_MBUS_VSYNC_ACTIVE_LOW |
1028 SOCAM_DATA_ACTIVE_HIGH | 1029 V4L2_MBUS_DATA_ACTIVE_HIGH |
1029 SOCAM_PCLK_SAMPLE_RISING | 1030 V4L2_MBUS_PCLK_SAMPLE_RISING |
1030 SOCAM_PCLK_SAMPLE_FALLING; 1031 V4L2_MBUS_PCLK_SAMPLE_FALLING;
1031 1032
1032 /* If requested data width is supported by the platform, use it */ 1033 /* If requested data width is supported by the platform, use it */
1033 switch (buswidth) { 1034 if ((1 << (buswidth - 1)) & pcdev->width_flags)
1034 case 10: 1035 return 0;
1035 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10))
1036 return -EINVAL;
1037 *flags |= SOCAM_DATAWIDTH_10;
1038 break;
1039 case 9:
1040 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9))
1041 return -EINVAL;
1042 *flags |= SOCAM_DATAWIDTH_9;
1043 break;
1044 case 8:
1045 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8))
1046 return -EINVAL;
1047 *flags |= SOCAM_DATAWIDTH_8;
1048 break;
1049 default:
1050 return -EINVAL;
1051 }
1052 1036
1053 return 0; 1037 return -EINVAL;
1054} 1038}
1055 1039
1056static void pxa_camera_setup_cicr(struct soc_camera_device *icd, 1040static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
@@ -1070,12 +1054,12 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1070 * Datawidth is now guaranteed to be equal to one of the three values. 1054 * Datawidth is now guaranteed to be equal to one of the three values.
1071 * We fix bit-per-pixel equal to data-width... 1055 * We fix bit-per-pixel equal to data-width...
1072 */ 1056 */
1073 switch (flags & SOCAM_DATAWIDTH_MASK) { 1057 switch (icd->current_fmt->host_fmt->bits_per_sample) {
1074 case SOCAM_DATAWIDTH_10: 1058 case 10:
1075 dw = 4; 1059 dw = 4;
1076 bpp = 0x40; 1060 bpp = 0x40;
1077 break; 1061 break;
1078 case SOCAM_DATAWIDTH_9: 1062 case 9:
1079 dw = 3; 1063 dw = 3;
1080 bpp = 0x20; 1064 bpp = 0x20;
1081 break; 1065 break;
@@ -1084,7 +1068,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1084 * Actually it can only be 8 now, 1068 * Actually it can only be 8 now,
1085 * default is just to silence compiler warnings 1069 * default is just to silence compiler warnings
1086 */ 1070 */
1087 case SOCAM_DATAWIDTH_8: 1071 case 8:
1088 dw = 2; 1072 dw = 2;
1089 bpp = 0; 1073 bpp = 0;
1090 } 1074 }
@@ -1093,11 +1077,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1093 cicr4 |= CICR4_PCLK_EN; 1077 cicr4 |= CICR4_PCLK_EN;
1094 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 1078 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1095 cicr4 |= CICR4_MCLK_EN; 1079 cicr4 |= CICR4_MCLK_EN;
1096 if (flags & SOCAM_PCLK_SAMPLE_FALLING) 1080 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1097 cicr4 |= CICR4_PCP; 1081 cicr4 |= CICR4_PCP;
1098 if (flags & SOCAM_HSYNC_ACTIVE_LOW) 1082 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1099 cicr4 |= CICR4_HSP; 1083 cicr4 |= CICR4_HSP;
1100 if (flags & SOCAM_VSYNC_ACTIVE_LOW) 1084 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1101 cicr4 |= CICR4_VSP; 1085 cicr4 |= CICR4_VSP;
1102 1086
1103 cicr0 = __raw_readl(pcdev->base + CICR0); 1087 cicr0 = __raw_readl(pcdev->base + CICR0);
@@ -1151,9 +1135,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1151 1135
1152static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1136static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1153{ 1137{
1138 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1154 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1139 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1155 struct pxa_camera_dev *pcdev = ici->priv; 1140 struct pxa_camera_dev *pcdev = ici->priv;
1156 unsigned long bus_flags, camera_flags, common_flags; 1141 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1142 unsigned long bus_flags, common_flags;
1157 int ret; 1143 int ret;
1158 struct pxa_cam *cam = icd->host_priv; 1144 struct pxa_cam *cam = icd->host_priv;
1159 1145
@@ -1162,44 +1148,58 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1162 if (ret < 0) 1148 if (ret < 0)
1163 return ret; 1149 return ret;
1164 1150
1165 camera_flags = icd->ops->query_bus_param(icd); 1151 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1166 1152 if (!ret) {
1167 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 1153 common_flags = soc_mbus_config_compatible(&cfg,
1168 if (!common_flags) 1154 bus_flags);
1169 return -EINVAL; 1155 if (!common_flags) {
1156 dev_warn(icd->parent,
1157 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1158 cfg.flags, bus_flags);
1159 return -EINVAL;
1160 }
1161 } else if (ret != -ENOIOCTLCMD) {
1162 return ret;
1163 } else {
1164 common_flags = bus_flags;
1165 }
1170 1166
1171 pcdev->channels = 1; 1167 pcdev->channels = 1;
1172 1168
1173 /* Make choises, based on platform preferences */ 1169 /* Make choises, based on platform preferences */
1174 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 1170 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1175 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 1171 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1176 if (pcdev->platform_flags & PXA_CAMERA_HSP) 1172 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1177 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 1173 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1178 else 1174 else
1179 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 1175 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1180 } 1176 }
1181 1177
1182 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 1178 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1183 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 1179 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1184 if (pcdev->platform_flags & PXA_CAMERA_VSP) 1180 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1185 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 1181 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1186 else 1182 else
1187 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 1183 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1188 } 1184 }
1189 1185
1190 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1186 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1191 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1187 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1192 if (pcdev->platform_flags & PXA_CAMERA_PCP) 1188 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1193 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1189 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1194 else 1190 else
1195 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1191 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1196 } 1192 }
1197 1193
1198 cam->flags = common_flags; 1194 cfg.flags = common_flags;
1199 1195 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1200 ret = icd->ops->set_bus_param(icd, common_flags); 1196 if (ret < 0 && ret != -ENOIOCTLCMD) {
1201 if (ret < 0) 1197 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
1198 common_flags, ret);
1202 return ret; 1199 return ret;
1200 }
1201
1202 cam->flags = common_flags;
1203 1203
1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt); 1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1205 1205
@@ -1209,17 +1209,31 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd, 1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1210 unsigned char buswidth) 1210 unsigned char buswidth)
1211{ 1211{
1212 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1212 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1213 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1213 struct pxa_camera_dev *pcdev = ici->priv; 1214 struct pxa_camera_dev *pcdev = ici->priv;
1214 unsigned long bus_flags, camera_flags; 1215 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1216 unsigned long bus_flags, common_flags;
1215 int ret = test_platform_param(pcdev, buswidth, &bus_flags); 1217 int ret = test_platform_param(pcdev, buswidth, &bus_flags);
1216 1218
1217 if (ret < 0) 1219 if (ret < 0)
1218 return ret; 1220 return ret;
1219 1221
1220 camera_flags = icd->ops->query_bus_param(icd); 1222 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1223 if (!ret) {
1224 common_flags = soc_mbus_config_compatible(&cfg,
1225 bus_flags);
1226 if (!common_flags) {
1227 dev_warn(icd->parent,
1228 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1229 cfg.flags, bus_flags);
1230 return -EINVAL;
1231 }
1232 } else if (ret == -ENOIOCTLCMD) {
1233 ret = 0;
1234 }
1221 1235
1222 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1236 return ret;
1223} 1237}
1224 1238
1225static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { 1239static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
@@ -1687,6 +1701,12 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1687 "data widths, using default 10 bit\n"); 1701 "data widths, using default 10 bit\n");
1688 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; 1702 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
1689 } 1703 }
1704 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
1705 pcdev->width_flags = 1 << 7;
1706 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
1707 pcdev->width_flags |= 1 << 8;
1708 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
1709 pcdev->width_flags |= 1 << 9;
1690 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; 1710 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
1691 if (!pcdev->mclk) { 1711 if (!pcdev->mclk) {
1692 dev_warn(&pdev->dev, 1712 dev_warn(&pdev->dev,