diff options
| -rw-r--r-- | drivers/media/platform/soc_camera/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/media/platform/soc_camera/Makefile | 1 | ||||
| -rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 229 | ||||
| -rw-r--r-- | drivers/media/platform/soc_camera/sh_mobile_csi2.c | 400 | ||||
| -rw-r--r-- | include/media/drv-intf/sh_mobile_ceu.h | 1 | ||||
| -rw-r--r-- | include/media/drv-intf/sh_mobile_csi2.h | 48 |
6 files changed, 10 insertions, 676 deletions
diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index 39f66414f621..99cf471a5fc0 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig | |||
| @@ -35,13 +35,6 @@ config VIDEO_RCAR_VIN_OLD | |||
| 35 | ---help--- | 35 | ---help--- |
| 36 | This is a v4l2 driver for the R-Car VIN Interface | 36 | This is a v4l2 driver for the R-Car VIN Interface |
| 37 | 37 | ||
| 38 | config VIDEO_SH_MOBILE_CSI2 | ||
| 39 | tristate "SuperH Mobile MIPI CSI-2 Interface driver" | ||
| 40 | depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK | ||
| 41 | depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST | ||
| 42 | ---help--- | ||
| 43 | This is a v4l2 driver for the SuperH MIPI CSI-2 Interface | ||
| 44 | |||
| 45 | config VIDEO_SH_MOBILE_CEU | 38 | config VIDEO_SH_MOBILE_CEU |
| 46 | tristate "SuperH Mobile CEU Interface driver" | 39 | tristate "SuperH Mobile CEU Interface driver" |
| 47 | depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK | 40 | depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK |
diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile index 7703cb7ce456..ee8f9a4ae2a4 100644 --- a/drivers/media/platform/soc_camera/Makefile +++ b/drivers/media/platform/soc_camera/Makefile | |||
| @@ -9,5 +9,4 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | |||
| 9 | obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o | 9 | obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o |
| 10 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o | 10 | obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o |
| 11 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o | 11 | obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o |
| 12 | obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o | ||
| 13 | obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o | 12 | obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o |
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 02b519dde42a..05eafe3a421e 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include <media/v4l2-dev.h> | 41 | #include <media/v4l2-dev.h> |
| 42 | #include <media/soc_camera.h> | 42 | #include <media/soc_camera.h> |
| 43 | #include <media/drv-intf/sh_mobile_ceu.h> | 43 | #include <media/drv-intf/sh_mobile_ceu.h> |
| 44 | #include <media/drv-intf/sh_mobile_csi2.h> | ||
| 45 | #include <media/videobuf2-dma-contig.h> | 44 | #include <media/videobuf2-dma-contig.h> |
| 46 | #include <media/v4l2-mediabus.h> | 45 | #include <media/v4l2-mediabus.h> |
| 47 | #include <media/drv-intf/soc_mediabus.h> | 46 | #include <media/drv-intf/soc_mediabus.h> |
| @@ -99,11 +98,6 @@ struct sh_mobile_ceu_buffer { | |||
| 99 | 98 | ||
| 100 | struct sh_mobile_ceu_dev { | 99 | struct sh_mobile_ceu_dev { |
| 101 | struct soc_camera_host ici; | 100 | struct soc_camera_host ici; |
| 102 | /* Asynchronous CSI2 linking */ | ||
| 103 | struct v4l2_async_subdev *csi2_asd; | ||
| 104 | struct v4l2_subdev *csi2_sd; | ||
| 105 | /* Synchronous probing compatibility */ | ||
| 106 | struct platform_device *csi2_pdev; | ||
| 107 | 101 | ||
| 108 | unsigned int irq; | 102 | unsigned int irq; |
| 109 | void __iomem *base; | 103 | void __iomem *base; |
| @@ -517,74 +511,20 @@ out: | |||
| 517 | return IRQ_HANDLED; | 511 | return IRQ_HANDLED; |
| 518 | } | 512 | } |
| 519 | 513 | ||
| 520 | static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) | ||
| 521 | { | ||
| 522 | struct v4l2_subdev *sd; | ||
| 523 | |||
| 524 | if (pcdev->csi2_sd) | ||
| 525 | return pcdev->csi2_sd; | ||
| 526 | |||
| 527 | if (pcdev->csi2_asd) { | ||
| 528 | char name[] = "sh-mobile-csi2"; | ||
| 529 | v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) | ||
| 530 | if (!strncmp(name, sd->name, sizeof(name) - 1)) { | ||
| 531 | pcdev->csi2_sd = sd; | ||
| 532 | return sd; | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 536 | return NULL; | ||
| 537 | } | ||
| 538 | |||
| 539 | static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev, | ||
| 540 | struct soc_camera_device *icd) | ||
| 541 | { | ||
| 542 | struct v4l2_subdev *sd = pcdev->csi2_sd; | ||
| 543 | |||
| 544 | return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL; | ||
| 545 | } | ||
| 546 | |||
| 547 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | 514 | static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) |
| 548 | { | 515 | { |
| 549 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | ||
| 550 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
| 551 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); | ||
| 552 | int ret; | ||
| 553 | |||
| 554 | if (csi2_sd) { | ||
| 555 | csi2_sd->grp_id = soc_camera_grp_id(icd); | ||
| 556 | v4l2_set_subdev_hostdata(csi2_sd, icd); | ||
| 557 | } | ||
| 558 | |||
| 559 | ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); | ||
| 560 | if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) | ||
| 561 | return ret; | ||
| 562 | |||
| 563 | /* | ||
| 564 | * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver | ||
| 565 | * has not found this soc-camera device among its clients | ||
| 566 | */ | ||
| 567 | if (csi2_sd && ret == -ENODEV) | ||
| 568 | csi2_sd->grp_id = 0; | ||
| 569 | |||
| 570 | dev_info(icd->parent, | 516 | dev_info(icd->parent, |
| 571 | "SuperH Mobile CEU%s driver attached to camera %d\n", | 517 | "SuperH Mobile CEU driver attached to camera %d\n", |
| 572 | csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum); | 518 | icd->devnum); |
| 573 | 519 | ||
| 574 | return 0; | 520 | return 0; |
| 575 | } | 521 | } |
| 576 | 522 | ||
| 577 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) | 523 | static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) |
| 578 | { | 524 | { |
| 579 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | ||
| 580 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
| 581 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); | ||
| 582 | |||
| 583 | dev_info(icd->parent, | 525 | dev_info(icd->parent, |
| 584 | "SuperH Mobile CEU driver detached from camera %d\n", | 526 | "SuperH Mobile CEU driver detached from camera %d\n", |
| 585 | icd->devnum); | 527 | icd->devnum); |
| 586 | |||
| 587 | v4l2_subdev_call(csi2_sd, core, s_power, 0); | ||
| 588 | } | 528 | } |
| 589 | 529 | ||
| 590 | /* Called with .host_lock held */ | 530 | /* Called with .host_lock held */ |
| @@ -704,12 +644,6 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) | |||
| 704 | cdwdr_width *= 2; | 644 | cdwdr_width *= 2; |
| 705 | } | 645 | } |
| 706 | 646 | ||
| 707 | /* CSI2 special configuration */ | ||
| 708 | if (csi2_subdev(pcdev, icd)) { | ||
| 709 | in_width = ((in_width - 2) * 2); | ||
| 710 | left_offset *= 2; | ||
| 711 | } | ||
| 712 | |||
| 713 | /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ | 647 | /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ |
| 714 | camor = left_offset | (top_offset << 16); | 648 | camor = left_offset | (top_offset << 16); |
| 715 | 649 | ||
| @@ -758,13 +692,6 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr) | |||
| 758 | ceu_write(pcdev, CAPSR, capsr); | 692 | ceu_write(pcdev, CAPSR, capsr); |
| 759 | } | 693 | } |
| 760 | 694 | ||
| 761 | /* Find the bus subdevice driver, e.g., CSI2 */ | ||
| 762 | static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, | ||
| 763 | struct soc_camera_device *icd) | ||
| 764 | { | ||
| 765 | return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd); | ||
| 766 | } | ||
| 767 | |||
| 768 | #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ | 695 | #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ |
| 769 | V4L2_MBUS_PCLK_SAMPLE_RISING | \ | 696 | V4L2_MBUS_PCLK_SAMPLE_RISING | \ |
| 770 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ | 697 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ |
| @@ -778,7 +705,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
| 778 | { | 705 | { |
| 779 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 706 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| 780 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | 707 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
| 781 | struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); | 708 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 782 | struct sh_mobile_ceu_cam *cam = icd->host_priv; | 709 | struct sh_mobile_ceu_cam *cam = icd->host_priv; |
| 783 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; | 710 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
| 784 | unsigned long value, common_flags = CEU_BUS_FLAGS; | 711 | unsigned long value, common_flags = CEU_BUS_FLAGS; |
| @@ -866,9 +793,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
| 866 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; | 793 | value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; |
| 867 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; | 794 | value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; |
| 868 | 795 | ||
| 869 | if (csi2_subdev(pcdev, icd)) /* CSI2 mode */ | 796 | if (pcdev->is_16bit) |
| 870 | value |= 3 << 12; | ||
| 871 | else if (pcdev->is_16bit) | ||
| 872 | value |= 1 << 12; | 797 | value |= 1 << 12; |
| 873 | else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) | 798 | else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) |
| 874 | value |= 2 << 12; | 799 | value |= 2 << 12; |
| @@ -923,9 +848,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) | |||
| 923 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, | 848 | static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, |
| 924 | unsigned char buswidth) | 849 | unsigned char buswidth) |
| 925 | { | 850 | { |
| 926 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); | 851 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 927 | struct sh_mobile_ceu_dev *pcdev = ici->priv; | ||
| 928 | struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); | ||
| 929 | unsigned long common_flags = CEU_BUS_FLAGS; | 852 | unsigned long common_flags = CEU_BUS_FLAGS; |
| 930 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; | 853 | struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; |
| 931 | int ret; | 854 | int ret; |
| @@ -1046,12 +969,9 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int | |||
| 1046 | return 0; | 969 | return 0; |
| 1047 | } | 970 | } |
| 1048 | 971 | ||
| 1049 | if (!csi2_subdev(pcdev, icd)) { | 972 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); |
| 1050 | /* Are there any restrictions in the CSI-2 case? */ | 973 | if (ret < 0) |
| 1051 | ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); | 974 | return 0; |
| 1052 | if (ret < 0) | ||
| 1053 | return 0; | ||
| 1054 | } | ||
| 1055 | 975 | ||
| 1056 | if (!icd->host_priv) { | 976 | if (!icd->host_priv) { |
| 1057 | struct v4l2_subdev_format fmt = { | 977 | struct v4l2_subdev_format fmt = { |
| @@ -1721,12 +1641,11 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
| 1721 | struct resource *res; | 1641 | struct resource *res; |
| 1722 | void __iomem *base; | 1642 | void __iomem *base; |
| 1723 | unsigned int irq; | 1643 | unsigned int irq; |
| 1724 | int err, i; | 1644 | int err; |
| 1725 | struct bus_wait wait = { | 1645 | struct bus_wait wait = { |
| 1726 | .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), | 1646 | .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), |
| 1727 | .notifier.notifier_call = bus_notify, | 1647 | .notifier.notifier_call = bus_notify, |
| 1728 | }; | 1648 | }; |
| 1729 | struct sh_mobile_ceu_companion *csi2; | ||
| 1730 | 1649 | ||
| 1731 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1650 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1732 | irq = platform_get_irq(pdev, 0); | 1651 | irq = platform_get_irq(pdev, 0); |
| @@ -1821,132 +1740,16 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) | |||
| 1821 | pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE; | 1740 | pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE; |
| 1822 | 1741 | ||
| 1823 | if (pcdev->pdata && pcdev->pdata->asd_sizes) { | 1742 | if (pcdev->pdata && pcdev->pdata->asd_sizes) { |
| 1824 | struct v4l2_async_subdev **asd; | ||
| 1825 | char name[] = "sh-mobile-csi2"; | ||
| 1826 | int j; | ||
| 1827 | |||
| 1828 | /* | ||
| 1829 | * CSI2 interfacing: several groups can use CSI2, pick up the | ||
| 1830 | * first one | ||
| 1831 | */ | ||
| 1832 | asd = pcdev->pdata->asd; | ||
| 1833 | for (j = 0; pcdev->pdata->asd_sizes[j]; j++) { | ||
| 1834 | for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) { | ||
| 1835 | dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n", | ||
| 1836 | __func__, i, (*asd)->match_type); | ||
| 1837 | if ((*asd)->match_type == V4L2_ASYNC_MATCH_DEVNAME && | ||
| 1838 | !strncmp(name, (*asd)->match.device_name.name, | ||
| 1839 | sizeof(name) - 1)) { | ||
| 1840 | pcdev->csi2_asd = *asd; | ||
| 1841 | break; | ||
| 1842 | } | ||
| 1843 | } | ||
| 1844 | if (pcdev->csi2_asd) | ||
| 1845 | break; | ||
| 1846 | } | ||
| 1847 | |||
| 1848 | pcdev->ici.asd = pcdev->pdata->asd; | 1743 | pcdev->ici.asd = pcdev->pdata->asd; |
| 1849 | pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes; | 1744 | pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes; |
| 1850 | } | 1745 | } |
| 1851 | 1746 | ||
| 1852 | /* Legacy CSI2 interfacing */ | ||
| 1853 | csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL; | ||
| 1854 | if (csi2) { | ||
| 1855 | /* | ||
| 1856 | * TODO: remove this once all users are converted to | ||
| 1857 | * asynchronous CSI2 probing. If it has to be kept, csi2 | ||
| 1858 | * platform device resources have to be added, using | ||
| 1859 | * platform_device_add_resources() | ||
| 1860 | */ | ||
| 1861 | struct platform_device *csi2_pdev = | ||
| 1862 | platform_device_alloc("sh-mobile-csi2", csi2->id); | ||
| 1863 | struct sh_csi2_pdata *csi2_pdata = csi2->platform_data; | ||
| 1864 | |||
| 1865 | if (!csi2_pdev) { | ||
| 1866 | err = -ENOMEM; | ||
| 1867 | goto exit_free_clk; | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | pcdev->csi2_pdev = csi2_pdev; | ||
| 1871 | |||
| 1872 | err = platform_device_add_data(csi2_pdev, csi2_pdata, | ||
| 1873 | sizeof(*csi2_pdata)); | ||
| 1874 | if (err < 0) | ||
| 1875 | goto exit_pdev_put; | ||
| 1876 | |||
| 1877 | csi2_pdev->resource = csi2->resource; | ||
| 1878 | csi2_pdev->num_resources = csi2->num_resources; | ||
| 1879 | |||
| 1880 | err = platform_device_add(csi2_pdev); | ||
| 1881 | if (err < 0) | ||
| 1882 | goto exit_pdev_put; | ||
| 1883 | |||
| 1884 | wait.dev = &csi2_pdev->dev; | ||
| 1885 | |||
| 1886 | err = bus_register_notifier(&platform_bus_type, &wait.notifier); | ||
| 1887 | if (err < 0) | ||
| 1888 | goto exit_pdev_unregister; | ||
| 1889 | |||
| 1890 | /* | ||
| 1891 | * From this point the driver module will not unload, until | ||
| 1892 | * we complete the completion. | ||
| 1893 | */ | ||
| 1894 | |||
| 1895 | if (!csi2_pdev->dev.driver) { | ||
| 1896 | complete(&wait.completion); | ||
| 1897 | /* Either too late, or probing failed */ | ||
| 1898 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); | ||
| 1899 | err = -ENXIO; | ||
| 1900 | goto exit_pdev_unregister; | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | /* | ||
| 1904 | * The module is still loaded, in the worst case it is hanging | ||
| 1905 | * in device release on our completion. So, _now_ dereferencing | ||
| 1906 | * the "owner" is safe! | ||
| 1907 | */ | ||
| 1908 | |||
| 1909 | err = try_module_get(csi2_pdev->dev.driver->owner); | ||
| 1910 | |||
| 1911 | /* Let notifier complete, if it has been locked */ | ||
| 1912 | complete(&wait.completion); | ||
| 1913 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); | ||
| 1914 | if (!err) { | ||
| 1915 | err = -ENODEV; | ||
| 1916 | goto exit_pdev_unregister; | ||
| 1917 | } | ||
| 1918 | |||
| 1919 | pcdev->csi2_sd = platform_get_drvdata(csi2_pdev); | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | err = soc_camera_host_register(&pcdev->ici); | 1747 | err = soc_camera_host_register(&pcdev->ici); |
| 1923 | if (err) | 1748 | if (err) |
| 1924 | goto exit_csi2_unregister; | 1749 | goto exit_free_clk; |
| 1925 | |||
| 1926 | if (csi2) { | ||
| 1927 | err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev, | ||
| 1928 | pcdev->csi2_sd); | ||
| 1929 | dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n", | ||
| 1930 | __func__, err); | ||
| 1931 | if (err < 0) | ||
| 1932 | goto exit_host_unregister; | ||
| 1933 | /* v4l2_device_register_subdev() took a reference too */ | ||
| 1934 | module_put(pcdev->csi2_sd->owner); | ||
| 1935 | } | ||
| 1936 | 1750 | ||
| 1937 | return 0; | 1751 | return 0; |
| 1938 | 1752 | ||
| 1939 | exit_host_unregister: | ||
| 1940 | soc_camera_host_unregister(&pcdev->ici); | ||
| 1941 | exit_csi2_unregister: | ||
| 1942 | if (csi2) { | ||
| 1943 | module_put(pcdev->csi2_pdev->dev.driver->owner); | ||
| 1944 | exit_pdev_unregister: | ||
| 1945 | platform_device_del(pcdev->csi2_pdev); | ||
| 1946 | exit_pdev_put: | ||
| 1947 | pcdev->csi2_pdev->resource = NULL; | ||
| 1948 | platform_device_put(pcdev->csi2_pdev); | ||
| 1949 | } | ||
| 1950 | exit_free_clk: | 1753 | exit_free_clk: |
| 1951 | pm_runtime_disable(&pdev->dev); | 1754 | pm_runtime_disable(&pdev->dev); |
| 1952 | exit_release_mem: | 1755 | exit_release_mem: |
| @@ -1958,21 +1761,11 @@ exit_release_mem: | |||
| 1958 | static int sh_mobile_ceu_remove(struct platform_device *pdev) | 1761 | static int sh_mobile_ceu_remove(struct platform_device *pdev) |
| 1959 | { | 1762 | { |
| 1960 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); | 1763 | struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); |
| 1961 | struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, | ||
| 1962 | struct sh_mobile_ceu_dev, ici); | ||
| 1963 | struct platform_device *csi2_pdev = pcdev->csi2_pdev; | ||
| 1964 | 1764 | ||
| 1965 | soc_camera_host_unregister(soc_host); | 1765 | soc_camera_host_unregister(soc_host); |
| 1966 | pm_runtime_disable(&pdev->dev); | 1766 | pm_runtime_disable(&pdev->dev); |
| 1967 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1767 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
| 1968 | dma_release_declared_memory(&pdev->dev); | 1768 | dma_release_declared_memory(&pdev->dev); |
| 1969 | if (csi2_pdev && csi2_pdev->dev.driver) { | ||
| 1970 | struct module *csi2_drv = csi2_pdev->dev.driver->owner; | ||
| 1971 | platform_device_del(csi2_pdev); | ||
| 1972 | csi2_pdev->resource = NULL; | ||
| 1973 | platform_device_put(csi2_pdev); | ||
| 1974 | module_put(csi2_drv); | ||
| 1975 | } | ||
| 1976 | 1769 | ||
| 1977 | return 0; | 1770 | return 0; |
| 1978 | } | 1771 | } |
| @@ -2012,8 +1805,6 @@ static struct platform_driver sh_mobile_ceu_driver = { | |||
| 2012 | 1805 | ||
| 2013 | static int __init sh_mobile_ceu_init(void) | 1806 | static int __init sh_mobile_ceu_init(void) |
| 2014 | { | 1807 | { |
| 2015 | /* Whatever return code */ | ||
| 2016 | request_module("sh_mobile_csi2"); | ||
| 2017 | return platform_driver_register(&sh_mobile_ceu_driver); | 1808 | return platform_driver_register(&sh_mobile_ceu_driver); |
| 2018 | } | 1809 | } |
| 2019 | 1810 | ||
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c deleted file mode 100644 index 09b18365a4b1..000000000000 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ /dev/null | |||
| @@ -1,400 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the SH-Mobile MIPI CSI-2 unit | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/delay.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/i2c.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/pm_runtime.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/videodev2.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | |||
| 21 | #include <media/drv-intf/sh_mobile_ceu.h> | ||
| 22 | #include <media/drv-intf/sh_mobile_csi2.h> | ||
| 23 | #include <media/soc_camera.h> | ||
| 24 | #include <media/drv-intf/soc_mediabus.h> | ||
| 25 | #include <media/v4l2-common.h> | ||
| 26 | #include <media/v4l2-dev.h> | ||
| 27 | #include <media/v4l2-device.h> | ||
| 28 | #include <media/v4l2-mediabus.h> | ||
| 29 | #include <media/v4l2-subdev.h> | ||
| 30 | |||
| 31 | #define SH_CSI2_TREF 0x00 | ||
| 32 | #define SH_CSI2_SRST 0x04 | ||
| 33 | #define SH_CSI2_PHYCNT 0x08 | ||
| 34 | #define SH_CSI2_CHKSUM 0x0C | ||
| 35 | #define SH_CSI2_VCDT 0x10 | ||
| 36 | |||
| 37 | struct sh_csi2 { | ||
| 38 | struct v4l2_subdev subdev; | ||
| 39 | unsigned int irq; | ||
| 40 | unsigned long mipi_flags; | ||
| 41 | void __iomem *base; | ||
| 42 | struct platform_device *pdev; | ||
| 43 | struct sh_csi2_client_config *client; | ||
| 44 | }; | ||
| 45 | |||
| 46 | static void sh_csi2_hwinit(struct sh_csi2 *priv); | ||
| 47 | |||
| 48 | static int sh_csi2_set_fmt(struct v4l2_subdev *sd, | ||
| 49 | struct v4l2_subdev_pad_config *cfg, | ||
| 50 | struct v4l2_subdev_format *format) | ||
| 51 | { | ||
| 52 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
| 53 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
| 54 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
| 55 | u32 tmp = (priv->client->channel & 3) << 8; | ||
| 56 | |||
| 57 | if (format->pad) | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | if (mf->width > 8188) | ||
| 61 | mf->width = 8188; | ||
| 62 | else if (mf->width & 1) | ||
| 63 | mf->width &= ~1; | ||
| 64 | |||
| 65 | switch (pdata->type) { | ||
| 66 | case SH_CSI2C: | ||
| 67 | switch (mf->code) { | ||
| 68 | case MEDIA_BUS_FMT_UYVY8_2X8: /* YUV422 */ | ||
| 69 | case MEDIA_BUS_FMT_YUYV8_1_5X8: /* YUV420 */ | ||
| 70 | case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ | ||
| 71 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
| 72 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
| 73 | break; | ||
| 74 | default: | ||
| 75 | /* All MIPI CSI-2 devices must support one of primary formats */ | ||
| 76 | mf->code = MEDIA_BUS_FMT_YUYV8_2X8; | ||
| 77 | } | ||
| 78 | break; | ||
| 79 | case SH_CSI2I: | ||
| 80 | switch (mf->code) { | ||
| 81 | case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ | ||
| 82 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
| 83 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
| 84 | case MEDIA_BUS_FMT_SBGGR10_1X10: /* RAW10 */ | ||
| 85 | case MEDIA_BUS_FMT_SBGGR12_1X12: /* RAW12 */ | ||
| 86 | break; | ||
| 87 | default: | ||
| 88 | /* All MIPI CSI-2 devices must support one of primary formats */ | ||
| 89 | mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; | ||
| 90 | } | ||
| 91 | break; | ||
| 92 | } | ||
| 93 | |||
| 94 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { | ||
| 95 | cfg->try_fmt = *mf; | ||
| 96 | return 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | if (mf->width > 8188 || mf->width & 1) | ||
| 100 | return -EINVAL; | ||
| 101 | |||
| 102 | switch (mf->code) { | ||
| 103 | case MEDIA_BUS_FMT_UYVY8_2X8: | ||
| 104 | tmp |= 0x1e; /* YUV422 8 bit */ | ||
| 105 | break; | ||
| 106 | case MEDIA_BUS_FMT_YUYV8_1_5X8: | ||
| 107 | tmp |= 0x18; /* YUV420 8 bit */ | ||
| 108 | break; | ||
| 109 | case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: | ||
| 110 | tmp |= 0x21; /* RGB555 */ | ||
| 111 | break; | ||
| 112 | case MEDIA_BUS_FMT_RGB565_2X8_BE: | ||
| 113 | tmp |= 0x22; /* RGB565 */ | ||
| 114 | break; | ||
| 115 | case MEDIA_BUS_FMT_Y8_1X8: | ||
| 116 | case MEDIA_BUS_FMT_SBGGR8_1X8: | ||
| 117 | case MEDIA_BUS_FMT_SGRBG8_1X8: | ||
| 118 | tmp |= 0x2a; /* RAW8 */ | ||
| 119 | break; | ||
| 120 | default: | ||
| 121 | return -EINVAL; | ||
| 122 | } | ||
| 123 | |||
| 124 | iowrite32(tmp, priv->base + SH_CSI2_VCDT); | ||
| 125 | |||
| 126 | return 0; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd, | ||
| 130 | struct v4l2_mbus_config *cfg) | ||
| 131 | { | ||
| 132 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
| 133 | |||
| 134 | if (!priv->mipi_flags) { | ||
| 135 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); | ||
| 136 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | ||
| 137 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
| 138 | unsigned long common_flags, csi2_flags; | ||
| 139 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; | ||
| 140 | int ret; | ||
| 141 | |||
| 142 | /* Check if we can support this camera */ | ||
| 143 | csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | | ||
| 144 | V4L2_MBUS_CSI2_1_LANE; | ||
| 145 | |||
| 146 | switch (pdata->type) { | ||
| 147 | case SH_CSI2C: | ||
| 148 | if (priv->client->lanes != 1) | ||
| 149 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
| 150 | break; | ||
| 151 | case SH_CSI2I: | ||
| 152 | switch (priv->client->lanes) { | ||
| 153 | default: | ||
| 154 | csi2_flags |= V4L2_MBUS_CSI2_4_LANE; | ||
| 155 | case 3: | ||
| 156 | csi2_flags |= V4L2_MBUS_CSI2_3_LANE; | ||
| 157 | case 2: | ||
| 158 | csi2_flags |= V4L2_MBUS_CSI2_2_LANE; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | |||
| 162 | ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg); | ||
| 163 | if (ret == -ENOIOCTLCMD) | ||
| 164 | common_flags = csi2_flags; | ||
| 165 | else if (!ret) | ||
| 166 | common_flags = soc_mbus_config_compatible(&client_cfg, | ||
| 167 | csi2_flags); | ||
| 168 | else | ||
| 169 | common_flags = 0; | ||
| 170 | |||
| 171 | if (!common_flags) | ||
| 172 | return -EINVAL; | ||
| 173 | |||
| 174 | /* All good: camera MIPI configuration supported */ | ||
| 175 | priv->mipi_flags = common_flags; | ||
| 176 | } | ||
| 177 | |||
| 178 | if (cfg) { | ||
| 179 | cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | | ||
| 180 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | | ||
| 181 | V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH; | ||
| 182 | cfg->type = V4L2_MBUS_PARALLEL; | ||
| 183 | } | ||
| 184 | |||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, | ||
| 189 | const struct v4l2_mbus_config *cfg) | ||
| 190 | { | ||
| 191 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
| 192 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); | ||
| 193 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | ||
| 194 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; | ||
| 195 | int ret = sh_csi2_g_mbus_config(sd, NULL); | ||
| 196 | |||
| 197 | if (ret < 0) | ||
| 198 | return ret; | ||
| 199 | |||
| 200 | pm_runtime_get_sync(&priv->pdev->dev); | ||
| 201 | |||
| 202 | sh_csi2_hwinit(priv); | ||
| 203 | |||
| 204 | client_cfg.flags = priv->mipi_flags; | ||
| 205 | |||
| 206 | return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg); | ||
| 207 | } | ||
| 208 | |||
| 209 | static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { | ||
| 210 | .g_mbus_config = sh_csi2_g_mbus_config, | ||
| 211 | .s_mbus_config = sh_csi2_s_mbus_config, | ||
| 212 | }; | ||
| 213 | |||
| 214 | static struct v4l2_subdev_pad_ops sh_csi2_subdev_pad_ops = { | ||
| 215 | .set_fmt = sh_csi2_set_fmt, | ||
| 216 | }; | ||
| 217 | |||
| 218 | static void sh_csi2_hwinit(struct sh_csi2 *priv) | ||
| 219 | { | ||
| 220 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | ||
| 221 | __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */ | ||
| 222 | |||
| 223 | /* Reflect registers immediately */ | ||
| 224 | iowrite32(0x00000001, priv->base + SH_CSI2_TREF); | ||
| 225 | /* reset CSI2 harware */ | ||
| 226 | iowrite32(0x00000001, priv->base + SH_CSI2_SRST); | ||
| 227 | udelay(5); | ||
| 228 | iowrite32(0x00000000, priv->base + SH_CSI2_SRST); | ||
| 229 | |||
| 230 | switch (pdata->type) { | ||
| 231 | case SH_CSI2C: | ||
| 232 | if (priv->client->lanes == 1) | ||
| 233 | tmp |= 1; | ||
| 234 | else | ||
| 235 | /* Default - both lanes */ | ||
| 236 | tmp |= 3; | ||
| 237 | break; | ||
| 238 | case SH_CSI2I: | ||
| 239 | if (!priv->client->lanes || priv->client->lanes > 4) | ||
| 240 | /* Default - all 4 lanes */ | ||
| 241 | tmp |= 0xf; | ||
| 242 | else | ||
| 243 | tmp |= (1 << priv->client->lanes) - 1; | ||
| 244 | } | ||
| 245 | |||
| 246 | if (priv->client->phy == SH_CSI2_PHY_MAIN) | ||
| 247 | tmp |= 0x8000; | ||
| 248 | |||
| 249 | iowrite32(tmp, priv->base + SH_CSI2_PHYCNT); | ||
| 250 | |||
| 251 | tmp = 0; | ||
| 252 | if (pdata->flags & SH_CSI2_ECC) | ||
| 253 | tmp |= 2; | ||
| 254 | if (pdata->flags & SH_CSI2_CRC) | ||
| 255 | tmp |= 1; | ||
| 256 | iowrite32(tmp, priv->base + SH_CSI2_CHKSUM); | ||
| 257 | } | ||
| 258 | |||
| 259 | static int sh_csi2_client_connect(struct sh_csi2 *priv) | ||
| 260 | { | ||
| 261 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); | ||
| 262 | struct sh_csi2_pdata *pdata = dev->platform_data; | ||
| 263 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev); | ||
| 264 | int i; | ||
| 265 | |||
| 266 | if (priv->client) | ||
| 267 | return -EBUSY; | ||
| 268 | |||
| 269 | for (i = 0; i < pdata->num_clients; i++) | ||
| 270 | if ((pdata->clients[i].pdev && | ||
| 271 | &pdata->clients[i].pdev->dev == icd->pdev) || | ||
| 272 | (icd->control && | ||
| 273 | strcmp(pdata->clients[i].name, dev_name(icd->control)))) | ||
| 274 | break; | ||
| 275 | |||
| 276 | dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i); | ||
| 277 | |||
| 278 | if (i == pdata->num_clients) | ||
| 279 | return -ENODEV; | ||
| 280 | |||
| 281 | priv->client = pdata->clients + i; | ||
| 282 | |||
| 283 | return 0; | ||
| 284 | } | ||
| 285 | |||
| 286 | static void sh_csi2_client_disconnect(struct sh_csi2 *priv) | ||
| 287 | { | ||
| 288 | if (!priv->client) | ||
| 289 | return; | ||
| 290 | |||
| 291 | priv->client = NULL; | ||
| 292 | |||
| 293 | pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); | ||
| 294 | } | ||
| 295 | |||
| 296 | static int sh_csi2_s_power(struct v4l2_subdev *sd, int on) | ||
| 297 | { | ||
| 298 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | ||
| 299 | |||
| 300 | if (on) | ||
| 301 | return sh_csi2_client_connect(priv); | ||
| 302 | |||
| 303 | sh_csi2_client_disconnect(priv); | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = { | ||
| 308 | .s_power = sh_csi2_s_power, | ||
| 309 | }; | ||
| 310 | |||
| 311 | static struct v4l2_subdev_ops sh_csi2_subdev_ops = { | ||
| 312 | .core = &sh_csi2_subdev_core_ops, | ||
| 313 | .video = &sh_csi2_subdev_video_ops, | ||
| 314 | .pad = &sh_csi2_subdev_pad_ops, | ||
| 315 | }; | ||
| 316 | |||
| 317 | static int sh_csi2_probe(struct platform_device *pdev) | ||
| 318 | { | ||
| 319 | struct resource *res; | ||
| 320 | unsigned int irq; | ||
| 321 | int ret; | ||
| 322 | struct sh_csi2 *priv; | ||
| 323 | /* Platform data specify the PHY, lanes, ECC, CRC */ | ||
| 324 | struct sh_csi2_pdata *pdata = pdev->dev.platform_data; | ||
| 325 | |||
| 326 | if (!pdata) | ||
| 327 | return -EINVAL; | ||
| 328 | |||
| 329 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL); | ||
| 330 | if (!priv) | ||
| 331 | return -ENOMEM; | ||
| 332 | |||
| 333 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 334 | /* Interrupt unused so far */ | ||
| 335 | irq = platform_get_irq(pdev, 0); | ||
| 336 | |||
| 337 | if (!res || (int)irq <= 0) { | ||
| 338 | dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n"); | ||
| 339 | return -ENODEV; | ||
| 340 | } | ||
| 341 | |||
| 342 | /* TODO: Add support for CSI2I. Careful: different register layout! */ | ||
| 343 | if (pdata->type != SH_CSI2C) { | ||
| 344 | dev_err(&pdev->dev, "Only CSI2C supported ATM.\n"); | ||
| 345 | return -EINVAL; | ||
| 346 | } | ||
| 347 | |||
| 348 | priv->irq = irq; | ||
| 349 | |||
| 350 | priv->base = devm_ioremap_resource(&pdev->dev, res); | ||
| 351 | if (IS_ERR(priv->base)) | ||
| 352 | return PTR_ERR(priv->base); | ||
| 353 | |||
| 354 | priv->pdev = pdev; | ||
| 355 | priv->subdev.owner = THIS_MODULE; | ||
| 356 | priv->subdev.dev = &pdev->dev; | ||
| 357 | platform_set_drvdata(pdev, &priv->subdev); | ||
| 358 | |||
| 359 | v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops); | ||
| 360 | v4l2_set_subdevdata(&priv->subdev, &pdev->dev); | ||
| 361 | |||
| 362 | snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi", | ||
| 363 | dev_name(&pdev->dev)); | ||
| 364 | |||
| 365 | ret = v4l2_async_register_subdev(&priv->subdev); | ||
| 366 | if (ret < 0) | ||
| 367 | return ret; | ||
| 368 | |||
| 369 | pm_runtime_enable(&pdev->dev); | ||
| 370 | |||
| 371 | dev_dbg(&pdev->dev, "CSI2 probed.\n"); | ||
| 372 | |||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | static int sh_csi2_remove(struct platform_device *pdev) | ||
| 377 | { | ||
| 378 | struct v4l2_subdev *subdev = platform_get_drvdata(pdev); | ||
| 379 | struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); | ||
| 380 | |||
| 381 | v4l2_async_unregister_subdev(&priv->subdev); | ||
| 382 | pm_runtime_disable(&pdev->dev); | ||
| 383 | |||
| 384 | return 0; | ||
| 385 | } | ||
| 386 | |||
| 387 | static struct platform_driver __refdata sh_csi2_pdrv = { | ||
| 388 | .remove = sh_csi2_remove, | ||
| 389 | .probe = sh_csi2_probe, | ||
| 390 | .driver = { | ||
| 391 | .name = "sh-mobile-csi2", | ||
| 392 | }, | ||
| 393 | }; | ||
| 394 | |||
| 395 | module_platform_driver(sh_csi2_pdrv); | ||
| 396 | |||
| 397 | MODULE_DESCRIPTION("SH-Mobile MIPI CSI-2 driver"); | ||
| 398 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
| 399 | MODULE_LICENSE("GPL v2"); | ||
| 400 | MODULE_ALIAS("platform:sh-mobile-csi2"); | ||
diff --git a/include/media/drv-intf/sh_mobile_ceu.h b/include/media/drv-intf/sh_mobile_ceu.h index 7f57056c22ba..2f43f7d9e28d 100644 --- a/include/media/drv-intf/sh_mobile_ceu.h +++ b/include/media/drv-intf/sh_mobile_ceu.h | |||
| @@ -21,7 +21,6 @@ struct sh_mobile_ceu_info { | |||
| 21 | unsigned long flags; | 21 | unsigned long flags; |
| 22 | int max_width; | 22 | int max_width; |
| 23 | int max_height; | 23 | int max_height; |
| 24 | struct sh_mobile_ceu_companion *csi2; | ||
| 25 | struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ | 24 | struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ |
| 26 | unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ | 25 | unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ |
| 27 | }; | 26 | }; |
diff --git a/include/media/drv-intf/sh_mobile_csi2.h b/include/media/drv-intf/sh_mobile_csi2.h deleted file mode 100644 index 14030db51f13..000000000000 --- a/include/media/drv-intf/sh_mobile_csi2.h +++ /dev/null | |||
| @@ -1,48 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver header for the SH-Mobile MIPI CSI-2 unit | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef SH_MIPI_CSI | ||
| 12 | #define SH_MIPI_CSI | ||
| 13 | |||
| 14 | #include <linux/list.h> | ||
| 15 | |||
| 16 | enum sh_csi2_phy { | ||
| 17 | SH_CSI2_PHY_MAIN, | ||
| 18 | SH_CSI2_PHY_SUB, | ||
| 19 | }; | ||
| 20 | |||
| 21 | enum sh_csi2_type { | ||
| 22 | SH_CSI2C, | ||
| 23 | SH_CSI2I, | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define SH_CSI2_CRC (1 << 0) | ||
| 27 | #define SH_CSI2_ECC (1 << 1) | ||
| 28 | |||
| 29 | struct platform_device; | ||
| 30 | |||
| 31 | struct sh_csi2_client_config { | ||
| 32 | enum sh_csi2_phy phy; | ||
| 33 | unsigned char lanes; /* bitmask[3:0] */ | ||
| 34 | unsigned char channel; /* 0..3 */ | ||
| 35 | struct platform_device *pdev; /* client platform device */ | ||
| 36 | const char *name; /* async matching: client name */ | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct v4l2_device; | ||
| 40 | |||
| 41 | struct sh_csi2_pdata { | ||
| 42 | enum sh_csi2_type type; | ||
| 43 | unsigned int flags; | ||
| 44 | struct sh_csi2_client_config *clients; | ||
| 45 | int num_clients; | ||
| 46 | }; | ||
| 47 | |||
| 48 | #endif | ||
