aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pxa_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-12-11 09:46:49 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-16 06:27:29 -0500
commit760697beca338599a65484389c7abbe54aedb664 (patch)
tree515735429d2240629a6f048ab1a7fefaf5299e46 /drivers/media/video/pxa_camera.c
parent9a74251d8bee7a25fee89a0be3ccea73e01c1a05 (diff)
V4L/DVB (13659): soc-camera: convert to the new mediabus API
Convert soc-camera core and all soc-camera drivers to the new mediabus API. This also takes soc-camera client drivers one step closer to also be usable with generic v4l2-subdev host drivers. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pxa_camera.c')
-rw-r--r--drivers/media/video/pxa_camera.c272
1 files changed, 143 insertions, 129 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index f063f5981f43..294f860ce2b0 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -32,6 +32,7 @@
32#include <media/v4l2-dev.h> 32#include <media/v4l2-dev.h>
33#include <media/videobuf-dma-sg.h> 33#include <media/videobuf-dma-sg.h>
34#include <media/soc_camera.h> 34#include <media/soc_camera.h>
35#include <media/soc_mediabus.h>
35 36
36#include <linux/videodev2.h> 37#include <linux/videodev2.h>
37 38
@@ -183,16 +184,12 @@ struct pxa_cam_dma {
183/* buffer for one video frame */ 184/* buffer for one video frame */
184struct pxa_buffer { 185struct pxa_buffer {
185 /* common v4l buffer stuff -- must be first */ 186 /* common v4l buffer stuff -- must be first */
186 struct videobuf_buffer vb; 187 struct videobuf_buffer vb;
187 188 enum v4l2_mbus_pixelcode code;
188 const struct soc_camera_data_format *fmt;
189
190 /* our descriptor lists for Y, U and V channels */ 189 /* our descriptor lists for Y, U and V channels */
191 struct pxa_cam_dma dmas[3]; 190 struct pxa_cam_dma dmas[3];
192 191 int inwork;
193 int inwork; 192 enum pxa_camera_active_dma active_dma;
194
195 enum pxa_camera_active_dma active_dma;
196}; 193};
197 194
198struct pxa_camera_dev { 195struct pxa_camera_dev {
@@ -243,11 +240,15 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
243 unsigned int *size) 240 unsigned int *size)
244{ 241{
245 struct soc_camera_device *icd = vq->priv_data; 242 struct soc_camera_device *icd = vq->priv_data;
243 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
244 icd->current_fmt->host_fmt);
245
246 if (bytes_per_line < 0)
247 return bytes_per_line;
246 248
247 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 249 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
248 250
249 *size = roundup(icd->user_width * icd->user_height * 251 *size = bytes_per_line * icd->user_height;
250 ((icd->current_fmt->depth + 7) >> 3), 8);
251 252
252 if (0 == *count) 253 if (0 == *count)
253 *count = 32; 254 *count = 32;
@@ -433,6 +434,11 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
433 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 434 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
434 int ret; 435 int ret;
435 int size_y, size_u = 0, size_v = 0; 436 int size_y, size_u = 0, size_v = 0;
437 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
438 icd->current_fmt->host_fmt);
439
440 if (bytes_per_line < 0)
441 return bytes_per_line;
436 442
437 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 443 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
438 vb, vb->baddr, vb->bsize); 444 vb, vb->baddr, vb->bsize);
@@ -456,18 +462,18 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
456 */ 462 */
457 buf->inwork = 1; 463 buf->inwork = 1;
458 464
459 if (buf->fmt != icd->current_fmt || 465 if (buf->code != icd->current_fmt->code ||
460 vb->width != icd->user_width || 466 vb->width != icd->user_width ||
461 vb->height != icd->user_height || 467 vb->height != icd->user_height ||
462 vb->field != field) { 468 vb->field != field) {
463 buf->fmt = icd->current_fmt; 469 buf->code = icd->current_fmt->code;
464 vb->width = icd->user_width; 470 vb->width = icd->user_width;
465 vb->height = icd->user_height; 471 vb->height = icd->user_height;
466 vb->field = field; 472 vb->field = field;
467 vb->state = VIDEOBUF_NEEDS_INIT; 473 vb->state = VIDEOBUF_NEEDS_INIT;
468 } 474 }
469 475
470 vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); 476 vb->size = bytes_per_line * vb->height;
471 if (0 != vb->baddr && vb->bsize < vb->size) { 477 if (0 != vb->baddr && vb->bsize < vb->size) {
472 ret = -EINVAL; 478 ret = -EINVAL;
473 goto out; 479 goto out;
@@ -1157,9 +1163,15 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1157 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1163 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1158 struct pxa_camera_dev *pcdev = ici->priv; 1164 struct pxa_camera_dev *pcdev = ici->priv;
1159 unsigned long bus_flags, camera_flags, common_flags; 1165 unsigned long bus_flags, camera_flags, common_flags;
1160 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags); 1166 const struct soc_mbus_pixelfmt *fmt;
1167 int ret;
1161 struct pxa_cam *cam = icd->host_priv; 1168 struct pxa_cam *cam = icd->host_priv;
1162 1169
1170 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1171 if (!fmt)
1172 return -EINVAL;
1173
1174 ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
1163 if (ret < 0) 1175 if (ret < 0)
1164 return ret; 1176 return ret;
1165 1177
@@ -1223,59 +1235,49 @@ static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1223 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1235 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL;
1224} 1236}
1225 1237
1226static const struct soc_camera_data_format pxa_camera_formats[] = { 1238static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
1227 { 1239 {
1228 .name = "Planar YUV422 16 bit", 1240 .fourcc = V4L2_PIX_FMT_YUV422P,
1229 .depth = 16, 1241 .name = "Planar YUV422 16 bit",
1230 .fourcc = V4L2_PIX_FMT_YUV422P, 1242 .bits_per_sample = 8,
1231 .colorspace = V4L2_COLORSPACE_JPEG, 1243 .packing = SOC_MBUS_PACKING_2X8_PADHI,
1244 .order = SOC_MBUS_ORDER_LE,
1232 }, 1245 },
1233}; 1246};
1234 1247
1235static bool buswidth_supported(struct soc_camera_device *icd, int depth) 1248/* This will be corrected as we get more formats */
1249static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
1236{ 1250{
1237 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1251 return fmt->packing == SOC_MBUS_PACKING_NONE ||
1238 struct pxa_camera_dev *pcdev = ici->priv; 1252 (fmt->bits_per_sample == 8 &&
1239 1253 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
1240 switch (depth) { 1254 (fmt->bits_per_sample > 8 &&
1241 case 8: 1255 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
1242 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8);
1243 case 9:
1244 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9);
1245 case 10:
1246 return !!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10);
1247 }
1248 return false;
1249}
1250
1251static int required_buswidth(const struct soc_camera_data_format *fmt)
1252{
1253 switch (fmt->fourcc) {
1254 case V4L2_PIX_FMT_UYVY:
1255 case V4L2_PIX_FMT_VYUY:
1256 case V4L2_PIX_FMT_YUYV:
1257 case V4L2_PIX_FMT_YVYU:
1258 case V4L2_PIX_FMT_RGB565:
1259 case V4L2_PIX_FMT_RGB555:
1260 return 8;
1261 default:
1262 return fmt->depth;
1263 }
1264} 1256}
1265 1257
1266static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, 1258static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1267 struct soc_camera_format_xlate *xlate) 1259 struct soc_camera_format_xlate *xlate)
1268{ 1260{
1261 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1269 struct device *dev = icd->dev.parent; 1262 struct device *dev = icd->dev.parent;
1270 int formats = 0, buswidth, ret; 1263 int formats = 0, ret;
1271 struct pxa_cam *cam; 1264 struct pxa_cam *cam;
1265 enum v4l2_mbus_pixelcode code;
1266 const struct soc_mbus_pixelfmt *fmt;
1272 1267
1273 buswidth = required_buswidth(icd->formats + idx); 1268 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
1269 if (ret < 0)
1270 /* No more formats */
1271 return 0;
1274 1272
1275 if (!buswidth_supported(icd, buswidth)) 1273 fmt = soc_mbus_get_fmtdesc(code);
1274 if (!fmt) {
1275 dev_err(dev, "Invalid format code #%d: %d\n", idx, code);
1276 return 0; 1276 return 0;
1277 }
1277 1278
1278 ret = pxa_camera_try_bus_param(icd, buswidth); 1279 /* This also checks support for the requested bits-per-sample */
1280 ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample);
1279 if (ret < 0) 1281 if (ret < 0)
1280 return 0; 1282 return 0;
1281 1283
@@ -1289,45 +1291,40 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1289 cam = icd->host_priv; 1291 cam = icd->host_priv;
1290 } 1292 }
1291 1293
1292 switch (icd->formats[idx].fourcc) { 1294 switch (code) {
1293 case V4L2_PIX_FMT_UYVY: 1295 case V4L2_MBUS_FMT_YUYV8_2X8_BE:
1294 formats++; 1296 formats++;
1295 if (xlate) { 1297 if (xlate) {
1296 xlate->host_fmt = &pxa_camera_formats[0]; 1298 xlate->host_fmt = &pxa_camera_formats[0];
1297 xlate->cam_fmt = icd->formats + idx; 1299 xlate->code = code;
1298 xlate->buswidth = buswidth;
1299 xlate++; 1300 xlate++;
1300 dev_dbg(dev, "Providing format %s using %s\n", 1301 dev_dbg(dev, "Providing format %s using code %d\n",
1301 pxa_camera_formats[0].name, 1302 pxa_camera_formats[0].name, code);
1302 icd->formats[idx].name);
1303 } 1303 }
1304 case V4L2_PIX_FMT_VYUY: 1304 case V4L2_MBUS_FMT_YVYU8_2X8_BE:
1305 case V4L2_PIX_FMT_YUYV: 1305 case V4L2_MBUS_FMT_YUYV8_2X8_LE:
1306 case V4L2_PIX_FMT_YVYU: 1306 case V4L2_MBUS_FMT_YVYU8_2X8_LE:
1307 case V4L2_PIX_FMT_RGB565: 1307 case V4L2_MBUS_FMT_RGB565_2X8_LE:
1308 case V4L2_PIX_FMT_RGB555: 1308 case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
1309 formats++; 1309 if (xlate)
1310 if (xlate) {
1311 xlate->host_fmt = icd->formats + idx;
1312 xlate->cam_fmt = icd->formats + idx;
1313 xlate->buswidth = buswidth;
1314 xlate++;
1315 dev_dbg(dev, "Providing format %s packed\n", 1310 dev_dbg(dev, "Providing format %s packed\n",
1316 icd->formats[idx].name); 1311 fmt->name);
1317 }
1318 break; 1312 break;
1319 default: 1313 default:
1320 /* Generic pass-through */ 1314 if (!pxa_camera_packing_supported(fmt))
1321 formats++; 1315 return 0;
1322 if (xlate) { 1316 if (xlate)
1323 xlate->host_fmt = icd->formats + idx;
1324 xlate->cam_fmt = icd->formats + idx;
1325 xlate->buswidth = icd->formats[idx].depth;
1326 xlate++;
1327 dev_dbg(dev, 1317 dev_dbg(dev,
1328 "Providing format %s in pass-through mode\n", 1318 "Providing format %s in pass-through mode\n",
1329 icd->formats[idx].name); 1319 fmt->name);
1330 } 1320 }
1321
1322 /* Generic pass-through */
1323 formats++;
1324 if (xlate) {
1325 xlate->host_fmt = fmt;
1326 xlate->code = code;
1327 xlate++;
1331 } 1328 }
1332 1329
1333 return formats; 1330 return formats;
@@ -1339,11 +1336,11 @@ static void pxa_camera_put_formats(struct soc_camera_device *icd)
1339 icd->host_priv = NULL; 1336 icd->host_priv = NULL;
1340} 1337}
1341 1338
1342static int pxa_camera_check_frame(struct v4l2_pix_format *pix) 1339static int pxa_camera_check_frame(u32 width, u32 height)
1343{ 1340{
1344 /* limit to pxa hardware capabilities */ 1341 /* limit to pxa hardware capabilities */
1345 return pix->height < 32 || pix->height > 2048 || pix->width < 48 || 1342 return height < 32 || height > 2048 || width < 48 || width > 2048 ||
1346 pix->width > 2048 || (pix->width & 0x01); 1343 (width & 0x01);
1347} 1344}
1348 1345
1349static int pxa_camera_set_crop(struct soc_camera_device *icd, 1346static int pxa_camera_set_crop(struct soc_camera_device *icd,
@@ -1358,9 +1355,9 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1358 .master_clock = pcdev->mclk, 1355 .master_clock = pcdev->mclk,
1359 .pixel_clock_max = pcdev->ciclk / 4, 1356 .pixel_clock_max = pcdev->ciclk / 4,
1360 }; 1357 };
1361 struct v4l2_format f; 1358 struct v4l2_mbus_framefmt mf;
1362 struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
1363 struct pxa_cam *cam = icd->host_priv; 1359 struct pxa_cam *cam = icd->host_priv;
1360 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
1364 int ret; 1361 int ret;
1365 1362
1366 /* If PCLK is used to latch data from the sensor, check sense */ 1363 /* If PCLK is used to latch data from the sensor, check sense */
@@ -1377,27 +1374,23 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1377 return ret; 1374 return ret;
1378 } 1375 }
1379 1376
1380 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1377 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
1381
1382 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1383 if (ret < 0) 1378 if (ret < 0)
1384 return ret; 1379 return ret;
1385 1380
1386 pix_tmp = *pix; 1381 if (pxa_camera_check_frame(mf.width, mf.height)) {
1387 if (pxa_camera_check_frame(pix)) {
1388 /* 1382 /*
1389 * Camera cropping produced a frame beyond our capabilities. 1383 * Camera cropping produced a frame beyond our capabilities.
1390 * FIXME: just extract a subframe, that we can process. 1384 * FIXME: just extract a subframe, that we can process.
1391 */ 1385 */
1392 v4l_bound_align_image(&pix->width, 48, 2048, 1, 1386 v4l_bound_align_image(&mf.width, 48, 2048, 1,
1393 &pix->height, 32, 2048, 0, 1387 &mf.height, 32, 2048, 0,
1394 icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 1388 fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1395 4 : 0); 1389 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1396 ret = v4l2_subdev_call(sd, video, s_fmt, &f);
1397 if (ret < 0) 1390 if (ret < 0)
1398 return ret; 1391 return ret;
1399 1392
1400 if (pxa_camera_check_frame(pix)) { 1393 if (pxa_camera_check_frame(mf.width, mf.height)) {
1401 dev_warn(icd->dev.parent, 1394 dev_warn(icd->dev.parent,
1402 "Inconsistent state. Use S_FMT to repair\n"); 1395 "Inconsistent state. Use S_FMT to repair\n");
1403 return -EINVAL; 1396 return -EINVAL;
@@ -1414,10 +1407,10 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1414 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1407 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1415 } 1408 }
1416 1409
1417 icd->user_width = pix->width; 1410 icd->user_width = mf.width;
1418 icd->user_height = pix->height; 1411 icd->user_height = mf.height;
1419 1412
1420 pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc); 1413 pxa_camera_setup_cicr(icd, cam->flags, fourcc);
1421 1414
1422 return ret; 1415 return ret;
1423} 1416}
@@ -1429,14 +1422,13 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1429 struct pxa_camera_dev *pcdev = ici->priv; 1422 struct pxa_camera_dev *pcdev = ici->priv;
1430 struct device *dev = icd->dev.parent; 1423 struct device *dev = icd->dev.parent;
1431 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1424 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1432 const struct soc_camera_data_format *cam_fmt = NULL;
1433 const struct soc_camera_format_xlate *xlate = NULL; 1425 const struct soc_camera_format_xlate *xlate = NULL;
1434 struct soc_camera_sense sense = { 1426 struct soc_camera_sense sense = {
1435 .master_clock = pcdev->mclk, 1427 .master_clock = pcdev->mclk,
1436 .pixel_clock_max = pcdev->ciclk / 4, 1428 .pixel_clock_max = pcdev->ciclk / 4,
1437 }; 1429 };
1438 struct v4l2_pix_format *pix = &f->fmt.pix; 1430 struct v4l2_pix_format *pix = &f->fmt.pix;
1439 struct v4l2_format cam_f = *f; 1431 struct v4l2_mbus_framefmt mf;
1440 int ret; 1432 int ret;
1441 1433
1442 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1434 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -1445,26 +1437,31 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1445 return -EINVAL; 1437 return -EINVAL;
1446 } 1438 }
1447 1439
1448 cam_fmt = xlate->cam_fmt;
1449
1450 /* If PCLK is used to latch data from the sensor, check sense */ 1440 /* If PCLK is used to latch data from the sensor, check sense */
1451 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1441 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1442 /* The caller holds a mutex. */
1452 icd->sense = &sense; 1443 icd->sense = &sense;
1453 1444
1454 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; 1445 mf.width = pix->width;
1455 ret = v4l2_subdev_call(sd, video, s_fmt, &cam_f); 1446 mf.height = pix->height;
1456 cam_f.fmt.pix.pixelformat = pix->pixelformat; 1447 mf.field = pix->field;
1457 *pix = cam_f.fmt.pix; 1448 mf.colorspace = pix->colorspace;
1449 mf.code = xlate->code;
1450
1451 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
1452
1453 if (mf.code != xlate->code)
1454 return -EINVAL;
1458 1455
1459 icd->sense = NULL; 1456 icd->sense = NULL;
1460 1457
1461 if (ret < 0) { 1458 if (ret < 0) {
1462 dev_warn(dev, "Failed to configure for format %x\n", 1459 dev_warn(dev, "Failed to configure for format %x\n",
1463 pix->pixelformat); 1460 pix->pixelformat);
1464 } else if (pxa_camera_check_frame(pix)) { 1461 } else if (pxa_camera_check_frame(mf.width, mf.height)) {
1465 dev_warn(dev, 1462 dev_warn(dev,
1466 "Camera driver produced an unsupported frame %dx%d\n", 1463 "Camera driver produced an unsupported frame %dx%d\n",
1467 pix->width, pix->height); 1464 mf.width, mf.height);
1468 ret = -EINVAL; 1465 ret = -EINVAL;
1469 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1466 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1470 if (sense.pixel_clock > sense.pixel_clock_max) { 1467 if (sense.pixel_clock > sense.pixel_clock_max) {
@@ -1476,10 +1473,14 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1476 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1473 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1477 } 1474 }
1478 1475
1479 if (!ret) { 1476 if (ret < 0)
1480 icd->buswidth = xlate->buswidth; 1477 return ret;
1481 icd->current_fmt = xlate->host_fmt; 1478
1482 } 1479 pix->width = mf.width;
1480 pix->height = mf.height;
1481 pix->field = mf.field;
1482 pix->colorspace = mf.colorspace;
1483 icd->current_fmt = xlate;
1483 1484
1484 return ret; 1485 return ret;
1485} 1486}
@@ -1487,17 +1488,16 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1487static int pxa_camera_try_fmt(struct soc_camera_device *icd, 1488static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1488 struct v4l2_format *f) 1489 struct v4l2_format *f)
1489{ 1490{
1490 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1491 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1491 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1492 const struct soc_camera_format_xlate *xlate; 1492 const struct soc_camera_format_xlate *xlate;
1493 struct v4l2_pix_format *pix = &f->fmt.pix; 1493 struct v4l2_pix_format *pix = &f->fmt.pix;
1494 struct v4l2_mbus_framefmt mf;
1494 __u32 pixfmt = pix->pixelformat; 1495 __u32 pixfmt = pix->pixelformat;
1495 enum v4l2_field field;
1496 int ret; 1496 int ret;
1497 1497
1498 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1498 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1499 if (!xlate) { 1499 if (!xlate) {
1500 dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt); 1500 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
1501 return -EINVAL; 1501 return -EINVAL;
1502 } 1502 }
1503 1503
@@ -1511,22 +1511,36 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1511 &pix->height, 32, 2048, 0, 1511 &pix->height, 32, 2048, 0,
1512 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); 1512 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1513 1513
1514 pix->bytesperline = pix->width * 1514 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
1515 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1515 xlate->host_fmt);
1516 if (pix->bytesperline < 0)
1517 return pix->bytesperline;
1516 pix->sizeimage = pix->height * pix->bytesperline; 1518 pix->sizeimage = pix->height * pix->bytesperline;
1517 1519
1518 /* camera has to see its format, but the user the original one */
1519 pix->pixelformat = xlate->cam_fmt->fourcc;
1520 /* limit to sensor capabilities */ 1520 /* limit to sensor capabilities */
1521 ret = v4l2_subdev_call(sd, video, try_fmt, f); 1521 mf.width = pix->width;
1522 pix->pixelformat = pixfmt; 1522 mf.height = pix->height;
1523 mf.field = pix->field;
1524 mf.colorspace = pix->colorspace;
1525 mf.code = xlate->code;
1523 1526
1524 field = pix->field; 1527 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
1528 if (ret < 0)
1529 return ret;
1525 1530
1526 if (field == V4L2_FIELD_ANY) { 1531 pix->width = mf.width;
1527 pix->field = V4L2_FIELD_NONE; 1532 pix->height = mf.height;
1528 } else if (field != V4L2_FIELD_NONE) { 1533 pix->colorspace = mf.colorspace;
1529 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); 1534
1535 switch (mf.field) {
1536 case V4L2_FIELD_ANY:
1537 case V4L2_FIELD_NONE:
1538 pix->field = V4L2_FIELD_NONE;
1539 break;
1540 default:
1541 /* TODO: support interlaced at least in pass-through mode */
1542 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
1543 mf.field);
1530 return -EINVAL; 1544 return -EINVAL;
1531 } 1545 }
1532 1546