diff options
Diffstat (limited to 'drivers/media/video/sh_mobile_ceu_camera.c')
-rw-r--r-- | drivers/media/video/sh_mobile_ceu_camera.c | 207 |
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 { | |||
96 | struct sh_mobile_ceu_dev { | 96 | struct 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) | |||
384 | static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb) | 385 | static 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) | |||
409 | static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) | 410 | static 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) | |||
437 | static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q) | 442 | static 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 | ||
507 | static 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 */ |
503 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | 522 | static 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 */ |
526 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | 554 | static 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 */ |
586 | static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) | 616 | static 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) | |||
697 | static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, | 727 | static 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, | |||
843 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, | 873 | static 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, | |||
1555 | static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, | 1585 | static 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, | |||
1848 | static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, | 1872 | static 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, | |||
1864 | static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd, | 1888 | static 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 | ||
2126 | exit_pdev_unregister: | ||
2127 | platform_device_del(pcdev->csi2_pdev); | ||
2128 | exit_pdev_put: | ||
2129 | pcdev->csi2_pdev->resource = NULL; | ||
2130 | platform_device_put(pcdev->csi2_pdev); | ||
2131 | exit_host_unregister: | ||
2132 | soc_camera_host_unregister(&pcdev->ici); | ||
2077 | exit_free_ctx: | 2133 | exit_free_ctx: |
2078 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); | 2134 | vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); |
2079 | exit_module_put: | ||
2080 | if (csi2 && csi2->driver) | ||
2081 | module_put(csi2->driver->owner); | ||
2082 | exit_free_clk: | 2135 | exit_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); | |||
2158 | MODULE_DESCRIPTION("SuperH Mobile CEU driver"); | 2216 | MODULE_DESCRIPTION("SuperH Mobile CEU driver"); |
2159 | MODULE_AUTHOR("Magnus Damm"); | 2217 | MODULE_AUTHOR("Magnus Damm"); |
2160 | MODULE_LICENSE("GPL"); | 2218 | MODULE_LICENSE("GPL"); |
2219 | MODULE_VERSION("0.0.6"); | ||
2161 | MODULE_ALIAS("platform:sh_mobile_ceu"); | 2220 | MODULE_ALIAS("platform:sh_mobile_ceu"); |