aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/soc_camera/omap1_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/soc_camera/omap1_camera.c')
-rw-r--r--drivers/media/platform/soc_camera/omap1_camera.c106
1 files changed, 60 insertions, 46 deletions
diff --git a/drivers/media/platform/soc_camera/omap1_camera.c b/drivers/media/platform/soc_camera/omap1_camera.c
index 16f65ecb70a3..ba8dcd11ae0e 100644
--- a/drivers/media/platform/soc_camera/omap1_camera.c
+++ b/drivers/media/platform/soc_camera/omap1_camera.c
@@ -1068,18 +1068,21 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1068 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1068 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1069 struct device *dev = icd->parent; 1069 struct device *dev = icd->parent;
1070 int formats = 0, ret; 1070 int formats = 0, ret;
1071 u32 code; 1071 struct v4l2_subdev_mbus_code_enum code = {
1072 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1073 .index = idx,
1074 };
1072 const struct soc_mbus_pixelfmt *fmt; 1075 const struct soc_mbus_pixelfmt *fmt;
1073 1076
1074 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code); 1077 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code);
1075 if (ret < 0) 1078 if (ret < 0)
1076 /* No more formats */ 1079 /* No more formats */
1077 return 0; 1080 return 0;
1078 1081
1079 fmt = soc_mbus_get_fmtdesc(code); 1082 fmt = soc_mbus_get_fmtdesc(code.code);
1080 if (!fmt) { 1083 if (!fmt) {
1081 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__, 1084 dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
1082 idx, code); 1085 idx, code.code);
1083 return 0; 1086 return 0;
1084 } 1087 }
1085 1088
@@ -1087,7 +1090,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1087 if (fmt->bits_per_sample != 8) 1090 if (fmt->bits_per_sample != 8)
1088 return 0; 1091 return 0;
1089 1092
1090 switch (code) { 1093 switch (code.code) {
1091 case MEDIA_BUS_FMT_YUYV8_2X8: 1094 case MEDIA_BUS_FMT_YUYV8_2X8:
1092 case MEDIA_BUS_FMT_YVYU8_2X8: 1095 case MEDIA_BUS_FMT_YVYU8_2X8:
1093 case MEDIA_BUS_FMT_UYVY8_2X8: 1096 case MEDIA_BUS_FMT_UYVY8_2X8:
@@ -1098,14 +1101,14 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1098 case MEDIA_BUS_FMT_RGB565_2X8_LE: 1101 case MEDIA_BUS_FMT_RGB565_2X8_LE:
1099 formats++; 1102 formats++;
1100 if (xlate) { 1103 if (xlate) {
1101 xlate->host_fmt = soc_mbus_find_fmtdesc(code, 1104 xlate->host_fmt = soc_mbus_find_fmtdesc(code.code,
1102 omap1_cam_formats, 1105 omap1_cam_formats,
1103 ARRAY_SIZE(omap1_cam_formats)); 1106 ARRAY_SIZE(omap1_cam_formats));
1104 xlate->code = code; 1107 xlate->code = code.code;
1105 xlate++; 1108 xlate++;
1106 dev_dbg(dev, 1109 dev_dbg(dev,
1107 "%s: providing format %s as byte swapped code #%d\n", 1110 "%s: providing format %s as byte swapped code #%d\n",
1108 __func__, xlate->host_fmt->name, code); 1111 __func__, xlate->host_fmt->name, code.code);
1109 } 1112 }
1110 default: 1113 default:
1111 if (xlate) 1114 if (xlate)
@@ -1116,7 +1119,7 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1116 formats++; 1119 formats++;
1117 if (xlate) { 1120 if (xlate) {
1118 xlate->host_fmt = fmt; 1121 xlate->host_fmt = fmt;
1119 xlate->code = code; 1122 xlate->code = code.code;
1120 xlate++; 1123 xlate++;
1121 } 1124 }
1122 1125
@@ -1154,7 +1157,7 @@ static int dma_align(int *width, int *height,
1154 return 1; 1157 return 1;
1155} 1158}
1156 1159
1157#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \ 1160#define subdev_call_with_sense(pcdev, dev, icd, sd, op, function, args...) \
1158({ \ 1161({ \
1159 struct soc_camera_sense sense = { \ 1162 struct soc_camera_sense sense = { \
1160 .master_clock = pcdev->camexclk, \ 1163 .master_clock = pcdev->camexclk, \
@@ -1165,7 +1168,7 @@ static int dma_align(int *width, int *height,
1165 if (pcdev->pdata) \ 1168 if (pcdev->pdata) \
1166 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \ 1169 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
1167 icd->sense = &sense; \ 1170 icd->sense = &sense; \
1168 __ret = v4l2_subdev_call(sd, video, function, ##args); \ 1171 __ret = v4l2_subdev_call(sd, op, function, ##args); \
1169 icd->sense = NULL; \ 1172 icd->sense = NULL; \
1170 \ 1173 \
1171 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \ 1174 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
@@ -1179,16 +1182,17 @@ static int dma_align(int *width, int *height,
1179 __ret; \ 1182 __ret; \
1180}) 1183})
1181 1184
1182static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, 1185static int set_format(struct omap1_cam_dev *pcdev, struct device *dev,
1183 struct soc_camera_device *icd, struct v4l2_subdev *sd, 1186 struct soc_camera_device *icd, struct v4l2_subdev *sd,
1184 struct v4l2_mbus_framefmt *mf, 1187 struct v4l2_subdev_format *format,
1185 const struct soc_camera_format_xlate *xlate) 1188 const struct soc_camera_format_xlate *xlate)
1186{ 1189{
1187 s32 bytes_per_line; 1190 s32 bytes_per_line;
1188 int ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_mbus_fmt, mf); 1191 struct v4l2_mbus_framefmt *mf = &format->format;
1192 int ret = subdev_call_with_sense(pcdev, dev, icd, sd, pad, set_fmt, NULL, format);
1189 1193
1190 if (ret < 0) { 1194 if (ret < 0) {
1191 dev_err(dev, "%s: s_mbus_fmt failed\n", __func__); 1195 dev_err(dev, "%s: set_fmt failed\n", __func__);
1192 return ret; 1196 return ret;
1193 } 1197 }
1194 1198
@@ -1221,42 +1225,45 @@ static int omap1_cam_set_crop(struct soc_camera_device *icd,
1221 struct device *dev = icd->parent; 1225 struct device *dev = icd->parent;
1222 struct soc_camera_host *ici = to_soc_camera_host(dev); 1226 struct soc_camera_host *ici = to_soc_camera_host(dev);
1223 struct omap1_cam_dev *pcdev = ici->priv; 1227 struct omap1_cam_dev *pcdev = ici->priv;
1224 struct v4l2_mbus_framefmt mf; 1228 struct v4l2_subdev_format fmt = {
1229 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1230 };
1231 struct v4l2_mbus_framefmt *mf = &fmt.format;
1225 int ret; 1232 int ret;
1226 1233
1227 ret = subdev_call_with_sense(pcdev, dev, icd, sd, s_crop, crop); 1234 ret = subdev_call_with_sense(pcdev, dev, icd, sd, video, s_crop, crop);
1228 if (ret < 0) { 1235 if (ret < 0) {
1229 dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__, 1236 dev_warn(dev, "%s: failed to crop to %ux%u@%u:%u\n", __func__,
1230 rect->width, rect->height, rect->left, rect->top); 1237 rect->width, rect->height, rect->left, rect->top);
1231 return ret; 1238 return ret;
1232 } 1239 }
1233 1240
1234 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf); 1241 ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
1235 if (ret < 0) { 1242 if (ret < 0) {
1236 dev_warn(dev, "%s: failed to fetch current format\n", __func__); 1243 dev_warn(dev, "%s: failed to fetch current format\n", __func__);
1237 return ret; 1244 return ret;
1238 } 1245 }
1239 1246
1240 ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, 1247 ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode,
1241 false); 1248 false);
1242 if (ret < 0) { 1249 if (ret < 0) {
1243 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", 1250 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
1244 __func__, mf.width, mf.height, 1251 __func__, mf->width, mf->height,
1245 xlate->host_fmt->name); 1252 xlate->host_fmt->name);
1246 return ret; 1253 return ret;
1247 } 1254 }
1248 1255
1249 if (!ret) { 1256 if (!ret) {
1250 /* sensor returned geometry not DMA aligned, trying to fix */ 1257 /* sensor returned geometry not DMA aligned, trying to fix */
1251 ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); 1258 ret = set_format(pcdev, dev, icd, sd, &fmt, xlate);
1252 if (ret < 0) { 1259 if (ret < 0) {
1253 dev_err(dev, "%s: failed to set format\n", __func__); 1260 dev_err(dev, "%s: failed to set format\n", __func__);
1254 return ret; 1261 return ret;
1255 } 1262 }
1256 } 1263 }
1257 1264
1258 icd->user_width = mf.width; 1265 icd->user_width = mf->width;
1259 icd->user_height = mf.height; 1266 icd->user_height = mf->height;
1260 1267
1261 return 0; 1268 return 0;
1262} 1269}
@@ -1270,7 +1277,10 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd,
1270 struct soc_camera_host *ici = to_soc_camera_host(dev); 1277 struct soc_camera_host *ici = to_soc_camera_host(dev);
1271 struct omap1_cam_dev *pcdev = ici->priv; 1278 struct omap1_cam_dev *pcdev = ici->priv;
1272 struct v4l2_pix_format *pix = &f->fmt.pix; 1279 struct v4l2_pix_format *pix = &f->fmt.pix;
1273 struct v4l2_mbus_framefmt mf; 1280 struct v4l2_subdev_format format = {
1281 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1282 };
1283 struct v4l2_mbus_framefmt *mf = &format.format;
1274 int ret; 1284 int ret;
1275 1285
1276 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1286 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -1280,13 +1290,13 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd,
1280 return -EINVAL; 1290 return -EINVAL;
1281 } 1291 }
1282 1292
1283 mf.width = pix->width; 1293 mf->width = pix->width;
1284 mf.height = pix->height; 1294 mf->height = pix->height;
1285 mf.field = pix->field; 1295 mf->field = pix->field;
1286 mf.colorspace = pix->colorspace; 1296 mf->colorspace = pix->colorspace;
1287 mf.code = xlate->code; 1297 mf->code = xlate->code;
1288 1298
1289 ret = dma_align(&mf.width, &mf.height, xlate->host_fmt, pcdev->vb_mode, 1299 ret = dma_align(&mf->width, &mf->height, xlate->host_fmt, pcdev->vb_mode,
1290 true); 1300 true);
1291 if (ret < 0) { 1301 if (ret < 0) {
1292 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n", 1302 dev_err(dev, "%s: failed to align %ux%u %s with DMA\n",
@@ -1295,16 +1305,16 @@ static int omap1_cam_set_fmt(struct soc_camera_device *icd,
1295 return ret; 1305 return ret;
1296 } 1306 }
1297 1307
1298 ret = set_mbus_format(pcdev, dev, icd, sd, &mf, xlate); 1308 ret = set_format(pcdev, dev, icd, sd, &format, xlate);
1299 if (ret < 0) { 1309 if (ret < 0) {
1300 dev_err(dev, "%s: failed to set format\n", __func__); 1310 dev_err(dev, "%s: failed to set format\n", __func__);
1301 return ret; 1311 return ret;
1302 } 1312 }
1303 1313
1304 pix->width = mf.width; 1314 pix->width = mf->width;
1305 pix->height = mf.height; 1315 pix->height = mf->height;
1306 pix->field = mf.field; 1316 pix->field = mf->field;
1307 pix->colorspace = mf.colorspace; 1317 pix->colorspace = mf->colorspace;
1308 icd->current_fmt = xlate; 1318 icd->current_fmt = xlate;
1309 1319
1310 return 0; 1320 return 0;
@@ -1316,7 +1326,11 @@ static int omap1_cam_try_fmt(struct soc_camera_device *icd,
1316 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1326 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1317 const struct soc_camera_format_xlate *xlate; 1327 const struct soc_camera_format_xlate *xlate;
1318 struct v4l2_pix_format *pix = &f->fmt.pix; 1328 struct v4l2_pix_format *pix = &f->fmt.pix;
1319 struct v4l2_mbus_framefmt mf; 1329 struct v4l2_subdev_pad_config pad_cfg;
1330 struct v4l2_subdev_format format = {
1331 .which = V4L2_SUBDEV_FORMAT_TRY,
1332 };
1333 struct v4l2_mbus_framefmt *mf = &format.format;
1320 int ret; 1334 int ret;
1321 /* TODO: limit to mx1 hardware capabilities */ 1335 /* TODO: limit to mx1 hardware capabilities */
1322 1336
@@ -1327,21 +1341,21 @@ static int omap1_cam_try_fmt(struct soc_camera_device *icd,
1327 return -EINVAL; 1341 return -EINVAL;
1328 } 1342 }
1329 1343
1330 mf.width = pix->width; 1344 mf->width = pix->width;
1331 mf.height = pix->height; 1345 mf->height = pix->height;
1332 mf.field = pix->field; 1346 mf->field = pix->field;
1333 mf.colorspace = pix->colorspace; 1347 mf->colorspace = pix->colorspace;
1334 mf.code = xlate->code; 1348 mf->code = xlate->code;
1335 1349
1336 /* limit to sensor capabilities */ 1350 /* limit to sensor capabilities */
1337 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf); 1351 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format);
1338 if (ret < 0) 1352 if (ret < 0)
1339 return ret; 1353 return ret;
1340 1354
1341 pix->width = mf.width; 1355 pix->width = mf->width;
1342 pix->height = mf.height; 1356 pix->height = mf->height;
1343 pix->field = mf.field; 1357 pix->field = mf->field;
1344 pix->colorspace = mf.colorspace; 1358 pix->colorspace = mf->colorspace;
1345 1359
1346 return 0; 1360 return 0;
1347} 1361}