aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/sh_mobile_ceu_camera.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/sh_mobile_ceu_camera.c')
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c207
1 files changed, 133 insertions, 74 deletions
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 3ae5c9c58cb..e54089802b6 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -27,7 +27,6 @@
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/version.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/device.h> 31#include <linux/device.h>
33#include <linux/platform_device.h> 32#include <linux/platform_device.h>
@@ -39,6 +38,7 @@
39#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
40#include <media/soc_camera.h> 39#include <media/soc_camera.h>
41#include <media/sh_mobile_ceu.h> 40#include <media/sh_mobile_ceu.h>
41#include <media/sh_mobile_csi2.h>
42#include <media/videobuf2-dma-contig.h> 42#include <media/videobuf2-dma-contig.h>
43#include <media/v4l2-mediabus.h> 43#include <media/v4l2-mediabus.h>
44#include <media/soc_mediabus.h> 44#include <media/soc_mediabus.h>
@@ -96,6 +96,7 @@ struct sh_mobile_ceu_buffer {
96struct sh_mobile_ceu_dev { 96struct sh_mobile_ceu_dev {
97 struct soc_camera_host ici; 97 struct soc_camera_host ici;
98 struct soc_camera_device *icd; 98 struct soc_camera_device *icd;
99 struct platform_device *csi2_pdev;
99 100
100 unsigned int irq; 101 unsigned int irq;
101 void __iomem *base; 102 void __iomem *base;
@@ -205,7 +206,7 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
205 206
206 207
207 if (2 != success) { 208 if (2 != success) {
208 dev_warn(&icd->dev, "soft reset time out\n"); 209 dev_warn(icd->pdev, "soft reset time out\n");
209 return -EIO; 210 return -EIO;
210 } 211 }
211 212
@@ -220,7 +221,7 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
220 unsigned long sizes[], void *alloc_ctxs[]) 221 unsigned long sizes[], void *alloc_ctxs[])
221{ 222{
222 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq); 223 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
223 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 224 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
224 struct sh_mobile_ceu_dev *pcdev = ici->priv; 225 struct sh_mobile_ceu_dev *pcdev = ici->priv;
225 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 226 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
226 icd->current_fmt->host_fmt); 227 icd->current_fmt->host_fmt);
@@ -242,7 +243,7 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
242 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]); 243 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]);
243 } 244 }
244 245
245 dev_dbg(icd->dev.parent, "count=%d, size=%lu\n", *count, sizes[0]); 246 dev_dbg(icd->parent, "count=%d, size=%lu\n", *count, sizes[0]);
246 247
247 return 0; 248 return 0;
248} 249}
@@ -351,7 +352,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
351 352
352 buf = to_ceu_vb(vb); 353 buf = to_ceu_vb(vb);
353 354
354 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 355 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
355 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 356 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
356 357
357 /* Added list head initialization on alloc */ 358 /* Added list head initialization on alloc */
@@ -371,7 +372,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
371 size = icd->user_height * bytes_per_line; 372 size = icd->user_height * bytes_per_line;
372 373
373 if (vb2_plane_size(vb, 0) < size) { 374 if (vb2_plane_size(vb, 0) < size) {
374 dev_err(icd->dev.parent, "Buffer too small (%lu < %lu)\n", 375 dev_err(icd->parent, "Buffer too small (%lu < %lu)\n",
375 vb2_plane_size(vb, 0), size); 376 vb2_plane_size(vb, 0), size);
376 return -ENOBUFS; 377 return -ENOBUFS;
377 } 378 }
@@ -384,11 +385,11 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
384static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb) 385static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
385{ 386{
386 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq); 387 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
387 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 388 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
388 struct sh_mobile_ceu_dev *pcdev = ici->priv; 389 struct sh_mobile_ceu_dev *pcdev = ici->priv;
389 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 390 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
390 391
391 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 392 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
392 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 393 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
393 394
394 spin_lock_irq(&pcdev->lock); 395 spin_lock_irq(&pcdev->lock);
@@ -409,7 +410,7 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
409static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) 410static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
410{ 411{
411 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq); 412 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
412 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 413 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
413 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb); 414 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
414 struct sh_mobile_ceu_dev *pcdev = ici->priv; 415 struct sh_mobile_ceu_dev *pcdev = ici->priv;
415 416
@@ -421,8 +422,12 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
421 pcdev->active = NULL; 422 pcdev->active = NULL;
422 } 423 }
423 424
424 /* Doesn't hurt also if the list is empty */ 425 /*
425 list_del_init(&buf->queue); 426 * Doesn't hurt also if the list is empty, but it hurts, if queuing the
427 * buffer failed, and .buf_init() hasn't been called
428 */
429 if (buf->queue.next)
430 list_del_init(&buf->queue);
426 431
427 spin_unlock_irq(&pcdev->lock); 432 spin_unlock_irq(&pcdev->lock);
428} 433}
@@ -437,7 +442,7 @@ static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
437static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q) 442static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
438{ 443{
439 struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq); 444 struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
440 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 445 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
441 struct sh_mobile_ceu_dev *pcdev = ici->priv; 446 struct sh_mobile_ceu_dev *pcdev = ici->priv;
442 struct list_head *buf_head, *tmp; 447 struct list_head *buf_head, *tmp;
443 448
@@ -499,25 +504,48 @@ out:
499 return IRQ_HANDLED; 504 return IRQ_HANDLED;
500} 505}
501 506
507static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev)
508{
509 struct v4l2_subdev *sd;
510
511 if (!pcdev->csi2_pdev)
512 return NULL;
513
514 v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev)
515 if (&pcdev->csi2_pdev->dev == v4l2_get_subdevdata(sd))
516 return sd;
517
518 return NULL;
519}
520
502/* Called with .video_lock held */ 521/* Called with .video_lock held */
503static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) 522static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
504{ 523{
505 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 524 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
506 struct sh_mobile_ceu_dev *pcdev = ici->priv; 525 struct sh_mobile_ceu_dev *pcdev = ici->priv;
526 struct v4l2_subdev *csi2_sd;
507 int ret; 527 int ret;
508 528
509 if (pcdev->icd) 529 if (pcdev->icd)
510 return -EBUSY; 530 return -EBUSY;
511 531
512 dev_info(icd->dev.parent, 532 dev_info(icd->parent,
513 "SuperH Mobile CEU driver attached to camera %d\n", 533 "SuperH Mobile CEU driver attached to camera %d\n",
514 icd->devnum); 534 icd->devnum);
515 535
516 pm_runtime_get_sync(ici->v4l2_dev.dev); 536 pm_runtime_get_sync(ici->v4l2_dev.dev);
517 537
518 ret = sh_mobile_ceu_soft_reset(pcdev); 538 ret = sh_mobile_ceu_soft_reset(pcdev);
519 if (!ret) 539
540 csi2_sd = find_csi2(pcdev);
541
542 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
543 if (ret != -ENODEV && ret != -ENOIOCTLCMD && ret < 0) {
544 pm_runtime_put_sync(ici->v4l2_dev.dev);
545 } else {
520 pcdev->icd = icd; 546 pcdev->icd = icd;
547 ret = 0;
548 }
521 549
522 return ret; 550 return ret;
523} 551}
@@ -525,11 +553,13 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
525/* Called with .video_lock held */ 553/* Called with .video_lock held */
526static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) 554static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
527{ 555{
528 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 556 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
529 struct sh_mobile_ceu_dev *pcdev = ici->priv; 557 struct sh_mobile_ceu_dev *pcdev = ici->priv;
558 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
530 559
531 BUG_ON(icd != pcdev->icd); 560 BUG_ON(icd != pcdev->icd);
532 561
562 v4l2_subdev_call(csi2_sd, core, s_power, 0);
533 /* disable capture, disable interrupts */ 563 /* disable capture, disable interrupts */
534 ceu_write(pcdev, CEIER, 0); 564 ceu_write(pcdev, CEIER, 0);
535 sh_mobile_ceu_soft_reset(pcdev); 565 sh_mobile_ceu_soft_reset(pcdev);
@@ -545,7 +575,7 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
545 575
546 pm_runtime_put_sync(ici->v4l2_dev.dev); 576 pm_runtime_put_sync(ici->v4l2_dev.dev);
547 577
548 dev_info(icd->dev.parent, 578 dev_info(icd->parent,
549 "SuperH Mobile CEU driver detached from camera %d\n", 579 "SuperH Mobile CEU driver detached from camera %d\n",
550 icd->devnum); 580 icd->devnum);
551 581
@@ -585,14 +615,14 @@ static u16 calc_scale(unsigned int src, unsigned int *dst)
585/* rect is guaranteed to not exceed the scaled camera rectangle */ 615/* rect is guaranteed to not exceed the scaled camera rectangle */
586static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) 616static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
587{ 617{
588 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 618 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
589 struct sh_mobile_ceu_cam *cam = icd->host_priv; 619 struct sh_mobile_ceu_cam *cam = icd->host_priv;
590 struct sh_mobile_ceu_dev *pcdev = ici->priv; 620 struct sh_mobile_ceu_dev *pcdev = ici->priv;
591 unsigned int height, width, cdwdr_width, in_width, in_height; 621 unsigned int height, width, cdwdr_width, in_width, in_height;
592 unsigned int left_offset, top_offset; 622 unsigned int left_offset, top_offset;
593 u32 camor; 623 u32 camor;
594 624
595 dev_geo(icd->dev.parent, "Crop %ux%u@%u:%u\n", 625 dev_geo(icd->parent, "Crop %ux%u@%u:%u\n",
596 icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top); 626 icd->user_width, icd->user_height, cam->ceu_left, cam->ceu_top);
597 627
598 left_offset = cam->ceu_left; 628 left_offset = cam->ceu_left;
@@ -641,7 +671,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
641 } 671 }
642 672
643 /* CSI2 special configuration */ 673 /* CSI2 special configuration */
644 if (pcdev->pdata->csi2_dev) { 674 if (pcdev->pdata->csi2) {
645 in_width = ((in_width - 2) * 2); 675 in_width = ((in_width - 2) * 2);
646 left_offset *= 2; 676 left_offset *= 2;
647 } 677 }
@@ -649,7 +679,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
649 /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ 679 /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
650 camor = left_offset | (top_offset << 16); 680 camor = left_offset | (top_offset << 16);
651 681
652 dev_geo(icd->dev.parent, 682 dev_geo(icd->parent,
653 "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor, 683 "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
654 (in_height << 16) | in_width, (height << 16) | width, 684 (in_height << 16) | in_width, (height << 16) | width,
655 cdwdr_width); 685 cdwdr_width);
@@ -697,7 +727,7 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
697static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 727static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
698 __u32 pixfmt) 728 __u32 pixfmt)
699{ 729{
700 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 730 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
701 struct sh_mobile_ceu_dev *pcdev = ici->priv; 731 struct sh_mobile_ceu_dev *pcdev = ici->priv;
702 int ret; 732 int ret;
703 unsigned long camera_flags, common_flags, value; 733 unsigned long camera_flags, common_flags, value;
@@ -783,7 +813,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
783 value |= pcdev->is_16bit ? 1 << 12 : 0; 813 value |= pcdev->is_16bit ? 1 << 12 : 0;
784 814
785 /* CSI2 mode */ 815 /* CSI2 mode */
786 if (pcdev->pdata->csi2_dev) 816 if (pcdev->pdata->csi2)
787 value |= 3 << 12; 817 value |= 3 << 12;
788 818
789 ceu_write(pcdev, CAMCR, value); 819 ceu_write(pcdev, CAMCR, value);
@@ -806,7 +836,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
806 sh_mobile_ceu_set_rect(icd); 836 sh_mobile_ceu_set_rect(icd);
807 mdelay(1); 837 mdelay(1);
808 838
809 dev_geo(icd->dev.parent, "CFLCR 0x%x\n", pcdev->cflcr); 839 dev_geo(icd->parent, "CFLCR 0x%x\n", pcdev->cflcr);
810 ceu_write(pcdev, CFLCR, pcdev->cflcr); 840 ceu_write(pcdev, CFLCR, pcdev->cflcr);
811 841
812 /* 842 /*
@@ -829,7 +859,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
829 ceu_write(pcdev, CDOCR, value); 859 ceu_write(pcdev, CDOCR, value);
830 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 860 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
831 861
832 dev_dbg(icd->dev.parent, "S_FMT successful for %c%c%c%c %ux%u\n", 862 dev_dbg(icd->parent, "S_FMT successful for %c%c%c%c %ux%u\n",
833 pixfmt & 0xff, (pixfmt >> 8) & 0xff, 863 pixfmt & 0xff, (pixfmt >> 8) & 0xff,
834 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff, 864 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
835 icd->user_width, icd->user_height); 865 icd->user_width, icd->user_height);
@@ -843,7 +873,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
843static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, 873static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
844 unsigned char buswidth) 874 unsigned char buswidth)
845{ 875{
846 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 876 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
847 struct sh_mobile_ceu_dev *pcdev = ici->priv; 877 struct sh_mobile_ceu_dev *pcdev = ici->priv;
848 unsigned long camera_flags, common_flags; 878 unsigned long camera_flags, common_flags;
849 879
@@ -901,7 +931,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
901 struct soc_camera_format_xlate *xlate) 931 struct soc_camera_format_xlate *xlate)
902{ 932{
903 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 933 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
904 struct device *dev = icd->dev.parent; 934 struct device *dev = icd->parent;
905 struct soc_camera_host *ici = to_soc_camera_host(dev); 935 struct soc_camera_host *ici = to_soc_camera_host(dev);
906 struct sh_mobile_ceu_dev *pcdev = ici->priv; 936 struct sh_mobile_ceu_dev *pcdev = ici->priv;
907 int ret, k, n; 937 int ret, k, n;
@@ -921,7 +951,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
921 return 0; 951 return 0;
922 } 952 }
923 953
924 if (!pcdev->pdata->csi2_dev) { 954 if (!pcdev->pdata->csi2) {
925 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); 955 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
926 if (ret < 0) 956 if (ret < 0)
927 return 0; 957 return 0;
@@ -1244,7 +1274,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
1244{ 1274{
1245 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1275 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1246 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1276 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1247 struct device *dev = icd->dev.parent; 1277 struct device *dev = icd->parent;
1248 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 1278 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
1249 unsigned int max_width, max_height; 1279 unsigned int max_width, max_height;
1250 struct v4l2_cropcap cap; 1280 struct v4l2_cropcap cap;
@@ -1313,7 +1343,7 @@ static int client_scale(struct soc_camera_device *icd,
1313 bool ceu_can_scale) 1343 bool ceu_can_scale)
1314{ 1344{
1315 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1345 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1316 struct device *dev = icd->dev.parent; 1346 struct device *dev = icd->parent;
1317 struct v4l2_mbus_framefmt mf_tmp = *mf; 1347 struct v4l2_mbus_framefmt mf_tmp = *mf;
1318 unsigned int scale_h, scale_v; 1348 unsigned int scale_h, scale_v;
1319 int ret; 1349 int ret;
@@ -1363,13 +1393,13 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1363 struct v4l2_crop *a) 1393 struct v4l2_crop *a)
1364{ 1394{
1365 struct v4l2_rect *rect = &a->c; 1395 struct v4l2_rect *rect = &a->c;
1366 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1396 struct device *dev = icd->parent;
1397 struct soc_camera_host *ici = to_soc_camera_host(dev);
1367 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1398 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1368 struct v4l2_crop cam_crop; 1399 struct v4l2_crop cam_crop;
1369 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1400 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1370 struct v4l2_rect *cam_rect = &cam_crop.c; 1401 struct v4l2_rect *cam_rect = &cam_crop.c;
1371 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1402 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1372 struct device *dev = icd->dev.parent;
1373 struct v4l2_mbus_framefmt mf; 1403 struct v4l2_mbus_framefmt mf;
1374 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v, 1404 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1375 out_width, out_height; 1405 out_width, out_height;
@@ -1511,7 +1541,7 @@ static void calculate_client_output(struct soc_camera_device *icd,
1511 struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf) 1541 struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1512{ 1542{
1513 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1543 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1514 struct device *dev = icd->dev.parent; 1544 struct device *dev = icd->parent;
1515 struct v4l2_rect *cam_subrect = &cam->subrect; 1545 struct v4l2_rect *cam_subrect = &cam->subrect;
1516 unsigned int scale_v, scale_h; 1546 unsigned int scale_v, scale_h;
1517 1547
@@ -1555,12 +1585,12 @@ static void calculate_client_output(struct soc_camera_device *icd,
1555static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, 1585static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1556 struct v4l2_format *f) 1586 struct v4l2_format *f)
1557{ 1587{
1558 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1588 struct device *dev = icd->parent;
1589 struct soc_camera_host *ici = to_soc_camera_host(dev);
1559 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1590 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1560 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1591 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1561 struct v4l2_pix_format *pix = &f->fmt.pix; 1592 struct v4l2_pix_format *pix = &f->fmt.pix;
1562 struct v4l2_mbus_framefmt mf; 1593 struct v4l2_mbus_framefmt mf;
1563 struct device *dev = icd->dev.parent;
1564 __u32 pixfmt = pix->pixelformat; 1594 __u32 pixfmt = pix->pixelformat;
1565 const struct soc_camera_format_xlate *xlate; 1595 const struct soc_camera_format_xlate *xlate;
1566 /* Keep Compiler Happy */ 1596 /* Keep Compiler Happy */
@@ -1684,12 +1714,12 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1684 int width, height; 1714 int width, height;
1685 int ret; 1715 int ret;
1686 1716
1687 dev_geo(icd->dev.parent, "TRY_FMT(pix=0x%x, %ux%u)\n", 1717 dev_geo(icd->parent, "TRY_FMT(pix=0x%x, %ux%u)\n",
1688 pixfmt, pix->width, pix->height); 1718 pixfmt, pix->width, pix->height);
1689 1719
1690 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1720 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1691 if (!xlate) { 1721 if (!xlate) {
1692 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt); 1722 dev_warn(icd->parent, "Format %x not found\n", pixfmt);
1693 return -EINVAL; 1723 return -EINVAL;
1694 } 1724 }
1695 1725
@@ -1701,11 +1731,6 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1701 width = pix->width; 1731 width = pix->width;
1702 height = pix->height; 1732 height = pix->height;
1703 1733
1704 pix->bytesperline = soc_mbus_bytes_per_line(width, xlate->host_fmt);
1705 if ((int)pix->bytesperline < 0)
1706 return pix->bytesperline;
1707 pix->sizeimage = height * pix->bytesperline;
1708
1709 /* limit to sensor capabilities */ 1734 /* limit to sensor capabilities */
1710 mf.width = pix->width; 1735 mf.width = pix->width;
1711 mf.height = pix->height; 1736 mf.height = pix->height;
@@ -1741,7 +1766,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1741 try_mbus_fmt, &mf); 1766 try_mbus_fmt, &mf);
1742 if (ret < 0) { 1767 if (ret < 0) {
1743 /* Shouldn't actually happen... */ 1768 /* Shouldn't actually happen... */
1744 dev_err(icd->dev.parent, 1769 dev_err(icd->parent,
1745 "FIXME: client try_fmt() = %d\n", ret); 1770 "FIXME: client try_fmt() = %d\n", ret);
1746 return ret; 1771 return ret;
1747 } 1772 }
@@ -1753,7 +1778,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1753 pix->height = height; 1778 pix->height = height;
1754 } 1779 }
1755 1780
1756 dev_geo(icd->dev.parent, "%s(): return %d, fmt 0x%x, %ux%u\n", 1781 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1757 __func__, ret, pix->pixelformat, pix->width, pix->height); 1782 __func__, ret, pix->pixelformat, pix->width, pix->height);
1758 1783
1759 return ret; 1784 return ret;
@@ -1763,7 +1788,7 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1763 struct v4l2_crop *a) 1788 struct v4l2_crop *a)
1764{ 1789{
1765 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1790 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1766 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1791 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1767 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1792 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1768 u32 out_width = icd->user_width, out_height = icd->user_height; 1793 u32 out_width = icd->user_width, out_height = icd->user_height;
1769 int ret; 1794 int ret;
@@ -1775,13 +1800,13 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1775 /* Stop the client */ 1800 /* Stop the client */
1776 ret = v4l2_subdev_call(sd, video, s_stream, 0); 1801 ret = v4l2_subdev_call(sd, video, s_stream, 0);
1777 if (ret < 0) 1802 if (ret < 0)
1778 dev_warn(icd->dev.parent, 1803 dev_warn(icd->parent,
1779 "Client failed to stop the stream: %d\n", ret); 1804 "Client failed to stop the stream: %d\n", ret);
1780 else 1805 else
1781 /* Do the crop, if it fails, there's nothing more we can do */ 1806 /* Do the crop, if it fails, there's nothing more we can do */
1782 sh_mobile_ceu_set_crop(icd, a); 1807 sh_mobile_ceu_set_crop(icd, a);
1783 1808
1784 dev_geo(icd->dev.parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height); 1809 dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
1785 1810
1786 if (icd->user_width != out_width || icd->user_height != out_height) { 1811 if (icd->user_width != out_width || icd->user_height != out_height) {
1787 struct v4l2_format f = { 1812 struct v4l2_format f = {
@@ -1827,7 +1852,6 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
1827 struct v4l2_capability *cap) 1852 struct v4l2_capability *cap)
1828{ 1853{
1829 strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); 1854 strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
1830 cap->version = KERNEL_VERSION(0, 0, 5);
1831 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 1855 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1832 return 0; 1856 return 0;
1833} 1857}
@@ -1848,7 +1872,7 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
1848static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, 1872static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1849 struct v4l2_control *ctrl) 1873 struct v4l2_control *ctrl)
1850{ 1874{
1851 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1875 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1852 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1876 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1853 u32 val; 1877 u32 val;
1854 1878
@@ -1864,7 +1888,7 @@ static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1864static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd, 1888static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1865 struct v4l2_control *ctrl) 1889 struct v4l2_control *ctrl)
1866{ 1890{
1867 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1891 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1868 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1892 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1869 1893
1870 switch (ctrl->id) { 1894 switch (ctrl->id) {
@@ -1950,7 +1974,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
1950 .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), 1974 .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion),
1951 .notifier.notifier_call = bus_notify, 1975 .notifier.notifier_call = bus_notify,
1952 }; 1976 };
1953 struct device *csi2; 1977 struct sh_mobile_ceu_companion *csi2;
1954 1978
1955 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1979 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1956 irq = platform_get_irq(pdev, 0); 1980 irq = platform_get_irq(pdev, 0);
@@ -2023,26 +2047,61 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2023 pcdev->ici.drv_name = dev_name(&pdev->dev); 2047 pcdev->ici.drv_name = dev_name(&pdev->dev);
2024 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 2048 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
2025 2049
2050 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2051 if (IS_ERR(pcdev->alloc_ctx)) {
2052 err = PTR_ERR(pcdev->alloc_ctx);
2053 goto exit_free_clk;
2054 }
2055
2056 err = soc_camera_host_register(&pcdev->ici);
2057 if (err)
2058 goto exit_free_ctx;
2059
2026 /* CSI2 interfacing */ 2060 /* CSI2 interfacing */
2027 csi2 = pcdev->pdata->csi2_dev; 2061 csi2 = pcdev->pdata->csi2;
2028 if (csi2) { 2062 if (csi2) {
2029 wait.dev = csi2; 2063 struct platform_device *csi2_pdev =
2064 platform_device_alloc("sh-mobile-csi2", csi2->id);
2065 struct sh_csi2_pdata *csi2_pdata = csi2->platform_data;
2066
2067 if (!csi2_pdev) {
2068 err = -ENOMEM;
2069 goto exit_host_unregister;
2070 }
2071
2072 pcdev->csi2_pdev = csi2_pdev;
2073
2074 err = platform_device_add_data(csi2_pdev, csi2_pdata, sizeof(*csi2_pdata));
2075 if (err < 0)
2076 goto exit_pdev_put;
2077
2078 csi2_pdata = csi2_pdev->dev.platform_data;
2079 csi2_pdata->v4l2_dev = &pcdev->ici.v4l2_dev;
2080
2081 csi2_pdev->resource = csi2->resource;
2082 csi2_pdev->num_resources = csi2->num_resources;
2083
2084 err = platform_device_add(csi2_pdev);
2085 if (err < 0)
2086 goto exit_pdev_put;
2087
2088 wait.dev = &csi2_pdev->dev;
2030 2089
2031 err = bus_register_notifier(&platform_bus_type, &wait.notifier); 2090 err = bus_register_notifier(&platform_bus_type, &wait.notifier);
2032 if (err < 0) 2091 if (err < 0)
2033 goto exit_free_clk; 2092 goto exit_pdev_unregister;
2034 2093
2035 /* 2094 /*
2036 * From this point the driver module will not unload, until 2095 * From this point the driver module will not unload, until
2037 * we complete the completion. 2096 * we complete the completion.
2038 */ 2097 */
2039 2098
2040 if (!csi2->driver) { 2099 if (!csi2_pdev->dev.driver) {
2041 complete(&wait.completion); 2100 complete(&wait.completion);
2042 /* Either too late, or probing failed */ 2101 /* Either too late, or probing failed */
2043 bus_unregister_notifier(&platform_bus_type, &wait.notifier); 2102 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2044 err = -ENXIO; 2103 err = -ENXIO;
2045 goto exit_free_clk; 2104 goto exit_pdev_unregister;
2046 } 2105 }
2047 2106
2048 /* 2107 /*
@@ -2051,34 +2110,28 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2051 * the "owner" is safe! 2110 * the "owner" is safe!
2052 */ 2111 */
2053 2112
2054 err = try_module_get(csi2->driver->owner); 2113 err = try_module_get(csi2_pdev->dev.driver->owner);
2055 2114
2056 /* Let notifier complete, if it has been locked */ 2115 /* Let notifier complete, if it has been locked */
2057 complete(&wait.completion); 2116 complete(&wait.completion);
2058 bus_unregister_notifier(&platform_bus_type, &wait.notifier); 2117 bus_unregister_notifier(&platform_bus_type, &wait.notifier);
2059 if (!err) { 2118 if (!err) {
2060 err = -ENODEV; 2119 err = -ENODEV;
2061 goto exit_free_clk; 2120 goto exit_pdev_unregister;
2062 } 2121 }
2063 } 2122 }
2064 2123
2065 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2066 if (IS_ERR(pcdev->alloc_ctx)) {
2067 err = PTR_ERR(pcdev->alloc_ctx);
2068 goto exit_module_put;
2069 }
2070
2071 err = soc_camera_host_register(&pcdev->ici);
2072 if (err)
2073 goto exit_free_ctx;
2074
2075 return 0; 2124 return 0;
2076 2125
2126exit_pdev_unregister:
2127 platform_device_del(pcdev->csi2_pdev);
2128exit_pdev_put:
2129 pcdev->csi2_pdev->resource = NULL;
2130 platform_device_put(pcdev->csi2_pdev);
2131exit_host_unregister:
2132 soc_camera_host_unregister(&pcdev->ici);
2077exit_free_ctx: 2133exit_free_ctx:
2078 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 2134 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2079exit_module_put:
2080 if (csi2 && csi2->driver)
2081 module_put(csi2->driver->owner);
2082exit_free_clk: 2135exit_free_clk:
2083 pm_runtime_disable(&pdev->dev); 2136 pm_runtime_disable(&pdev->dev);
2084 free_irq(pcdev->irq, pcdev); 2137 free_irq(pcdev->irq, pcdev);
@@ -2098,7 +2151,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2098 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); 2151 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
2099 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, 2152 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
2100 struct sh_mobile_ceu_dev, ici); 2153 struct sh_mobile_ceu_dev, ici);
2101 struct device *csi2 = pcdev->pdata->csi2_dev; 2154 struct platform_device *csi2_pdev = pcdev->csi2_pdev;
2102 2155
2103 soc_camera_host_unregister(soc_host); 2156 soc_camera_host_unregister(soc_host);
2104 pm_runtime_disable(&pdev->dev); 2157 pm_runtime_disable(&pdev->dev);
@@ -2107,8 +2160,13 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2107 dma_release_declared_memory(&pdev->dev); 2160 dma_release_declared_memory(&pdev->dev);
2108 iounmap(pcdev->base); 2161 iounmap(pcdev->base);
2109 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 2162 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2110 if (csi2 && csi2->driver) 2163 if (csi2_pdev && csi2_pdev->dev.driver) {
2111 module_put(csi2->driver->owner); 2164 struct module *csi2_drv = csi2_pdev->dev.driver->owner;
2165 platform_device_del(csi2_pdev);
2166 csi2_pdev->resource = NULL;
2167 platform_device_put(csi2_pdev);
2168 module_put(csi2_drv);
2169 }
2112 kfree(pcdev); 2170 kfree(pcdev);
2113 2171
2114 return 0; 2172 return 0;
@@ -2158,4 +2216,5 @@ module_exit(sh_mobile_ceu_exit);
2158MODULE_DESCRIPTION("SuperH Mobile CEU driver"); 2216MODULE_DESCRIPTION("SuperH Mobile CEU driver");
2159MODULE_AUTHOR("Magnus Damm"); 2217MODULE_AUTHOR("Magnus Damm");
2160MODULE_LICENSE("GPL"); 2218MODULE_LICENSE("GPL");
2219MODULE_VERSION("0.0.6");
2161MODULE_ALIAS("platform:sh_mobile_ceu"); 2220MODULE_ALIAS("platform:sh_mobile_ceu");