aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mx3_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/mx3_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/mx3_camera.c')
-rw-r--r--drivers/media/video/mx3_camera.c278
1 files changed, 161 insertions, 117 deletions
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index ae7d48324493..bd297f567dc7 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -23,6 +23,7 @@
23#include <media/v4l2-dev.h> 23#include <media/v4l2-dev.h>
24#include <media/videobuf-dma-contig.h> 24#include <media/videobuf-dma-contig.h>
25#include <media/soc_camera.h> 25#include <media/soc_camera.h>
26#include <media/soc_mediabus.h>
26 27
27#include <mach/ipu.h> 28#include <mach/ipu.h>
28#include <mach/mx3_camera.h> 29#include <mach/mx3_camera.h>
@@ -63,7 +64,7 @@
63struct mx3_camera_buffer { 64struct mx3_camera_buffer {
64 /* common v4l buffer stuff -- must be first */ 65 /* common v4l buffer stuff -- must be first */
65 struct videobuf_buffer vb; 66 struct videobuf_buffer vb;
66 const struct soc_camera_data_format *fmt; 67 enum v4l2_mbus_pixelcode code;
67 68
68 /* One descriptot per scatterlist (per frame) */ 69 /* One descriptot per scatterlist (per frame) */
69 struct dma_async_tx_descriptor *txd; 70 struct dma_async_tx_descriptor *txd;
@@ -118,8 +119,6 @@ struct dma_chan_request {
118 enum ipu_channel id; 119 enum ipu_channel id;
119}; 120};
120 121
121static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt);
122
123static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) 122static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
124{ 123{
125 return __raw_readl(mx3->base + reg); 124 return __raw_readl(mx3->base + reg);
@@ -211,17 +210,16 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
211 struct soc_camera_device *icd = vq->priv_data; 210 struct soc_camera_device *icd = vq->priv_data;
212 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 211 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
213 struct mx3_camera_dev *mx3_cam = ici->priv; 212 struct mx3_camera_dev *mx3_cam = ici->priv;
214 /* 213 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
215 * bits-per-pixel (depth) as specified in camera's pixel format does 214 icd->current_fmt->host_fmt);
216 * not necessarily match what the camera interface writes to RAM, but 215
217 * it should be good enough for now. 216 if (bytes_per_line < 0)
218 */ 217 return bytes_per_line;
219 unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8);
220 218
221 if (!mx3_cam->idmac_channel[0]) 219 if (!mx3_cam->idmac_channel[0])
222 return -EINVAL; 220 return -EINVAL;
223 221
224 *size = icd->user_width * icd->user_height * bpp; 222 *size = bytes_per_line * icd->user_height;
225 223
226 if (!*count) 224 if (!*count)
227 *count = 32; 225 *count = 32;
@@ -241,21 +239,26 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
241 struct mx3_camera_dev *mx3_cam = ici->priv; 239 struct mx3_camera_dev *mx3_cam = ici->priv;
242 struct mx3_camera_buffer *buf = 240 struct mx3_camera_buffer *buf =
243 container_of(vb, struct mx3_camera_buffer, vb); 241 container_of(vb, struct mx3_camera_buffer, vb);
244 /* current_fmt _must_ always be set */ 242 size_t new_size;
245 size_t new_size = icd->user_width * icd->user_height *
246 ((icd->current_fmt->depth + 7) >> 3);
247 int ret; 243 int ret;
244 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
245 icd->current_fmt->host_fmt);
246
247 if (bytes_per_line < 0)
248 return bytes_per_line;
249
250 new_size = bytes_per_line * icd->user_height;
248 251
249 /* 252 /*
250 * I think, in buf_prepare you only have to protect global data, 253 * I think, in buf_prepare you only have to protect global data,
251 * the actual buffer is yours 254 * the actual buffer is yours
252 */ 255 */
253 256
254 if (buf->fmt != icd->current_fmt || 257 if (buf->code != icd->current_fmt->code ||
255 vb->width != icd->user_width || 258 vb->width != icd->user_width ||
256 vb->height != icd->user_height || 259 vb->height != icd->user_height ||
257 vb->field != field) { 260 vb->field != field) {
258 buf->fmt = icd->current_fmt; 261 buf->code = icd->current_fmt->code;
259 vb->width = icd->user_width; 262 vb->width = icd->user_width;
260 vb->height = icd->user_height; 263 vb->height = icd->user_height;
261 vb->field = field; 264 vb->field = field;
@@ -348,13 +351,13 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
348 struct dma_async_tx_descriptor *txd = buf->txd; 351 struct dma_async_tx_descriptor *txd = buf->txd;
349 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 352 struct idmac_channel *ichan = to_idmac_chan(txd->chan);
350 struct idmac_video_param *video = &ichan->params.video; 353 struct idmac_video_param *video = &ichan->params.video;
351 const struct soc_camera_data_format *data_fmt = icd->current_fmt;
352 dma_cookie_t cookie; 354 dma_cookie_t cookie;
355 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
353 356
354 BUG_ON(!irqs_disabled()); 357 BUG_ON(!irqs_disabled());
355 358
356 /* This is the configuration of one sg-element */ 359 /* This is the configuration of one sg-element */
357 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); 360 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc);
358 video->out_width = icd->user_width; 361 video->out_width = icd->user_width;
359 video->out_height = icd->user_height; 362 video->out_height = icd->user_height;
360 video->out_stride = icd->user_width; 363 video->out_stride = icd->user_width;
@@ -568,28 +571,33 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
568 * If requested data width is supported by the platform, use it or any 571 * If requested data width is supported by the platform, use it or any
569 * possible lower value - i.MX31 is smart enough to schift bits 572 * possible lower value - i.MX31 is smart enough to schift bits
570 */ 573 */
574 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
575 *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
576 SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
577 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
578 *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
579 SOCAM_DATAWIDTH_4;
580 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
581 *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
582 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
583 *flags |= SOCAM_DATAWIDTH_4;
584
571 switch (buswidth) { 585 switch (buswidth) {
572 case 15: 586 case 15:
573 if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) 587 if (!(*flags & SOCAM_DATAWIDTH_15))
574 return -EINVAL; 588 return -EINVAL;
575 *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
576 SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
577 break; 589 break;
578 case 10: 590 case 10:
579 if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) 591 if (!(*flags & SOCAM_DATAWIDTH_10))
580 return -EINVAL; 592 return -EINVAL;
581 *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
582 SOCAM_DATAWIDTH_4;
583 break; 593 break;
584 case 8: 594 case 8:
585 if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) 595 if (!(*flags & SOCAM_DATAWIDTH_8))
586 return -EINVAL; 596 return -EINVAL;
587 *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
588 break; 597 break;
589 case 4: 598 case 4:
590 if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) 599 if (!(*flags & SOCAM_DATAWIDTH_4))
591 return -EINVAL; 600 return -EINVAL;
592 *flags |= SOCAM_DATAWIDTH_4;
593 break; 601 break;
594 default: 602 default:
595 dev_warn(mx3_cam->soc_host.v4l2_dev.dev, 603 dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
@@ -638,91 +646,92 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
638 pdata->dma_dev == chan->device->dev; 646 pdata->dma_dev == chan->device->dev;
639} 647}
640 648
641static const struct soc_camera_data_format mx3_camera_formats[] = { 649static const struct soc_mbus_pixelfmt mx3_camera_formats[] = {
642 { 650 {
643 .name = "Bayer (sRGB) 8 bit", 651 .fourcc = V4L2_PIX_FMT_SBGGR8,
644 .depth = 8, 652 .name = "Bayer BGGR (sRGB) 8 bit",
645 .fourcc = V4L2_PIX_FMT_SBGGR8, 653 .bits_per_sample = 8,
646 .colorspace = V4L2_COLORSPACE_SRGB, 654 .packing = SOC_MBUS_PACKING_NONE,
655 .order = SOC_MBUS_ORDER_LE,
647 }, { 656 }, {
648 .name = "Monochrome 8 bit", 657 .fourcc = V4L2_PIX_FMT_GREY,
649 .depth = 8, 658 .name = "Monochrome 8 bit",
650 .fourcc = V4L2_PIX_FMT_GREY, 659 .bits_per_sample = 8,
651 .colorspace = V4L2_COLORSPACE_JPEG, 660 .packing = SOC_MBUS_PACKING_NONE,
661 .order = SOC_MBUS_ORDER_LE,
652 }, 662 },
653}; 663};
654 664
655static bool buswidth_supported(struct soc_camera_host *ici, int depth) 665/* This will be corrected as we get more formats */
666static bool mx3_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
656{ 667{
657 struct mx3_camera_dev *mx3_cam = ici->priv; 668 return fmt->packing == SOC_MBUS_PACKING_NONE ||
658 669 (fmt->bits_per_sample == 8 &&
659 switch (depth) { 670 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
660 case 4: 671 (fmt->bits_per_sample > 8 &&
661 return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); 672 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
662 case 8:
663 return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8);
664 case 10:
665 return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10);
666 case 15:
667 return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15);
668 }
669 return false;
670} 673}
671 674
672static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, 675static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
673 struct soc_camera_format_xlate *xlate) 676 struct soc_camera_format_xlate *xlate)
674{ 677{
675 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 678 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
676 int formats = 0, buswidth, ret; 679 struct device *dev = icd->dev.parent;
680 int formats = 0, ret;
681 enum v4l2_mbus_pixelcode code;
682 const struct soc_mbus_pixelfmt *fmt;
677 683
678 buswidth = icd->formats[idx].depth; 684 ret = v4l2_subdev_call(sd, video, enum_mbus_fmt, idx, &code);
685 if (ret < 0)
686 /* No more formats */
687 return 0;
679 688
680 if (!buswidth_supported(ici, buswidth)) 689 fmt = soc_mbus_get_fmtdesc(code);
690 if (!fmt) {
691 dev_err(icd->dev.parent,
692 "Invalid format code #%d: %d\n", idx, code);
681 return 0; 693 return 0;
694 }
682 695
683 ret = mx3_camera_try_bus_param(icd, buswidth); 696 /* This also checks support for the requested bits-per-sample */
697 ret = mx3_camera_try_bus_param(icd, fmt->bits_per_sample);
684 if (ret < 0) 698 if (ret < 0)
685 return 0; 699 return 0;
686 700
687 switch (icd->formats[idx].fourcc) { 701 switch (code) {
688 case V4L2_PIX_FMT_SGRBG10: 702 case V4L2_MBUS_FMT_SBGGR10_1X10:
689 formats++; 703 formats++;
690 if (xlate) { 704 if (xlate) {
691 xlate->host_fmt = &mx3_camera_formats[0]; 705 xlate->host_fmt = &mx3_camera_formats[0];
692 xlate->cam_fmt = icd->formats + idx; 706 xlate->code = code;
693 xlate->buswidth = buswidth;
694 xlate++; 707 xlate++;
695 dev_dbg(icd->dev.parent, 708 dev_dbg(dev, "Providing format %s using code %d\n",
696 "Providing format %s using %s\n", 709 mx3_camera_formats[0].name, code);
697 mx3_camera_formats[0].name,
698 icd->formats[idx].name);
699 } 710 }
700 goto passthrough; 711 break;
701 case V4L2_PIX_FMT_Y16: 712 case V4L2_MBUS_FMT_Y10_1X10:
702 formats++; 713 formats++;
703 if (xlate) { 714 if (xlate) {
704 xlate->host_fmt = &mx3_camera_formats[1]; 715 xlate->host_fmt = &mx3_camera_formats[1];
705 xlate->cam_fmt = icd->formats + idx; 716 xlate->code = code;
706 xlate->buswidth = buswidth;
707 xlate++; 717 xlate++;
708 dev_dbg(icd->dev.parent, 718 dev_dbg(dev, "Providing format %s using code %d\n",
709 "Providing format %s using %s\n", 719 mx3_camera_formats[1].name, code);
710 mx3_camera_formats[0].name,
711 icd->formats[idx].name);
712 } 720 }
721 break;
713 default: 722 default:
714passthrough: 723 if (!mx3_camera_packing_supported(fmt))
715 /* Generic pass-through */ 724 return 0;
716 formats++; 725 }
717 if (xlate) { 726
718 xlate->host_fmt = icd->formats + idx; 727 /* Generic pass-through */
719 xlate->cam_fmt = icd->formats + idx; 728 formats++;
720 xlate->buswidth = buswidth; 729 if (xlate) {
721 xlate++; 730 xlate->host_fmt = fmt;
722 dev_dbg(icd->dev.parent, 731 xlate->code = code;
723 "Providing format %s in pass-through mode\n", 732 xlate++;
724 icd->formats[idx].name); 733 dev_dbg(dev, "Providing format %x in pass-through mode\n",
725 } 734 xlate->host_fmt->fourcc);
726 } 735 }
727 736
728 return formats; 737 return formats;
@@ -806,8 +815,7 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
806 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 815 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
807 struct mx3_camera_dev *mx3_cam = ici->priv; 816 struct mx3_camera_dev *mx3_cam = ici->priv;
808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 817 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
809 struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE}; 818 struct v4l2_mbus_framefmt mf;
810 struct v4l2_pix_format *pix = &f.fmt.pix;
811 int ret; 819 int ret;
812 820
813 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096); 821 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
@@ -818,19 +826,19 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
818 return ret; 826 return ret;
819 827
820 /* The capture device might have changed its output */ 828 /* The capture device might have changed its output */
821 ret = v4l2_subdev_call(sd, video, g_fmt, &f); 829 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
822 if (ret < 0) 830 if (ret < 0)
823 return ret; 831 return ret;
824 832
825 if (pix->width & 7) { 833 if (mf.width & 7) {
826 /* Ouch! We can only handle 8-byte aligned width... */ 834 /* Ouch! We can only handle 8-byte aligned width... */
827 stride_align(&pix->width); 835 stride_align(&mf.width);
828 ret = v4l2_subdev_call(sd, video, s_fmt, &f); 836 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
829 if (ret < 0) 837 if (ret < 0)
830 return ret; 838 return ret;
831 } 839 }
832 840
833 if (pix->width != icd->user_width || pix->height != icd->user_height) { 841 if (mf.width != icd->user_width || mf.height != icd->user_height) {
834 /* 842 /*
835 * We now know pixel formats and can decide upon DMA-channel(s) 843 * We now know pixel formats and can decide upon DMA-channel(s)
836 * So far only direct camera-to-memory is supported 844 * So far only direct camera-to-memory is supported
@@ -841,14 +849,14 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
841 return ret; 849 return ret;
842 } 850 }
843 851
844 configure_geometry(mx3_cam, pix->width, pix->height); 852 configure_geometry(mx3_cam, mf.width, mf.height);
845 } 853 }
846 854
847 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 855 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
848 pix->width, pix->height); 856 mf.width, mf.height);
849 857
850 icd->user_width = pix->width; 858 icd->user_width = mf.width;
851 icd->user_height = pix->height; 859 icd->user_height = mf.height;
852 860
853 return ret; 861 return ret;
854} 862}
@@ -861,6 +869,7 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
861 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 869 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
862 const struct soc_camera_format_xlate *xlate; 870 const struct soc_camera_format_xlate *xlate;
863 struct v4l2_pix_format *pix = &f->fmt.pix; 871 struct v4l2_pix_format *pix = &f->fmt.pix;
872 struct v4l2_mbus_framefmt mf;
864 int ret; 873 int ret;
865 874
866 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 875 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
@@ -885,11 +894,24 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
885 894
886 configure_geometry(mx3_cam, pix->width, pix->height); 895 configure_geometry(mx3_cam, pix->width, pix->height);
887 896
888 ret = v4l2_subdev_call(sd, video, s_fmt, f); 897 mf.width = pix->width;
889 if (!ret) { 898 mf.height = pix->height;
890 icd->buswidth = xlate->buswidth; 899 mf.field = pix->field;
891 icd->current_fmt = xlate->host_fmt; 900 mf.colorspace = pix->colorspace;
892 } 901 mf.code = xlate->code;
902
903 ret = v4l2_subdev_call(sd, video, s_mbus_fmt, &mf);
904 if (ret < 0)
905 return ret;
906
907 if (mf.code != xlate->code)
908 return -EINVAL;
909
910 pix->width = mf.width;
911 pix->height = mf.height;
912 pix->field = mf.field;
913 pix->colorspace = mf.colorspace;
914 icd->current_fmt = xlate;
893 915
894 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); 916 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
895 917
@@ -902,8 +924,8 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
902 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 924 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
903 const struct soc_camera_format_xlate *xlate; 925 const struct soc_camera_format_xlate *xlate;
904 struct v4l2_pix_format *pix = &f->fmt.pix; 926 struct v4l2_pix_format *pix = &f->fmt.pix;
927 struct v4l2_mbus_framefmt mf;
905 __u32 pixfmt = pix->pixelformat; 928 __u32 pixfmt = pix->pixelformat;
906 enum v4l2_field field;
907 int ret; 929 int ret;
908 930
909 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 931 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
@@ -918,23 +940,37 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
918 if (pix->width > 4096) 940 if (pix->width > 4096)
919 pix->width = 4096; 941 pix->width = 4096;
920 942
921 pix->bytesperline = pix->width * 943 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
922 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 944 xlate->host_fmt);
945 if (pix->bytesperline < 0)
946 return pix->bytesperline;
923 pix->sizeimage = pix->height * pix->bytesperline; 947 pix->sizeimage = pix->height * pix->bytesperline;
924 948
925 /* camera has to see its format, but the user the original one */
926 pix->pixelformat = xlate->cam_fmt->fourcc;
927 /* limit to sensor capabilities */ 949 /* limit to sensor capabilities */
928 ret = v4l2_subdev_call(sd, video, try_fmt, f); 950 mf.width = pix->width;
929 pix->pixelformat = xlate->host_fmt->fourcc; 951 mf.height = pix->height;
952 mf.field = pix->field;
953 mf.colorspace = pix->colorspace;
954 mf.code = xlate->code;
930 955
931 field = pix->field; 956 ret = v4l2_subdev_call(sd, video, try_mbus_fmt, &mf);
957 if (ret < 0)
958 return ret;
932 959
933 if (field == V4L2_FIELD_ANY) { 960 pix->width = mf.width;
961 pix->height = mf.height;
962 pix->colorspace = mf.colorspace;
963
964 switch (mf.field) {
965 case V4L2_FIELD_ANY:
934 pix->field = V4L2_FIELD_NONE; 966 pix->field = V4L2_FIELD_NONE;
935 } else if (field != V4L2_FIELD_NONE) { 967 break;
936 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field); 968 case V4L2_FIELD_NONE:
937 return -EINVAL; 969 break;
970 default:
971 dev_err(icd->dev.parent, "Field type %d unsupported.\n",
972 mf.field);
973 ret = -EINVAL;
938 } 974 }
939 975
940 return ret; 976 return ret;
@@ -970,18 +1006,26 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
970 struct mx3_camera_dev *mx3_cam = ici->priv; 1006 struct mx3_camera_dev *mx3_cam = ici->priv;
971 unsigned long bus_flags, camera_flags, common_flags; 1007 unsigned long bus_flags, camera_flags, common_flags;
972 u32 dw, sens_conf; 1008 u32 dw, sens_conf;
973 int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); 1009 const struct soc_mbus_pixelfmt *fmt;
1010 int buswidth;
1011 int ret;
974 const struct soc_camera_format_xlate *xlate; 1012 const struct soc_camera_format_xlate *xlate;
975 struct device *dev = icd->dev.parent; 1013 struct device *dev = icd->dev.parent;
976 1014
1015 fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
1016 if (!fmt)
1017 return -EINVAL;
1018
1019 buswidth = fmt->bits_per_sample;
1020 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1021
977 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1022 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
978 if (!xlate) { 1023 if (!xlate) {
979 dev_warn(dev, "Format %x not found\n", pixfmt); 1024 dev_warn(dev, "Format %x not found\n", pixfmt);
980 return -EINVAL; 1025 return -EINVAL;
981 } 1026 }
982 1027
983 dev_dbg(dev, "requested bus width %d bit: %d\n", 1028 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
984 icd->buswidth, ret);
985 1029
986 if (ret < 0) 1030 if (ret < 0)
987 return ret; 1031 return ret;
@@ -1082,7 +1126,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1082 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; 1126 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1083 1127
1084 /* Just do what we're asked to do */ 1128 /* Just do what we're asked to do */
1085 switch (xlate->host_fmt->depth) { 1129 switch (xlate->host_fmt->bits_per_sample) {
1086 case 4: 1130 case 4:
1087 dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; 1131 dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
1088 break; 1132 break;